Simplify clinit codegen, delete code duplication
Logic for <clinit> generation was present both in PackagePartCodegen and in ClassBodyCodegen, move it to MemberCodegen
This commit is contained in:
@@ -21,32 +21,24 @@ import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.codegen.bridges.BridgesPackage;
|
||||
import org.jetbrains.jet.codegen.context.ClassContext;
|
||||
import org.jetbrains.jet.codegen.state.GenerationState;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.descriptors.annotations.Annotations;
|
||||
import org.jetbrains.jet.lang.descriptors.impl.SimpleFunctionDescriptorImpl;
|
||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
import org.jetbrains.org.objectweb.asm.MethodVisitor;
|
||||
import org.jetbrains.org.objectweb.asm.Type;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.jet.codegen.binding.CodegenBinding.enumEntryNeedSubclass;
|
||||
import static org.jetbrains.org.objectweb.asm.Opcodes.ACC_STATIC;
|
||||
import static org.jetbrains.org.objectweb.asm.Opcodes.RETURN;
|
||||
|
||||
public abstract class ClassBodyCodegen extends MemberCodegen {
|
||||
protected final JetClassOrObject myClass;
|
||||
protected final OwnerKind kind;
|
||||
protected final ClassDescriptor descriptor;
|
||||
protected final ClassBuilder v;
|
||||
|
||||
private MethodVisitor clInitMethod;
|
||||
|
||||
private ExpressionCodegen clInitCodegen;
|
||||
|
||||
protected ClassBodyCodegen(
|
||||
@NotNull JetClassOrObject aClass,
|
||||
@@ -56,10 +48,9 @@ public abstract class ClassBodyCodegen extends MemberCodegen {
|
||||
@Nullable MemberCodegen parentCodegen
|
||||
) {
|
||||
super(state, parentCodegen, context, v);
|
||||
descriptor = state.getBindingContext().get(BindingContext.CLASS, aClass);
|
||||
myClass = aClass;
|
||||
this.kind = context.getContextKind();
|
||||
this.v = v;
|
||||
kind = context.getContextKind();
|
||||
descriptor = bindingContext.get(BindingContext.CLASS, aClass);
|
||||
}
|
||||
|
||||
public void generate() {
|
||||
@@ -69,7 +60,7 @@ public abstract class ClassBodyCodegen extends MemberCodegen {
|
||||
|
||||
generateSyntheticParts();
|
||||
|
||||
generateStaticInitializer();
|
||||
completeStaticInitializer();
|
||||
|
||||
generateKotlinAnnotation();
|
||||
}
|
||||
@@ -152,49 +143,18 @@ public abstract class ClassBodyCodegen extends MemberCodegen {
|
||||
}
|
||||
}
|
||||
|
||||
protected @NotNull List<JetParameter> getPrimaryConstructorParameters() {
|
||||
@NotNull
|
||||
protected List<JetParameter> getPrimaryConstructorParameters() {
|
||||
if (myClass instanceof JetClass) {
|
||||
return ((JetClass) myClass).getPrimaryConstructorParameters();
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
private void generateStaticInitializer() {
|
||||
if (clInitMethod != null) {
|
||||
createOrGetClInitMethod();
|
||||
|
||||
if (state.getClassBuilderMode() == ClassBuilderMode.FULL) {
|
||||
ExpressionCodegen codegen = createOrGetClInitCodegen();
|
||||
|
||||
createOrGetClInitMethod().visitInsn(RETURN);
|
||||
FunctionCodegen.endVisit(codegen.v, "static initializer", myClass);
|
||||
}
|
||||
private void completeStaticInitializer() {
|
||||
if (clInit != null) {
|
||||
clInit.v.visitInsn(RETURN);
|
||||
FunctionCodegen.endVisit(clInit.v, "static initializer", myClass);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected MethodVisitor createOrGetClInitMethod() {
|
||||
if (clInitMethod == null) {
|
||||
clInitMethod = v.newMethod(null, ACC_STATIC, "<clinit>", "()V", null, null);
|
||||
}
|
||||
return clInitMethod;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected ExpressionCodegen createOrGetClInitCodegen() {
|
||||
assert state.getClassBuilderMode() == ClassBuilderMode.FULL;
|
||||
if (clInitCodegen == null) {
|
||||
MethodVisitor method = createOrGetClInitMethod();
|
||||
method.visitCode();
|
||||
SimpleFunctionDescriptorImpl clInit =
|
||||
SimpleFunctionDescriptorImpl.create(descriptor, Annotations.EMPTY,
|
||||
Name.special("<clinit>"),
|
||||
CallableMemberDescriptor.Kind.SYNTHESIZED);
|
||||
clInit.initialize(null, null, Collections.<TypeParameterDescriptor>emptyList(),
|
||||
Collections.<ValueParameterDescriptor>emptyList(), null, null, Visibilities.PRIVATE);
|
||||
|
||||
clInitCodegen = new ExpressionCodegen(method, new FrameMap(), Type.VOID_TYPE, context.intoFunction(clInit), state, this);
|
||||
}
|
||||
return clInitCodegen;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,24 +19,32 @@ package org.jetbrains.jet.codegen;
|
||||
import com.intellij.openapi.progress.ProcessCanceledException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.codegen.inline.InlineCodegenUtil;
|
||||
import org.jetbrains.jet.codegen.inline.NameGenerator;
|
||||
import org.jetbrains.jet.codegen.context.ClassContext;
|
||||
import org.jetbrains.jet.codegen.context.CodegenContext;
|
||||
import org.jetbrains.jet.codegen.context.FieldOwnerContext;
|
||||
import org.jetbrains.jet.codegen.inline.InlineCodegenUtil;
|
||||
import org.jetbrains.jet.codegen.inline.NameGenerator;
|
||||
import org.jetbrains.jet.codegen.state.GenerationState;
|
||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.descriptors.annotations.Annotations;
|
||||
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.name.Name;
|
||||
import org.jetbrains.jet.lang.resolve.name.SpecialNames;
|
||||
import org.jetbrains.jet.lang.types.ErrorUtils;
|
||||
import org.jetbrains.org.objectweb.asm.MethodVisitor;
|
||||
import org.jetbrains.org.objectweb.asm.Type;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import static org.jetbrains.jet.lang.descriptors.CallableMemberDescriptor.Kind.SYNTHESIZED;
|
||||
import static org.jetbrains.org.objectweb.asm.Opcodes.ACC_STATIC;
|
||||
|
||||
public class MemberCodegen extends ParentCodegenAwareImpl {
|
||||
|
||||
protected final FieldOwnerContext context;
|
||||
|
||||
private final ClassBuilder builder;
|
||||
protected final ClassBuilder v;
|
||||
protected ExpressionCodegen clInit;
|
||||
|
||||
private NameGenerator inlineNameGenerator;
|
||||
|
||||
@@ -44,11 +52,11 @@ public class MemberCodegen extends ParentCodegenAwareImpl {
|
||||
@NotNull GenerationState state,
|
||||
@Nullable MemberCodegen parentCodegen,
|
||||
@NotNull FieldOwnerContext context,
|
||||
@Nullable ClassBuilder builder
|
||||
ClassBuilder builder
|
||||
) {
|
||||
super(state, parentCodegen);
|
||||
this.context = context;
|
||||
this.builder = builder;
|
||||
this.v = builder;
|
||||
}
|
||||
|
||||
public void genFunctionOrProperty(
|
||||
@@ -121,8 +129,7 @@ public class MemberCodegen extends ParentCodegenAwareImpl {
|
||||
|
||||
private static void badDescriptor(ClassDescriptor descriptor, ClassBuilderMode mode) {
|
||||
if (mode != ClassBuilderMode.LIGHT_CLASSES) {
|
||||
throw new IllegalStateException(
|
||||
"Generating bad descriptor in ClassBuilderMode = " + mode + ": " + descriptor);
|
||||
throw new IllegalStateException("Generating bad descriptor in ClassBuilderMode = " + mode + ": " + descriptor);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,15 +139,33 @@ public class MemberCodegen extends ParentCodegenAwareImpl {
|
||||
|
||||
@NotNull
|
||||
public ClassBuilder getBuilder() {
|
||||
return builder;
|
||||
return v;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public NameGenerator getInlineNameGenerator() {
|
||||
if (inlineNameGenerator == null) {
|
||||
String prefix = InlineCodegenUtil.getInlineName(context, typeMapper);
|
||||
|
||||
inlineNameGenerator = new NameGenerator(prefix);
|
||||
}
|
||||
return inlineNameGenerator;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected ExpressionCodegen createOrGetClInitCodegen() {
|
||||
DeclarationDescriptor descriptor = context.getContextDescriptor();
|
||||
assert state.getClassBuilderMode() == ClassBuilderMode.FULL
|
||||
: "<clinit> should not be generated for light classes. Descriptor: " + descriptor;
|
||||
if (clInit == null) {
|
||||
MethodVisitor mv = v.newMethod(null, ACC_STATIC, "<clinit>", "()V", null, null);
|
||||
mv.visitCode();
|
||||
SimpleFunctionDescriptorImpl clInit =
|
||||
SimpleFunctionDescriptorImpl.create(descriptor, Annotations.EMPTY, Name.special("<clinit>"), SYNTHESIZED);
|
||||
clInit.initialize(null, null, Collections.<TypeParameterDescriptor>emptyList(),
|
||||
Collections.<ValueParameterDescriptor>emptyList(), null, null, Visibilities.PRIVATE);
|
||||
|
||||
this.clInit = new ExpressionCodegen(mv, new FrameMap(), Type.VOID_TYPE, context.intoFunction(clInit), state, this);
|
||||
}
|
||||
return clInit;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,9 +28,6 @@ import com.intellij.util.PathUtil;
|
||||
import com.intellij.util.SmartList;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.org.objectweb.asm.AnnotationVisitor;
|
||||
import org.jetbrains.org.objectweb.asm.MethodVisitor;
|
||||
import org.jetbrains.org.objectweb.asm.Type;
|
||||
import org.jetbrains.jet.codegen.context.CodegenContext;
|
||||
import org.jetbrains.jet.codegen.context.FieldOwnerContext;
|
||||
import org.jetbrains.jet.codegen.context.MethodContext;
|
||||
@@ -39,7 +36,10 @@ import org.jetbrains.jet.codegen.signature.JvmMethodSignature;
|
||||
import org.jetbrains.jet.codegen.state.GenerationState;
|
||||
import org.jetbrains.jet.codegen.state.GenerationStateAware;
|
||||
import org.jetbrains.jet.config.IncrementalCompilation;
|
||||
import org.jetbrains.jet.descriptors.serialization.*;
|
||||
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.descriptors.serialization.descriptors.DeserializedCallableMemberDescriptor;
|
||||
import org.jetbrains.jet.descriptors.serialization.descriptors.DeserializedPropertyDescriptor;
|
||||
import org.jetbrains.jet.descriptors.serialization.descriptors.DeserializedSimpleFunctionDescriptor;
|
||||
@@ -57,14 +57,17 @@ import org.jetbrains.jet.lang.resolve.java.lazy.descriptors.LazyJavaPackageFragm
|
||||
import org.jetbrains.jet.lang.resolve.kotlin.BaseDescriptorDeserializer;
|
||||
import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
import org.jetbrains.org.objectweb.asm.AnnotationVisitor;
|
||||
import org.jetbrains.org.objectweb.asm.MethodVisitor;
|
||||
import org.jetbrains.org.objectweb.asm.Type;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
|
||||
import static org.jetbrains.jet.codegen.AsmUtil.asmDescByFqNameWithoutInnerClasses;
|
||||
import static org.jetbrains.jet.codegen.AsmUtil.asmTypeByFqNameWithoutInnerClasses;
|
||||
import static org.jetbrains.jet.descriptors.serialization.NameSerializationUtil.createNameResolver;
|
||||
import static org.jetbrains.jet.lang.resolve.java.PackageClassUtils.getPackageClassFqName;
|
||||
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
|
||||
|
||||
public class PackageCodegen extends GenerationStateAware {
|
||||
@NotNull
|
||||
@@ -321,7 +324,7 @@ public class PackageCodegen extends GenerationStateAware {
|
||||
@NotNull
|
||||
@Override
|
||||
public ClassBuilder getBuilder() {
|
||||
return v.getClassBuilder();
|
||||
return PackageCodegen.this.v.getClassBuilder();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -19,56 +19,37 @@ package org.jetbrains.jet.codegen;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.org.objectweb.asm.MethodVisitor;
|
||||
import org.jetbrains.org.objectweb.asm.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.Annotations;
|
||||
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.name.Name;
|
||||
import org.jetbrains.org.objectweb.asm.Type;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
|
||||
import static org.jetbrains.jet.codegen.AsmUtil.writeKotlinSyntheticClassAnnotation;
|
||||
import static org.jetbrains.jet.lang.resolve.java.JvmAnnotationNames.KotlinSyntheticClass;
|
||||
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
|
||||
|
||||
public class PackagePartCodegen extends MemberCodegen {
|
||||
|
||||
private final ClassBuilder v;
|
||||
|
||||
private final PackageFragmentDescriptor descriptor;
|
||||
|
||||
private final JetFile jetFile;
|
||||
|
||||
private final Type packagePartName;
|
||||
|
||||
private final FieldOwnerContext context;
|
||||
private final Type packagePartType;
|
||||
|
||||
public PackagePartCodegen(
|
||||
@NotNull ClassBuilder v,
|
||||
@NotNull JetFile jetFile,
|
||||
@NotNull Type packagePartName,
|
||||
@NotNull Type packagePartType,
|
||||
@NotNull FieldOwnerContext context,
|
||||
@NotNull GenerationState state
|
||||
) {
|
||||
super(state, null, context, v);
|
||||
this.v = v;
|
||||
this.jetFile = jetFile;
|
||||
this.packagePartName = packagePartName;
|
||||
this.context = context;
|
||||
descriptor = state.getBindingContext().get(BindingContext.FILE_TO_PACKAGE_FRAGMENT, jetFile);
|
||||
assert descriptor != null : "No package fragment found for jetFile " + jetFile + " declared package: " + jetFile.getPackageFqName();
|
||||
this.packagePartType = packagePartType;
|
||||
}
|
||||
|
||||
public void generate() {
|
||||
v.defineClass(jetFile, V1_6,
|
||||
ACC_PUBLIC | ACC_FINAL,
|
||||
packagePartName.getInternalName(),
|
||||
packagePartType.getInternalName(),
|
||||
null,
|
||||
"java/lang/Object",
|
||||
ArrayUtil.EMPTY_STRING_ARRAY
|
||||
@@ -89,44 +70,24 @@ public class PackagePartCodegen extends MemberCodegen {
|
||||
}
|
||||
|
||||
private void generateStaticInitializers() {
|
||||
List<JetProperty> properties = collectPropertiesToInitialize();
|
||||
List<JetProperty> properties = Lists.newArrayList();
|
||||
for (JetDeclaration declaration : jetFile.getDeclarations()) {
|
||||
if (declaration instanceof JetProperty) {
|
||||
JetProperty property = (JetProperty) declaration;
|
||||
if (ImplementationBodyCodegen.shouldInitializeProperty(property, typeMapper)) {
|
||||
properties.add(property);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (properties.isEmpty()) return;
|
||||
|
||||
MethodVisitor mv = v.newMethod(jetFile, ACC_STATIC, "<clinit>", "()V", null, null);
|
||||
if (state.getClassBuilderMode() == ClassBuilderMode.FULL) {
|
||||
mv.visitCode();
|
||||
ExpressionCodegen codegen = createOrGetClInitCodegen();
|
||||
|
||||
FrameMap frameMap = new FrameMap();
|
||||
|
||||
SimpleFunctionDescriptorImpl clInit =
|
||||
SimpleFunctionDescriptorImpl.create(this.descriptor, Annotations.EMPTY,
|
||||
Name.special("<clinit>"),
|
||||
CallableMemberDescriptor.Kind.SYNTHESIZED);
|
||||
clInit.initialize(null, null, Collections.<TypeParameterDescriptor>emptyList(),
|
||||
Collections.<ValueParameterDescriptor>emptyList(), null, null, Visibilities.PRIVATE);
|
||||
|
||||
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 package", jetFile);
|
||||
mv.visitEnd();
|
||||
for (JetProperty property : properties) {
|
||||
ImplementationBodyCodegen.initializeProperty(codegen, bindingContext, property);
|
||||
}
|
||||
}
|
||||
|
||||
@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;
|
||||
codegen.v.visitInsn(RETURN);
|
||||
FunctionCodegen.endVisit(codegen.v, "static initializer for package", jetFile);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user