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