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 | ACC_SUPER, 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 }