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