001 /* 002 * Copyright 2010-2013 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.jet.codegen; 018 019 import com.google.common.collect.Lists; 020 import com.intellij.util.ArrayUtil; 021 import org.jetbrains.annotations.NotNull; 022 import org.jetbrains.asm4.AnnotationVisitor; 023 import org.jetbrains.asm4.MethodVisitor; 024 import org.jetbrains.asm4.Type; 025 import org.jetbrains.jet.codegen.context.FieldOwnerContext; 026 import org.jetbrains.jet.codegen.state.GenerationState; 027 import org.jetbrains.jet.lang.descriptors.*; 028 import org.jetbrains.jet.lang.descriptors.annotations.Annotations; 029 import org.jetbrains.jet.lang.descriptors.impl.SimpleFunctionDescriptorImpl; 030 import org.jetbrains.jet.lang.psi.*; 031 import org.jetbrains.jet.lang.resolve.BindingContext; 032 import org.jetbrains.jet.lang.resolve.java.JvmAbi; 033 import org.jetbrains.jet.lang.resolve.java.JvmAnnotationNames; 034 import org.jetbrains.jet.lang.resolve.name.Name; 035 036 import java.util.Collections; 037 import java.util.List; 038 039 import static org.jetbrains.asm4.Opcodes.*; 040 import static org.jetbrains.jet.codegen.AsmUtil.asmTypeByFqNameWithoutInnerClasses; 041 import static org.jetbrains.jet.lang.resolve.java.JvmAnnotationNames.KOTLIN_SYNTHETIC_CLASS; 042 043 public class PackagePartCodegen extends MemberCodegen { 044 045 private final ClassBuilder v; 046 047 private final PackageFragmentDescriptor descriptor; 048 049 private final JetFile jetFile; 050 051 private final Type packagePartName; 052 053 private final FieldOwnerContext context; 054 055 public PackagePartCodegen( 056 @NotNull ClassBuilder v, 057 @NotNull JetFile jetFile, 058 @NotNull Type packagePartName, 059 @NotNull FieldOwnerContext context, 060 @NotNull GenerationState state 061 ) { 062 super(state, null, context, v); 063 this.v = v; 064 this.jetFile = jetFile; 065 this.packagePartName = packagePartName; 066 this.context = context; 067 descriptor = state.getBindingContext().get(BindingContext.FILE_TO_PACKAGE_FRAGMENT, jetFile); 068 assert descriptor != null : "No package fragment found for jetFile " + jetFile + " declared package: " + jetFile.getPackageName(); 069 } 070 071 public void generate() { 072 v.defineClass(jetFile, V1_6, 073 ACC_PUBLIC | ACC_FINAL, 074 packagePartName.getInternalName(), 075 null, 076 "java/lang/Object", 077 ArrayUtil.EMPTY_STRING_ARRAY 078 ); 079 v.visitSource(jetFile.getName(), null); 080 081 writeKotlinAnnotation(); 082 083 for (JetDeclaration declaration : jetFile.getDeclarations()) { 084 if (declaration instanceof JetNamedFunction || declaration instanceof JetProperty) { 085 genFunctionOrProperty(context, (JetTypeParameterListOwner) declaration, v); 086 } 087 } 088 089 generateStaticInitializers(); 090 091 v.done(); 092 } 093 094 private void writeKotlinAnnotation() { 095 Type type = asmTypeByFqNameWithoutInnerClasses(KOTLIN_SYNTHETIC_CLASS); 096 AnnotationVisitor av = v.newAnnotation(type.getDescriptor(), true); 097 av.visit(JvmAnnotationNames.ABI_VERSION_FIELD_NAME, JvmAbi.VERSION); 098 av.visitEnum("kind", "L" + type.getInternalName() + "$Kind;", "PACKAGE_PART"); 099 av.visitEnd(); 100 } 101 102 103 private void generateStaticInitializers() { 104 List<JetProperty> properties = collectPropertiesToInitialize(); 105 if (properties.isEmpty()) return; 106 107 MethodVisitor mv = v.newMethod(jetFile, ACC_STATIC, "<clinit>", "()V", null, null); 108 if (state.getClassBuilderMode() == ClassBuilderMode.FULL) { 109 mv.visitCode(); 110 111 FrameMap frameMap = new FrameMap(); 112 113 SimpleFunctionDescriptorImpl clInit = 114 new SimpleFunctionDescriptorImpl(this.descriptor, Annotations.EMPTY, 115 Name.special("<clinit>"), 116 CallableMemberDescriptor.Kind.SYNTHESIZED); 117 clInit.initialize(null, null, Collections.<TypeParameterDescriptor>emptyList(), 118 Collections.<ValueParameterDescriptor>emptyList(), null, null, Visibilities.PRIVATE); 119 120 ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, Type.VOID_TYPE, this.context.intoFunction(clInit), state, this); 121 122 for (JetDeclaration declaration : properties) { 123 ImplementationBodyCodegen. 124 initializeProperty(codegen, state.getBindingContext(), (JetProperty) declaration); 125 } 126 127 mv.visitInsn(RETURN); 128 FunctionCodegen.endVisit(mv, "static initializer for package", jetFile); 129 mv.visitEnd(); 130 } 131 } 132 133 @NotNull 134 private List<JetProperty> collectPropertiesToInitialize() { 135 List<JetProperty> result = Lists.newArrayList(); 136 for (JetDeclaration declaration : jetFile.getDeclarations()) { 137 if (declaration instanceof JetProperty && 138 ImplementationBodyCodegen.shouldInitializeProperty((JetProperty) declaration, typeMapper)) { 139 result.add((JetProperty) declaration); 140 } 141 } 142 return result; 143 } 144 }