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.jvm.functions.Function0;
021 import org.jetbrains.annotations.NotNull;
022 import org.jetbrains.kotlin.codegen.annotation.AnnotatedSimple;
023 import org.jetbrains.kotlin.codegen.context.FieldOwnerContext;
024 import org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings;
025 import org.jetbrains.kotlin.codegen.serialization.JvmSerializerExtension;
026 import org.jetbrains.kotlin.codegen.state.GenerationState;
027 import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
028 import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor;
029 import org.jetbrains.kotlin.descriptors.VariableDescriptor;
030 import org.jetbrains.kotlin.descriptors.annotations.Annotated;
031 import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor;
032 import org.jetbrains.kotlin.descriptors.annotations.AnnotationsImpl;
033 import org.jetbrains.kotlin.load.java.JvmAnnotationNames;
034 import org.jetbrains.kotlin.psi.*;
035 import org.jetbrains.kotlin.resolve.BindingContext;
036 import org.jetbrains.kotlin.serialization.DescriptorSerializer;
037 import org.jetbrains.kotlin.serialization.ProtoBuf;
038 import org.jetbrains.org.objectweb.asm.AnnotationVisitor;
039 import org.jetbrains.org.objectweb.asm.Type;
040
041 import java.util.ArrayList;
042 import java.util.List;
043
044 import static org.jetbrains.kotlin.codegen.AsmUtil.asmDescByFqNameWithoutInnerClasses;
045 import static org.jetbrains.kotlin.codegen.AsmUtil.writeAnnotationData;
046 import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.writeModuleName;
047 import static org.jetbrains.org.objectweb.asm.Opcodes.*;
048
049 public class PackagePartCodegen extends MemberCodegen<KtFile> {
050 private final Type packagePartType;
051
052 public PackagePartCodegen(
053 @NotNull ClassBuilder v,
054 @NotNull KtFile file,
055 @NotNull Type packagePartType,
056 @NotNull FieldOwnerContext context,
057 @NotNull GenerationState state
058 ) {
059 super(state, null, context, file, v);
060 this.packagePartType = packagePartType;
061 }
062
063 @Override
064 protected void generateDeclaration() {
065 v.defineClass(element, V1_6,
066 ACC_PUBLIC | ACC_FINAL,
067 packagePartType.getInternalName(),
068 null,
069 "java/lang/Object",
070 ArrayUtil.EMPTY_STRING_ARRAY
071 );
072 v.visitSource(element.getName(), null);
073
074 generatePropertyMetadataArrayFieldIfNeeded(packagePartType);
075
076 generateAnnotationsForPartClass();
077 }
078
079 private void generateAnnotationsForPartClass() {
080 List<AnnotationDescriptor> fileAnnotationDescriptors = new ArrayList<AnnotationDescriptor>();
081 for (KtAnnotationEntry annotationEntry : element.getAnnotationEntries()) {
082 AnnotationDescriptor annotationDescriptor = state.getBindingContext().get(BindingContext.ANNOTATION, annotationEntry);
083 if (annotationDescriptor != null) {
084 fileAnnotationDescriptors.add(annotationDescriptor);
085 }
086 }
087 Annotated annotatedFile = new AnnotatedSimple(new AnnotationsImpl(fileAnnotationDescriptors));
088 AnnotationCodegen.forClass(v.getVisitor(), state.getTypeMapper()).genAnnotations(annotatedFile, null);
089 }
090
091 @Override
092 protected void generateBody() {
093 for (KtDeclaration declaration : element.getDeclarations()) {
094 if (declaration instanceof KtNamedFunction || declaration instanceof KtProperty) {
095 genFunctionOrProperty(declaration);
096 }
097 }
098
099 if (state.getClassBuilderMode() == ClassBuilderMode.FULL) {
100 generateInitializers(new Function0<ExpressionCodegen>() {
101 @Override
102 public ExpressionCodegen invoke() {
103 return createOrGetClInitCodegen();
104 }
105 });
106 }
107 }
108
109 @Override
110 protected void generateKotlinAnnotation() {
111 List<DeclarationDescriptor> members = new ArrayList<DeclarationDescriptor>();
112 for (KtDeclaration declaration : element.getDeclarations()) {
113 if (declaration instanceof KtNamedFunction) {
114 SimpleFunctionDescriptor functionDescriptor = bindingContext.get(BindingContext.FUNCTION, declaration);
115 members.add(functionDescriptor);
116 } else if (declaration instanceof KtProperty) {
117 VariableDescriptor property = bindingContext.get(BindingContext.VARIABLE, declaration);
118 members.add(property);
119 }
120 }
121
122 JvmSerializationBindings bindings = v.getSerializationBindings();
123
124 DescriptorSerializer serializer = DescriptorSerializer.createTopLevel(new JvmSerializerExtension(
125 bindings, state.getTypeMapper(), state.getUseTypeTableInSerializer()
126 ));
127 ProtoBuf.Package packageProto = serializer.packagePartProto(members).build();
128
129 AnnotationVisitor av = v.newAnnotation(asmDescByFqNameWithoutInnerClasses(JvmAnnotationNames.KOTLIN_FILE_FACADE), true);
130 writeAnnotationData(av, serializer, packageProto);
131 writeModuleName(av, state);
132 av.visitEnd();
133 }
134
135 @Override
136 protected void generateSyntheticParts() {
137 generateSyntheticAccessors();
138 }
139 }