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 }