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    }