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