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