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 }