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 }