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.context.FieldOwnerContext; 023 import org.jetbrains.kotlin.codegen.state.GenerationState; 024 import org.jetbrains.kotlin.descriptors.DeclarationDescriptor; 025 import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor; 026 import org.jetbrains.kotlin.descriptors.VariableDescriptor; 027 import org.jetbrains.kotlin.load.java.JvmAnnotationNames; 028 import org.jetbrains.kotlin.psi.JetDeclaration; 029 import org.jetbrains.kotlin.psi.JetFile; 030 import org.jetbrains.kotlin.psi.JetNamedFunction; 031 import org.jetbrains.kotlin.psi.JetProperty; 032 import org.jetbrains.kotlin.resolve.BindingContext; 033 import org.jetbrains.kotlin.serialization.*; 034 import org.jetbrains.kotlin.serialization.deserialization.NameResolver; 035 import org.jetbrains.kotlin.serialization.jvm.BitEncoding; 036 import org.jetbrains.org.objectweb.asm.AnnotationVisitor; 037 import org.jetbrains.org.objectweb.asm.Type; 038 039 import java.util.ArrayList; 040 import java.util.List; 041 042 import static org.jetbrains.kotlin.codegen.AsmUtil.asmDescByFqNameWithoutInnerClasses; 043 import static org.jetbrains.org.objectweb.asm.Opcodes.*; 044 045 public class PackagePartCodegen extends MemberCodegen<JetFile> { 046 private final Type packagePartType; 047 048 public PackagePartCodegen( 049 @NotNull ClassBuilder v, 050 @NotNull JetFile file, 051 @NotNull Type packagePartType, 052 @NotNull FieldOwnerContext context, 053 @NotNull GenerationState state 054 ) { 055 super(state, null, context, file, v); 056 this.packagePartType = packagePartType; 057 } 058 059 @Override 060 protected void generateDeclaration() { 061 v.defineClass(element, V1_6, 062 ACC_PUBLIC | ACC_FINAL, 063 packagePartType.getInternalName(), 064 null, 065 "java/lang/Object", 066 ArrayUtil.EMPTY_STRING_ARRAY 067 ); 068 v.visitSource(element.getName(), null); 069 070 generatePropertyMetadataArrayFieldIfNeeded(packagePartType); 071 } 072 073 @Override 074 protected void generateBody() { 075 for (JetDeclaration declaration : element.getDeclarations()) { 076 if (declaration instanceof JetNamedFunction || declaration instanceof JetProperty) { 077 genFunctionOrProperty(declaration); 078 } 079 } 080 081 if (state.getClassBuilderMode() == ClassBuilderMode.FULL) { 082 generateInitializers(new Function0<ExpressionCodegen>() { 083 @Override 084 public ExpressionCodegen invoke() { 085 return createOrGetClInitCodegen(); 086 } 087 }); 088 } 089 } 090 091 @Override 092 protected void generateKotlinAnnotation() { 093 if (state.getClassBuilderMode() != ClassBuilderMode.FULL) { 094 return; 095 } 096 097 List<DeclarationDescriptor> members = new ArrayList<DeclarationDescriptor>(); 098 for (JetDeclaration declaration : element.getDeclarations()) { 099 if (declaration instanceof JetNamedFunction) { 100 SimpleFunctionDescriptor functionDescriptor = bindingContext.get(BindingContext.FUNCTION, declaration); 101 members.add(functionDescriptor); 102 } else if (declaration instanceof JetProperty) { 103 VariableDescriptor property = bindingContext.get(BindingContext.VARIABLE, declaration); 104 members.add(property); 105 } 106 } 107 108 JvmSerializationBindings bindings = v.getSerializationBindings(); 109 110 DescriptorSerializer serializer = DescriptorSerializer.createTopLevel(new JvmSerializerExtension(bindings, state.getTypeMapper())); 111 ProtoBuf.Package packageProto = serializer.packagePartProto(members).build(); 112 113 if (packageProto.getMemberCount() == 0) return; 114 115 StringTable strings = serializer.getStringTable(); 116 NameResolver nameResolver = new NameResolver(strings.serializeSimpleNames(), strings.serializeQualifiedNames()); 117 PackageData data = new PackageData(nameResolver, packageProto); 118 119 AnnotationVisitor av = v.newAnnotation(asmDescByFqNameWithoutInnerClasses(JvmAnnotationNames.KOTLIN_FILE_FACADE), true); 120 JvmCodegenUtil.writeAbiVersion(av); 121 AnnotationVisitor array = av.visitArray(JvmAnnotationNames.DATA_FIELD_NAME); 122 for (String string : BitEncoding.encodeBytes(SerializationUtil.serializePackageData(data))) { 123 array.visit(null, string); 124 } 125 array.visitEnd(); 126 av.visitEnd(); 127 } 128 }