001 /*
002 * Copyright 2010-2015 JetBrains s.r.o.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017 package org.jetbrains.kotlin.codegen;
018
019 import com.intellij.util.ArrayUtil;
020 import kotlin.Unit;
021 import kotlin.jvm.functions.Function0;
022 import kotlin.jvm.functions.Function1;
023 import org.jetbrains.annotations.NotNull;
024 import org.jetbrains.kotlin.codegen.annotation.AnnotatedSimple;
025 import org.jetbrains.kotlin.codegen.context.FieldOwnerContext;
026 import org.jetbrains.kotlin.codegen.serialization.JvmSerializerExtension;
027 import org.jetbrains.kotlin.codegen.state.GenerationState;
028 import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
029 import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor;
030 import org.jetbrains.kotlin.descriptors.VariableDescriptor;
031 import org.jetbrains.kotlin.descriptors.annotations.Annotated;
032 import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor;
033 import org.jetbrains.kotlin.descriptors.annotations.AnnotationsImpl;
034 import org.jetbrains.kotlin.load.java.JvmAnnotationNames;
035 import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader;
036 import org.jetbrains.kotlin.psi.*;
037 import org.jetbrains.kotlin.resolve.BindingContext;
038 import org.jetbrains.kotlin.serialization.DescriptorSerializer;
039 import org.jetbrains.kotlin.serialization.ProtoBuf;
040 import org.jetbrains.org.objectweb.asm.AnnotationVisitor;
041 import org.jetbrains.org.objectweb.asm.Type;
042
043 import java.util.ArrayList;
044 import java.util.List;
045
046 import static org.jetbrains.kotlin.codegen.AsmUtil.asmDescByFqNameWithoutInnerClasses;
047 import static org.jetbrains.kotlin.codegen.AsmUtil.writeAnnotationData;
048 import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.writeAbiVersion;
049 import static org.jetbrains.org.objectweb.asm.Opcodes.*;
050
051 public class PackagePartCodegen extends MemberCodegen<KtFile> {
052 private final Type packagePartType;
053
054 public PackagePartCodegen(
055 @NotNull ClassBuilder v,
056 @NotNull KtFile file,
057 @NotNull Type packagePartType,
058 @NotNull FieldOwnerContext context,
059 @NotNull GenerationState state
060 ) {
061 super(state, null, context, file, v);
062 this.packagePartType = packagePartType;
063 }
064
065 @Override
066 protected void generateDeclaration() {
067 v.defineClass(element, V1_6,
068 ACC_PUBLIC | ACC_FINAL | ACC_SUPER,
069 packagePartType.getInternalName(),
070 null,
071 "java/lang/Object",
072 ArrayUtil.EMPTY_STRING_ARRAY
073 );
074 v.visitSource(element.getName(), null);
075
076 generatePropertyMetadataArrayFieldIfNeeded(packagePartType);
077
078 generateAnnotationsForPartClass();
079 }
080
081 private void generateAnnotationsForPartClass() {
082 List<AnnotationDescriptor> fileAnnotationDescriptors = new ArrayList<AnnotationDescriptor>();
083 for (KtAnnotationEntry annotationEntry : element.getAnnotationEntries()) {
084 AnnotationDescriptor annotationDescriptor = state.getBindingContext().get(BindingContext.ANNOTATION, annotationEntry);
085 if (annotationDescriptor != null) {
086 fileAnnotationDescriptors.add(annotationDescriptor);
087 }
088 }
089 Annotated annotatedFile = new AnnotatedSimple(new AnnotationsImpl(fileAnnotationDescriptors));
090 AnnotationCodegen.forClass(v.getVisitor(), state.getTypeMapper()).genAnnotations(annotatedFile, null);
091 }
092
093 @Override
094 protected void generateBody() {
095 for (KtDeclaration declaration : element.getDeclarations()) {
096 if (declaration instanceof KtNamedFunction || declaration instanceof KtProperty) {
097 genFunctionOrProperty(declaration);
098 }
099 }
100
101 if (state.getClassBuilderMode() == ClassBuilderMode.FULL) {
102 generateInitializers(new Function0<ExpressionCodegen>() {
103 @Override
104 public ExpressionCodegen invoke() {
105 return createOrGetClInitCodegen();
106 }
107 });
108 }
109 }
110
111 @Override
112 protected void generateKotlinAnnotation() {
113 List<DeclarationDescriptor> members = new ArrayList<DeclarationDescriptor>();
114 for (KtDeclaration declaration : element.getDeclarations()) {
115 if (declaration instanceof KtNamedFunction) {
116 SimpleFunctionDescriptor functionDescriptor = bindingContext.get(BindingContext.FUNCTION, declaration);
117 members.add(functionDescriptor);
118 } else if (declaration instanceof KtProperty) {
119 VariableDescriptor property = bindingContext.get(BindingContext.VARIABLE, declaration);
120 members.add(property);
121 }
122 }
123
124 final DescriptorSerializer serializer =
125 DescriptorSerializer.createTopLevel(new JvmSerializerExtension(v.getSerializationBindings(), state));
126 final ProtoBuf.Package packageProto = serializer.packagePartProto(members).build();
127
128 WriteAnnotationUtilKt.writeKotlinMetadata(v, KotlinClassHeader.Kind.FILE_FACADE, new Function1<AnnotationVisitor, Unit>() {
129 @Override
130 public Unit invoke(AnnotationVisitor av) {
131 writeAnnotationData(av, serializer, packageProto, false);
132 return Unit.INSTANCE;
133 }
134 });
135
136 AnnotationVisitor av = v.newAnnotation(asmDescByFqNameWithoutInnerClasses(JvmAnnotationNames.KOTLIN_FILE_FACADE), true);
137 writeAbiVersion(av);
138 writeAnnotationData(av, serializer, packageProto, true);
139 av.visitEnd();
140 }
141
142 @Override
143 protected void generateSyntheticParts() {
144 generateSyntheticAccessors();
145 }
146 }