NamespaceCodegen refactoring
This commit is contained in:
@@ -16,7 +16,6 @@
|
||||
|
||||
package org.jetbrains.jet.codegen;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.progress.ProcessCanceledException;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
@@ -26,7 +25,6 @@ import com.intellij.util.PathUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.asm4.AnnotationVisitor;
|
||||
import org.jetbrains.asm4.MethodVisitor;
|
||||
import org.jetbrains.asm4.Type;
|
||||
import org.jetbrains.jet.codegen.context.CodegenContext;
|
||||
import org.jetbrains.jet.codegen.context.FieldOwnerContext;
|
||||
@@ -35,9 +33,7 @@ import org.jetbrains.jet.descriptors.serialization.BitEncoding;
|
||||
import org.jetbrains.jet.descriptors.serialization.DescriptorSerializer;
|
||||
import org.jetbrains.jet.descriptors.serialization.PackageData;
|
||||
import org.jetbrains.jet.descriptors.serialization.ProtoBuf;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.impl.SimpleFunctionDescriptorImpl;
|
||||
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
|
||||
import org.jetbrains.jet.lang.diagnostics.DiagnosticUtils;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
@@ -49,7 +45,6 @@ import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.asm4.Opcodes.*;
|
||||
@@ -61,15 +56,19 @@ import static org.jetbrains.jet.lang.resolve.java.PackageClassUtils.getPackageCl
|
||||
public class NamespaceCodegen extends MemberCodegen {
|
||||
@NotNull
|
||||
private final ClassBuilderOnDemand v;
|
||||
@NotNull private final FqName name;
|
||||
|
||||
@NotNull
|
||||
private final FqName name;
|
||||
|
||||
@NotNull
|
||||
private final Collection<JetFile> files;
|
||||
private final NamespaceDescriptor descriptor;
|
||||
|
||||
public NamespaceCodegen(
|
||||
@NotNull ClassBuilderOnDemand v,
|
||||
@NotNull final FqName fqName,
|
||||
GenerationState state,
|
||||
Collection<JetFile> namespaceFiles
|
||||
@NotNull GenerationState state,
|
||||
@NotNull Collection<JetFile> namespaceFiles
|
||||
) {
|
||||
super(state, null);
|
||||
checkAllFilesHaveSameNamespace(namespaceFiles);
|
||||
@@ -165,9 +164,12 @@ public class NamespaceCodegen extends MemberCodegen {
|
||||
av.visitEnd();
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
private ClassBuilder generate(@NotNull JetFile file) {
|
||||
boolean generateSrcClass = false;
|
||||
FieldOwnerContext namespaceImpl = CodegenContext.STATIC.intoNamespace(descriptor);
|
||||
|
||||
for (JetDeclaration declaration : file.getDeclarations()) {
|
||||
if (declaration instanceof JetProperty || declaration instanceof JetNamedFunction) {
|
||||
generateSrcClass = true;
|
||||
@@ -178,7 +180,7 @@ public class NamespaceCodegen extends MemberCodegen {
|
||||
}
|
||||
}
|
||||
else if (declaration instanceof JetScript) {
|
||||
ScriptCodegen.createScriptCodegen((JetScript) declaration, state, CodegenContext.STATIC.intoNamespace(descriptor)).generate();
|
||||
ScriptCodegen.createScriptCodegen((JetScript) declaration, state, namespaceImpl).generate();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -187,42 +189,20 @@ public class NamespaceCodegen extends MemberCodegen {
|
||||
Type namespacePartType = getNamespacePartType(getPackageClassFqName(name), file);
|
||||
ClassBuilder builder = state.getFactory().forNamespacePart(namespacePartType, file);
|
||||
|
||||
builder.defineClass(file, V1_6,
|
||||
ACC_PUBLIC | ACC_FINAL,
|
||||
namespacePartType.getInternalName(),
|
||||
null,
|
||||
//"jet/lang/Namespace",
|
||||
"java/lang/Object",
|
||||
new String[0]
|
||||
);
|
||||
builder.visitSource(file.getName(), null);
|
||||
NamespacePartCodegen namespacePartCodegen = new NamespacePartCodegen(builder, file, namespacePartType, namespaceImpl, state);
|
||||
namespacePartCodegen.generate();
|
||||
|
||||
writeKotlinPackageFragmentAnnotation(builder);
|
||||
|
||||
FieldOwnerContext nameSpaceContext = CodegenContext.STATIC.intoNamespace(descriptor);
|
||||
|
||||
FieldOwnerContext nameSpacePart = CodegenContext.STATIC.intoNamespacePart(namespacePartType, descriptor);
|
||||
FieldOwnerContext nameSpacePart = CodegenContext.STATIC.intoNamespaceFacade(namespacePartType, descriptor);
|
||||
|
||||
for (JetDeclaration declaration : file.getDeclarations()) {
|
||||
if (declaration instanceof JetNamedFunction || declaration instanceof JetProperty) {
|
||||
genFunctionOrProperty(nameSpaceContext, (JetTypeParameterListOwner) declaration, builder);
|
||||
genFunctionOrProperty(nameSpacePart, (JetTypeParameterListOwner) declaration, v.getClassBuilder());
|
||||
}
|
||||
}
|
||||
|
||||
generateStaticInitializers(builder, file, nameSpaceContext);
|
||||
|
||||
builder.done();
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
private static void writeKotlinPackageFragmentAnnotation(@NotNull ClassBuilder builder) {
|
||||
AnnotationVisitor av = builder.newAnnotation(asmDescByFqNameWithoutInnerClasses(JvmAnnotationNames.KOTLIN_PACKAGE_FRAGMENT), true);
|
||||
av.visit(JvmAnnotationNames.ABI_VERSION_FIELD_NAME, JvmAbi.VERSION);
|
||||
av.visitEnd();
|
||||
}
|
||||
|
||||
public void generateClassOrObject(@NotNull JetClassOrObject classOrObject) {
|
||||
CodegenContext context = CodegenContext.STATIC.intoNamespace(descriptor);
|
||||
genClassOrObject(context, classOrObject);
|
||||
@@ -263,48 +243,6 @@ public class NamespaceCodegen extends MemberCodegen {
|
||||
}
|
||||
}
|
||||
|
||||
private void generateStaticInitializers(@NotNull ClassBuilder builder, @NotNull JetFile file, @NotNull FieldOwnerContext context) {
|
||||
List<JetProperty> properties = collectPropertiesToInitialize(file);
|
||||
if (properties.isEmpty()) return;
|
||||
|
||||
MethodVisitor mv = builder.newMethod(file, ACC_STATIC, "<clinit>", "()V", null, null);
|
||||
if (state.getClassBuilderMode() == ClassBuilderMode.FULL) {
|
||||
mv.visitCode();
|
||||
|
||||
FrameMap frameMap = new FrameMap();
|
||||
|
||||
SimpleFunctionDescriptorImpl clInit =
|
||||
new SimpleFunctionDescriptorImpl(descriptor, Collections.<AnnotationDescriptor>emptyList(),
|
||||
Name.special("<clinit>"),
|
||||
CallableMemberDescriptor.Kind.SYNTHESIZED);
|
||||
clInit.initialize(null, null, Collections.<TypeParameterDescriptor>emptyList(),
|
||||
Collections.<ValueParameterDescriptor>emptyList(), null, null, Visibilities.PRIVATE, false);
|
||||
|
||||
ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, Type.VOID_TYPE, context.intoFunction(clInit), state, this);
|
||||
|
||||
for (JetDeclaration declaration : properties) {
|
||||
ImplementationBodyCodegen.
|
||||
initializeProperty(codegen, state.getBindingContext(), (JetProperty) declaration);
|
||||
}
|
||||
|
||||
mv.visitInsn(RETURN);
|
||||
FunctionCodegen.endVisit(mv, "static initializer for namespace", file);
|
||||
mv.visitEnd();
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private List<JetProperty> collectPropertiesToInitialize(@NotNull JetFile file) {
|
||||
List<JetProperty> result = Lists.newArrayList();
|
||||
for (JetDeclaration declaration : file.getDeclarations()) {
|
||||
if (declaration instanceof JetProperty &&
|
||||
ImplementationBodyCodegen.shouldInitializeProperty((JetProperty) declaration, typeMapper)) {
|
||||
result.add((JetProperty) declaration);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public void done() {
|
||||
v.done();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
* Copyright 2010-2013 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.jet.codegen;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.asm4.AnnotationVisitor;
|
||||
import org.jetbrains.asm4.MethodVisitor;
|
||||
import org.jetbrains.asm4.Type;
|
||||
import org.jetbrains.jet.codegen.context.FieldOwnerContext;
|
||||
import org.jetbrains.jet.codegen.state.GenerationState;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.impl.SimpleFunctionDescriptorImpl;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.java.JvmAbi;
|
||||
import org.jetbrains.jet.lang.resolve.java.JvmAnnotationNames;
|
||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.asm4.Opcodes.*;
|
||||
import static org.jetbrains.jet.codegen.AsmUtil.asmDescByFqNameWithoutInnerClasses;
|
||||
|
||||
public class NamespacePartCodegen extends MemberCodegen {
|
||||
|
||||
private final ClassBuilder v;
|
||||
|
||||
private final NamespaceDescriptor descriptor;
|
||||
|
||||
private final JetFile jetFile;
|
||||
|
||||
private final Type namespacePartName;
|
||||
|
||||
private final FieldOwnerContext context;
|
||||
|
||||
public NamespacePartCodegen(
|
||||
@NotNull ClassBuilder v,
|
||||
@NotNull JetFile jetFile,
|
||||
@NotNull Type namespacePartName,
|
||||
@NotNull FieldOwnerContext context,
|
||||
@NotNull GenerationState state
|
||||
) {
|
||||
super(state, null);
|
||||
this.v = v;
|
||||
this.jetFile = jetFile;
|
||||
this.namespacePartName = namespacePartName;
|
||||
this.context = context;
|
||||
descriptor = state.getBindingContext().get(BindingContext.FILE_TO_NAMESPACE, jetFile);
|
||||
assert descriptor != null : "No namespace found for jetFile " + jetFile + " declared package: " + jetFile.getPackageName();
|
||||
}
|
||||
|
||||
public void generate() {
|
||||
v.defineClass(jetFile, V1_6,
|
||||
ACC_PUBLIC | ACC_FINAL,
|
||||
namespacePartName.getInternalName(),
|
||||
null,
|
||||
//"jet/lang/Namespace",
|
||||
"java/lang/Object",
|
||||
new String[0]
|
||||
);
|
||||
v.visitSource(jetFile.getName(), null);
|
||||
|
||||
writeKotlinPackageFragmentAnnotation();
|
||||
|
||||
for (JetDeclaration declaration : jetFile.getDeclarations()) {
|
||||
if (declaration instanceof JetNamedFunction || declaration instanceof JetProperty) {
|
||||
genFunctionOrProperty(context, (JetTypeParameterListOwner) declaration, v);
|
||||
}
|
||||
}
|
||||
|
||||
generateStaticInitializers();
|
||||
|
||||
v.done();
|
||||
}
|
||||
|
||||
private void writeKotlinPackageFragmentAnnotation() {
|
||||
AnnotationVisitor av = v.newAnnotation(asmDescByFqNameWithoutInnerClasses(JvmAnnotationNames.KOTLIN_PACKAGE_FRAGMENT), true);
|
||||
av.visit(JvmAnnotationNames.ABI_VERSION_FIELD_NAME, JvmAbi.VERSION);
|
||||
av.visitEnd();
|
||||
}
|
||||
|
||||
|
||||
private void generateStaticInitializers() {
|
||||
List<JetProperty> properties = collectPropertiesToInitialize();
|
||||
if (properties.isEmpty()) return;
|
||||
|
||||
MethodVisitor mv = v.newMethod(jetFile, ACC_STATIC, "<clinit>", "()V", null, null);
|
||||
if (state.getClassBuilderMode() == ClassBuilderMode.FULL) {
|
||||
mv.visitCode();
|
||||
|
||||
FrameMap frameMap = new FrameMap();
|
||||
|
||||
SimpleFunctionDescriptorImpl clInit =
|
||||
new SimpleFunctionDescriptorImpl(this.descriptor, Collections.<AnnotationDescriptor>emptyList(),
|
||||
Name.special("<clinit>"),
|
||||
CallableMemberDescriptor.Kind.SYNTHESIZED);
|
||||
clInit.initialize(null, null, Collections.<TypeParameterDescriptor>emptyList(),
|
||||
Collections.<ValueParameterDescriptor>emptyList(), null, null, Visibilities.PRIVATE, false);
|
||||
|
||||
ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, Type.VOID_TYPE, this.context.intoFunction(clInit), state, this);
|
||||
|
||||
for (JetDeclaration declaration : properties) {
|
||||
ImplementationBodyCodegen.
|
||||
initializeProperty(codegen, state.getBindingContext(), (JetProperty) declaration);
|
||||
}
|
||||
|
||||
mv.visitInsn(RETURN);
|
||||
FunctionCodegen.endVisit(mv, "static initializer for namespace", jetFile);
|
||||
mv.visitEnd();
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private List<JetProperty> collectPropertiesToInitialize() {
|
||||
List<JetProperty> result = Lists.newArrayList();
|
||||
for (JetDeclaration declaration : jetFile.getDeclarations()) {
|
||||
if (declaration instanceof JetProperty &&
|
||||
ImplementationBodyCodegen.shouldInitializeProperty((JetProperty) declaration, typeMapper)) {
|
||||
result.add((JetProperty) declaration);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -152,8 +152,8 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public FieldOwnerContext intoNamespacePart(@NotNull Type delegateTo, @NotNull NamespaceDescriptor descriptor) {
|
||||
return new NamespaceContext(descriptor, this, new OwnerKind.StaticDelegateKind(delegateTo));
|
||||
public FieldOwnerContext intoNamespaceFacade(@NotNull Type delegateTo, @NotNull NamespaceDescriptor descriptor) {
|
||||
return new NamespaceFacadeContext(descriptor, this, new OwnerKind.StaticDelegateKind(delegateTo));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2010-2013 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.jet.codegen.context;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.codegen.OwnerKind;
|
||||
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
|
||||
|
||||
public class NamespaceFacadeContext extends NamespaceContext {
|
||||
|
||||
public NamespaceFacadeContext(
|
||||
@NotNull NamespaceDescriptor contextDescriptor,
|
||||
@Nullable CodegenContext parent,
|
||||
@NotNull OwnerKind kind
|
||||
) {
|
||||
super(contextDescriptor, parent, kind);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user