NamespaceCodegen refactoring
This commit is contained in:
@@ -16,7 +16,6 @@
|
|||||||
|
|
||||||
package org.jetbrains.jet.codegen;
|
package org.jetbrains.jet.codegen;
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
|
||||||
import com.intellij.openapi.application.ApplicationManager;
|
import com.intellij.openapi.application.ApplicationManager;
|
||||||
import com.intellij.openapi.progress.ProcessCanceledException;
|
import com.intellij.openapi.progress.ProcessCanceledException;
|
||||||
import com.intellij.openapi.util.io.FileUtil;
|
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.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.asm4.AnnotationVisitor;
|
import org.jetbrains.asm4.AnnotationVisitor;
|
||||||
import org.jetbrains.asm4.MethodVisitor;
|
|
||||||
import org.jetbrains.asm4.Type;
|
import org.jetbrains.asm4.Type;
|
||||||
import org.jetbrains.jet.codegen.context.CodegenContext;
|
import org.jetbrains.jet.codegen.context.CodegenContext;
|
||||||
import org.jetbrains.jet.codegen.context.FieldOwnerContext;
|
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.DescriptorSerializer;
|
||||||
import org.jetbrains.jet.descriptors.serialization.PackageData;
|
import org.jetbrains.jet.descriptors.serialization.PackageData;
|
||||||
import org.jetbrains.jet.descriptors.serialization.ProtoBuf;
|
import org.jetbrains.jet.descriptors.serialization.ProtoBuf;
|
||||||
import org.jetbrains.jet.lang.descriptors.*;
|
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
|
||||||
import org.jetbrains.jet.lang.descriptors.impl.SimpleFunctionDescriptorImpl;
|
|
||||||
import org.jetbrains.jet.lang.diagnostics.DiagnosticUtils;
|
import org.jetbrains.jet.lang.diagnostics.DiagnosticUtils;
|
||||||
import org.jetbrains.jet.lang.psi.*;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
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.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static org.jetbrains.asm4.Opcodes.*;
|
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 {
|
public class NamespaceCodegen extends MemberCodegen {
|
||||||
@NotNull
|
@NotNull
|
||||||
private final ClassBuilderOnDemand v;
|
private final ClassBuilderOnDemand v;
|
||||||
@NotNull private final FqName name;
|
|
||||||
|
@NotNull
|
||||||
|
private final FqName name;
|
||||||
|
|
||||||
|
@NotNull
|
||||||
private final Collection<JetFile> files;
|
private final Collection<JetFile> files;
|
||||||
private final NamespaceDescriptor descriptor;
|
private final NamespaceDescriptor descriptor;
|
||||||
|
|
||||||
public NamespaceCodegen(
|
public NamespaceCodegen(
|
||||||
@NotNull ClassBuilderOnDemand v,
|
@NotNull ClassBuilderOnDemand v,
|
||||||
@NotNull final FqName fqName,
|
@NotNull final FqName fqName,
|
||||||
GenerationState state,
|
@NotNull GenerationState state,
|
||||||
Collection<JetFile> namespaceFiles
|
@NotNull Collection<JetFile> namespaceFiles
|
||||||
) {
|
) {
|
||||||
super(state, null);
|
super(state, null);
|
||||||
checkAllFilesHaveSameNamespace(namespaceFiles);
|
checkAllFilesHaveSameNamespace(namespaceFiles);
|
||||||
@@ -165,9 +164,12 @@ public class NamespaceCodegen extends MemberCodegen {
|
|||||||
av.visitEnd();
|
av.visitEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private ClassBuilder generate(@NotNull JetFile file) {
|
private ClassBuilder generate(@NotNull JetFile file) {
|
||||||
boolean generateSrcClass = false;
|
boolean generateSrcClass = false;
|
||||||
|
FieldOwnerContext namespaceImpl = CodegenContext.STATIC.intoNamespace(descriptor);
|
||||||
|
|
||||||
for (JetDeclaration declaration : file.getDeclarations()) {
|
for (JetDeclaration declaration : file.getDeclarations()) {
|
||||||
if (declaration instanceof JetProperty || declaration instanceof JetNamedFunction) {
|
if (declaration instanceof JetProperty || declaration instanceof JetNamedFunction) {
|
||||||
generateSrcClass = true;
|
generateSrcClass = true;
|
||||||
@@ -178,7 +180,7 @@ public class NamespaceCodegen extends MemberCodegen {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (declaration instanceof JetScript) {
|
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);
|
Type namespacePartType = getNamespacePartType(getPackageClassFqName(name), file);
|
||||||
ClassBuilder builder = state.getFactory().forNamespacePart(namespacePartType, file);
|
ClassBuilder builder = state.getFactory().forNamespacePart(namespacePartType, file);
|
||||||
|
|
||||||
builder.defineClass(file, V1_6,
|
NamespacePartCodegen namespacePartCodegen = new NamespacePartCodegen(builder, file, namespacePartType, namespaceImpl, state);
|
||||||
ACC_PUBLIC | ACC_FINAL,
|
namespacePartCodegen.generate();
|
||||||
namespacePartType.getInternalName(),
|
|
||||||
null,
|
|
||||||
//"jet/lang/Namespace",
|
|
||||||
"java/lang/Object",
|
|
||||||
new String[0]
|
|
||||||
);
|
|
||||||
builder.visitSource(file.getName(), null);
|
|
||||||
|
|
||||||
writeKotlinPackageFragmentAnnotation(builder);
|
FieldOwnerContext nameSpacePart = CodegenContext.STATIC.intoNamespaceFacade(namespacePartType, descriptor);
|
||||||
|
|
||||||
FieldOwnerContext nameSpaceContext = CodegenContext.STATIC.intoNamespace(descriptor);
|
|
||||||
|
|
||||||
FieldOwnerContext nameSpacePart = CodegenContext.STATIC.intoNamespacePart(namespacePartType, descriptor);
|
|
||||||
|
|
||||||
for (JetDeclaration declaration : file.getDeclarations()) {
|
for (JetDeclaration declaration : file.getDeclarations()) {
|
||||||
if (declaration instanceof JetNamedFunction || declaration instanceof JetProperty) {
|
if (declaration instanceof JetNamedFunction || declaration instanceof JetProperty) {
|
||||||
genFunctionOrProperty(nameSpaceContext, (JetTypeParameterListOwner) declaration, builder);
|
|
||||||
genFunctionOrProperty(nameSpacePart, (JetTypeParameterListOwner) declaration, v.getClassBuilder());
|
genFunctionOrProperty(nameSpacePart, (JetTypeParameterListOwner) declaration, v.getClassBuilder());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
generateStaticInitializers(builder, file, nameSpaceContext);
|
|
||||||
|
|
||||||
builder.done();
|
|
||||||
|
|
||||||
return builder;
|
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) {
|
public void generateClassOrObject(@NotNull JetClassOrObject classOrObject) {
|
||||||
CodegenContext context = CodegenContext.STATIC.intoNamespace(descriptor);
|
CodegenContext context = CodegenContext.STATIC.intoNamespace(descriptor);
|
||||||
genClassOrObject(context, classOrObject);
|
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() {
|
public void done() {
|
||||||
v.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
|
@NotNull
|
||||||
public FieldOwnerContext intoNamespacePart(@NotNull Type delegateTo, @NotNull NamespaceDescriptor descriptor) {
|
public FieldOwnerContext intoNamespaceFacade(@NotNull Type delegateTo, @NotNull NamespaceDescriptor descriptor) {
|
||||||
return new NamespaceContext(descriptor, this, new OwnerKind.StaticDelegateKind(delegateTo));
|
return new NamespaceFacadeContext(descriptor, this, new OwnerKind.StaticDelegateKind(delegateTo));
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@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