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