Refactor codegen hierarchy
- pull generate() and a bunch of abstract methods from ClassBodyCodegen up to MemberCodegen - implement these methods in ScriptCodegen and PackagePartCodegen - make MemberCodegen generic on the type of the element it is generating
This commit is contained in:
@@ -33,9 +33,8 @@ import java.util.Collections;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static org.jetbrains.jet.codegen.binding.CodegenBinding.enumEntryNeedSubclass;
|
import static org.jetbrains.jet.codegen.binding.CodegenBinding.enumEntryNeedSubclass;
|
||||||
import static org.jetbrains.org.objectweb.asm.Opcodes.RETURN;
|
|
||||||
|
|
||||||
public abstract class ClassBodyCodegen extends MemberCodegen {
|
public abstract class ClassBodyCodegen extends MemberCodegen<JetClassOrObject> {
|
||||||
protected final JetClassOrObject myClass;
|
protected final JetClassOrObject myClass;
|
||||||
protected final OwnerKind kind;
|
protected final OwnerKind kind;
|
||||||
protected final ClassDescriptor descriptor;
|
protected final ClassDescriptor descriptor;
|
||||||
@@ -45,34 +44,16 @@ public abstract class ClassBodyCodegen extends MemberCodegen {
|
|||||||
@NotNull ClassContext context,
|
@NotNull ClassContext context,
|
||||||
@NotNull ClassBuilder v,
|
@NotNull ClassBuilder v,
|
||||||
@NotNull GenerationState state,
|
@NotNull GenerationState state,
|
||||||
@Nullable MemberCodegen parentCodegen
|
@Nullable MemberCodegen<?> parentCodegen
|
||||||
) {
|
) {
|
||||||
super(state, parentCodegen, context, v);
|
super(state, parentCodegen, context, aClass, v);
|
||||||
myClass = aClass;
|
myClass = aClass;
|
||||||
kind = context.getContextKind();
|
kind = context.getContextKind();
|
||||||
descriptor = bindingContext.get(BindingContext.CLASS, aClass);
|
descriptor = bindingContext.get(BindingContext.CLASS, aClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void generate() {
|
@Override
|
||||||
generateDeclaration();
|
protected void generateBody() {
|
||||||
|
|
||||||
generateClassBody();
|
|
||||||
|
|
||||||
generateSyntheticParts();
|
|
||||||
|
|
||||||
completeStaticInitializer();
|
|
||||||
|
|
||||||
generateKotlinAnnotation();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract void generateDeclaration();
|
|
||||||
|
|
||||||
protected abstract void generateKotlinAnnotation();
|
|
||||||
|
|
||||||
protected void generateSyntheticParts() {
|
|
||||||
}
|
|
||||||
|
|
||||||
private void generateClassBody() {
|
|
||||||
FunctionCodegen functionCodegen = new FunctionCodegen(context, v, state, this);
|
FunctionCodegen functionCodegen = new FunctionCodegen(context, v, state, this);
|
||||||
PropertyCodegen propertyCodegen = new PropertyCodegen(context, v, functionCodegen, this);
|
PropertyCodegen propertyCodegen = new PropertyCodegen(context, v, functionCodegen, this);
|
||||||
|
|
||||||
@@ -150,11 +131,4 @@ public abstract class ClassBodyCodegen extends MemberCodegen {
|
|||||||
}
|
}
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void completeStaticInitializer() {
|
|
||||||
if (clInit != null) {
|
|
||||||
clInit.v.visitInsn(RETURN);
|
|
||||||
FunctionCodegen.endVisit(clInit.v, "static initializer", myClass);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,10 +21,6 @@ import com.intellij.psi.PsiElement;
|
|||||||
import com.intellij.util.ArrayUtil;
|
import com.intellij.util.ArrayUtil;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.org.objectweb.asm.MethodVisitor;
|
|
||||||
import org.jetbrains.org.objectweb.asm.Type;
|
|
||||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
|
|
||||||
import org.jetbrains.org.objectweb.asm.commons.Method;
|
|
||||||
import org.jetbrains.jet.codegen.binding.CalculatedClosure;
|
import org.jetbrains.jet.codegen.binding.CalculatedClosure;
|
||||||
import org.jetbrains.jet.codegen.context.CodegenContext;
|
import org.jetbrains.jet.codegen.context.CodegenContext;
|
||||||
import org.jetbrains.jet.codegen.context.LocalLookup;
|
import org.jetbrains.jet.codegen.context.LocalLookup;
|
||||||
@@ -40,15 +36,19 @@ import org.jetbrains.jet.lang.resolve.java.sam.SingleAbstractMethodUtils;
|
|||||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||||
import org.jetbrains.jet.lang.types.JetType;
|
import org.jetbrains.jet.lang.types.JetType;
|
||||||
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
||||||
|
import org.jetbrains.org.objectweb.asm.MethodVisitor;
|
||||||
|
import org.jetbrains.org.objectweb.asm.Type;
|
||||||
|
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
|
||||||
|
import org.jetbrains.org.objectweb.asm.commons.Method;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
|
|
||||||
import static org.jetbrains.jet.codegen.AsmUtil.*;
|
import static org.jetbrains.jet.codegen.AsmUtil.*;
|
||||||
import static org.jetbrains.jet.codegen.CodegenUtil.isConst;
|
import static org.jetbrains.jet.codegen.CodegenUtil.isConst;
|
||||||
import static org.jetbrains.jet.codegen.binding.CodegenBinding.*;
|
import static org.jetbrains.jet.codegen.binding.CodegenBinding.*;
|
||||||
import static org.jetbrains.jet.lang.resolve.java.JvmAnnotationNames.KotlinSyntheticClass;
|
import static org.jetbrains.jet.lang.resolve.java.JvmAnnotationNames.KotlinSyntheticClass;
|
||||||
|
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
|
||||||
|
|
||||||
public class ClosureCodegen extends ParentCodegenAwareImpl {
|
public class ClosureCodegen extends ParentCodegenAwareImpl {
|
||||||
private final PsiElement fun;
|
private final PsiElement fun;
|
||||||
@@ -74,7 +74,7 @@ public class ClosureCodegen extends ParentCodegenAwareImpl {
|
|||||||
@NotNull KotlinSyntheticClass.Kind syntheticClassKind,
|
@NotNull KotlinSyntheticClass.Kind syntheticClassKind,
|
||||||
@NotNull LocalLookup localLookup,
|
@NotNull LocalLookup localLookup,
|
||||||
@NotNull FunctionGenerationStrategy strategy,
|
@NotNull FunctionGenerationStrategy strategy,
|
||||||
@Nullable MemberCodegen parentCodegen
|
@Nullable MemberCodegen<?> parentCodegen
|
||||||
) {
|
) {
|
||||||
super(state, parentCodegen);
|
super(state, parentCodegen);
|
||||||
|
|
||||||
|
|||||||
@@ -16,12 +16,9 @@
|
|||||||
|
|
||||||
package org.jetbrains.jet.codegen;
|
package org.jetbrains.jet.codegen;
|
||||||
|
|
||||||
import com.intellij.openapi.util.Condition;
|
|
||||||
import com.intellij.openapi.util.io.FileUtil;
|
import com.intellij.openapi.util.io.FileUtil;
|
||||||
import com.intellij.openapi.vfs.VirtualFile;
|
import com.intellij.openapi.vfs.VirtualFile;
|
||||||
import com.intellij.util.containers.ContainerUtil;
|
|
||||||
import com.intellij.util.containers.Stack;
|
import com.intellij.util.containers.Stack;
|
||||||
import jet.runtime.typeinfo.JetValueParameter;
|
|
||||||
import kotlin.Function1;
|
import kotlin.Function1;
|
||||||
import kotlin.KotlinPackage;
|
import kotlin.KotlinPackage;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
@@ -240,12 +237,11 @@ public class CodegenUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static ImplementationBodyCodegen getParentBodyCodegen(@Nullable MemberCodegen classBodyCodegen) {
|
public static ImplementationBodyCodegen getParentBodyCodegen(@Nullable MemberCodegen<?> classBodyCodegen) {
|
||||||
assert classBodyCodegen != null &&
|
assert classBodyCodegen != null && classBodyCodegen.getParentCodegen() instanceof ImplementationBodyCodegen
|
||||||
classBodyCodegen
|
: "Class object should have appropriate parent BodyCodegen";
|
||||||
.getParentCodegen() instanceof ImplementationBodyCodegen : "Class object should have appropriate parent BodyCodegen";
|
|
||||||
|
|
||||||
return ((ImplementationBodyCodegen) classBodyCodegen.getParentCodegen());
|
return (ImplementationBodyCodegen) classBodyCodegen.getParentCodegen();
|
||||||
}
|
}
|
||||||
|
|
||||||
static int getPathHashCode(@NotNull VirtualFile file) {
|
static int getPathHashCode(@NotNull VirtualFile file) {
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
|||||||
private final Stack<BlockStackElement> blockStackElements = new Stack<BlockStackElement>();
|
private final Stack<BlockStackElement> blockStackElements = new Stack<BlockStackElement>();
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private final MemberCodegen parentCodegen;
|
private final MemberCodegen<?> parentCodegen;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* When we create a temporary variable to hold some value not to compute it many times
|
* When we create a temporary variable to hold some value not to compute it many times
|
||||||
@@ -120,16 +120,11 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
|||||||
ClassDescriptor classDescriptor = bindingContext.get(CLASS, objectDeclaration);
|
ClassDescriptor classDescriptor = bindingContext.get(CLASS, objectDeclaration);
|
||||||
assert classDescriptor != null;
|
assert classDescriptor != null;
|
||||||
|
|
||||||
//noinspection SuspiciousMethodCalls
|
|
||||||
CalculatedClosure closure = bindingContext.get(CLOSURE, classDescriptor);
|
|
||||||
|
|
||||||
ClassContext objectContext = context.intoAnonymousClass(classDescriptor, this);
|
ClassContext objectContext = context.intoAnonymousClass(classDescriptor, this);
|
||||||
ImplementationBodyCodegen implementationBodyCodegen =
|
|
||||||
new ImplementationBodyCodegen(objectDeclaration, objectContext, classBuilder, state, getParentCodegen());
|
|
||||||
|
|
||||||
implementationBodyCodegen.generate();
|
new ImplementationBodyCodegen(objectDeclaration, objectContext, classBuilder, state, getParentCodegen()).generate();
|
||||||
|
|
||||||
return closure;
|
return bindingContext.get(CLOSURE, classDescriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
static class BlockStackElement {
|
static class BlockStackElement {
|
||||||
@@ -167,7 +162,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
|||||||
@NotNull Type returnType,
|
@NotNull Type returnType,
|
||||||
@NotNull MethodContext context,
|
@NotNull MethodContext context,
|
||||||
@NotNull GenerationState state,
|
@NotNull GenerationState state,
|
||||||
@Nullable MemberCodegen parentCodegen
|
@Nullable MemberCodegen<?> parentCodegen
|
||||||
) {
|
) {
|
||||||
this.myFrameMap = myMap;
|
this.myFrameMap = myMap;
|
||||||
this.parentCodegen = parentCodegen;
|
this.parentCodegen = parentCodegen;
|
||||||
@@ -209,7 +204,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
|||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public MemberCodegen getParentCodegen() {
|
public MemberCodegen<?> getParentCodegen() {
|
||||||
return parentCodegen;
|
return parentCodegen;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -279,7 +274,6 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
|||||||
|
|
||||||
ClassContext objectContext = context.intoAnonymousClass(descriptor, this);
|
ClassContext objectContext = context.intoAnonymousClass(descriptor, this);
|
||||||
new ImplementationBodyCodegen(declaration, objectContext, classBuilder, state, getParentCodegen()).generate();
|
new ImplementationBodyCodegen(declaration, objectContext, classBuilder, state, getParentCodegen()).generate();
|
||||||
classBuilder.done();
|
|
||||||
|
|
||||||
return StackValue.none();
|
return StackValue.none();
|
||||||
}
|
}
|
||||||
@@ -3778,7 +3772,7 @@ The "returned" value of try expression with no finally is either the last expres
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private ScriptCodegen getParentScriptCodegen() {
|
private ScriptCodegen getParentScriptCodegen() {
|
||||||
MemberCodegen codegen = parentCodegen;
|
MemberCodegen<?> codegen = parentCodegen;
|
||||||
while (codegen != null) {
|
while (codegen != null) {
|
||||||
if (codegen instanceof ScriptCodegen) {
|
if (codegen instanceof ScriptCodegen) {
|
||||||
return (ScriptCodegen) codegen;
|
return (ScriptCodegen) codegen;
|
||||||
|
|||||||
@@ -80,7 +80,12 @@ public class FunctionCodegen extends ParentCodegenAwareImpl {
|
|||||||
|
|
||||||
private final ClassBuilder v;
|
private final ClassBuilder v;
|
||||||
|
|
||||||
public FunctionCodegen(@NotNull CodegenContext owner, @NotNull ClassBuilder v, @NotNull GenerationState state, MemberCodegen parentCodegen) {
|
public FunctionCodegen(
|
||||||
|
@NotNull CodegenContext owner,
|
||||||
|
@NotNull ClassBuilder v,
|
||||||
|
@NotNull GenerationState state,
|
||||||
|
MemberCodegen<?> parentCodegen
|
||||||
|
) {
|
||||||
super(state, parentCodegen);
|
super(state, parentCodegen);
|
||||||
this.owner = owner;
|
this.owner = owner;
|
||||||
this.v = v;
|
this.v = v;
|
||||||
@@ -277,7 +282,7 @@ public class FunctionCodegen extends ParentCodegenAwareImpl {
|
|||||||
@NotNull MethodContext context,
|
@NotNull MethodContext context,
|
||||||
@NotNull JvmMethodSignature signature,
|
@NotNull JvmMethodSignature signature,
|
||||||
@NotNull FunctionGenerationStrategy strategy,
|
@NotNull FunctionGenerationStrategy strategy,
|
||||||
@NotNull MemberCodegen parentCodegen
|
@NotNull MemberCodegen<?> parentCodegen
|
||||||
) {
|
) {
|
||||||
mv.visitCode();
|
mv.visitCode();
|
||||||
|
|
||||||
|
|||||||
@@ -18,13 +18,13 @@ package org.jetbrains.jet.codegen;
|
|||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.org.objectweb.asm.MethodVisitor;
|
|
||||||
import org.jetbrains.jet.codegen.context.MethodContext;
|
import org.jetbrains.jet.codegen.context.MethodContext;
|
||||||
import org.jetbrains.jet.codegen.signature.JvmMethodSignature;
|
import org.jetbrains.jet.codegen.signature.JvmMethodSignature;
|
||||||
import org.jetbrains.jet.codegen.state.GenerationState;
|
import org.jetbrains.jet.codegen.state.GenerationState;
|
||||||
import org.jetbrains.jet.codegen.state.JetTypeMapper;
|
import org.jetbrains.jet.codegen.state.JetTypeMapper;
|
||||||
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
|
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
|
||||||
import org.jetbrains.jet.lang.psi.JetDeclarationWithBody;
|
import org.jetbrains.jet.lang.psi.JetDeclarationWithBody;
|
||||||
|
import org.jetbrains.org.objectweb.asm.MethodVisitor;
|
||||||
|
|
||||||
public abstract class FunctionGenerationStrategy {
|
public abstract class FunctionGenerationStrategy {
|
||||||
|
|
||||||
@@ -34,7 +34,7 @@ public abstract class FunctionGenerationStrategy {
|
|||||||
@NotNull MethodVisitor mv,
|
@NotNull MethodVisitor mv,
|
||||||
@NotNull JvmMethodSignature signature,
|
@NotNull JvmMethodSignature signature,
|
||||||
@NotNull MethodContext context,
|
@NotNull MethodContext context,
|
||||||
@Nullable MemberCodegen parentCodegen
|
@Nullable MemberCodegen<?> parentCodegen
|
||||||
);
|
);
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -82,7 +82,7 @@ public abstract class FunctionGenerationStrategy {
|
|||||||
@NotNull MethodVisitor mv,
|
@NotNull MethodVisitor mv,
|
||||||
@NotNull JvmMethodSignature signature,
|
@NotNull JvmMethodSignature signature,
|
||||||
@NotNull MethodContext context,
|
@NotNull MethodContext context,
|
||||||
@Nullable MemberCodegen parentCodegen
|
@Nullable MemberCodegen<?> parentCodegen
|
||||||
) {
|
) {
|
||||||
ExpressionCodegen codegen = new ExpressionCodegen(mv, getFrameMap(state.getTypeMapper(), context),
|
ExpressionCodegen codegen = new ExpressionCodegen(mv, getFrameMap(state.getTypeMapper(), context),
|
||||||
signature.getReturnType(), context, state, parentCodegen);
|
signature.getReturnType(), context, state, parentCodegen);
|
||||||
|
|||||||
@@ -84,10 +84,10 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
|
|
||||||
public ImplementationBodyCodegen(
|
public ImplementationBodyCodegen(
|
||||||
@NotNull JetClassOrObject aClass,
|
@NotNull JetClassOrObject aClass,
|
||||||
@NotNull ClassContext context,
|
@NotNull ClassContext context,
|
||||||
@NotNull ClassBuilder v,
|
@NotNull ClassBuilder v,
|
||||||
@NotNull GenerationState state,
|
@NotNull GenerationState state,
|
||||||
@Nullable MemberCodegen parentCodegen
|
@Nullable MemberCodegen<?> parentCodegen
|
||||||
) {
|
) {
|
||||||
super(aClass, context, v, state, parentCodegen);
|
super(aClass, context, v, state, parentCodegen);
|
||||||
this.classAsmType = typeMapper.mapClass(descriptor);
|
this.classAsmType = typeMapper.mapClass(descriptor);
|
||||||
@@ -478,7 +478,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
|
|
||||||
private void generateDelegatedPropertyMetadataArray() {
|
private void generateDelegatedPropertyMetadataArray() {
|
||||||
if (state.getClassBuilderMode() == ClassBuilderMode.FULL) {
|
if (state.getClassBuilderMode() == ClassBuilderMode.FULL) {
|
||||||
generatePropertyMetadataArrayFieldIfNeeded(classAsmType, myClass);
|
generatePropertyMetadataArrayFieldIfNeeded(classAsmType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -875,7 +875,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
@NotNull MethodVisitor mv,
|
@NotNull MethodVisitor mv,
|
||||||
@NotNull JvmMethodSignature signature,
|
@NotNull JvmMethodSignature signature,
|
||||||
@NotNull MethodContext context,
|
@NotNull MethodContext context,
|
||||||
@Nullable MemberCodegen parentCodegen
|
@Nullable MemberCodegen<?> parentCodegen
|
||||||
) {
|
) {
|
||||||
Type componentType = signature.getReturnType();
|
Type componentType = signature.getReturnType();
|
||||||
InstructionAdapter iv = new InstructionAdapter(mv);
|
InstructionAdapter iv = new InstructionAdapter(mv);
|
||||||
@@ -900,7 +900,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
@NotNull MethodVisitor mv,
|
@NotNull MethodVisitor mv,
|
||||||
@NotNull JvmMethodSignature signature,
|
@NotNull JvmMethodSignature signature,
|
||||||
@NotNull MethodContext context,
|
@NotNull MethodContext context,
|
||||||
@Nullable MemberCodegen parentCodegen
|
@Nullable MemberCodegen<?> parentCodegen
|
||||||
) {
|
) {
|
||||||
InstructionAdapter iv = new InstructionAdapter(mv);
|
InstructionAdapter iv = new InstructionAdapter(mv);
|
||||||
|
|
||||||
@@ -1280,14 +1280,14 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
final ImplementationBodyCodegen parentCodegen = getParentBodyCodegen(this);
|
final ImplementationBodyCodegen parentCodegen = getParentBodyCodegen(this);
|
||||||
//generate object$
|
//generate object$
|
||||||
parentCodegen.genInitSingleton(descriptor, StackValue.singleton(descriptor, typeMapper));
|
parentCodegen.genInitSingleton(descriptor, StackValue.singleton(descriptor, typeMapper));
|
||||||
generateInitializers(myClass.getDeclarations(), new Function0<ExpressionCodegen>() {
|
generateInitializers(new Function0<ExpressionCodegen>() {
|
||||||
@Override
|
@Override
|
||||||
public ExpressionCodegen invoke() {
|
public ExpressionCodegen invoke() {
|
||||||
return parentCodegen.createOrGetClInitCodegen();
|
return parentCodegen.createOrGetClInitCodegen();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
generateInitializers(myClass.getDeclarations(), new Function0<ExpressionCodegen>() {
|
generateInitializers(new Function0<ExpressionCodegen>() {
|
||||||
@Override
|
@Override
|
||||||
public ExpressionCodegen invoke() {
|
public ExpressionCodegen invoke() {
|
||||||
return codegen;
|
return codegen;
|
||||||
|
|||||||
@@ -55,7 +55,8 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.VARIABLE;
|
|||||||
import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.*;
|
import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.*;
|
||||||
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
|
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
|
||||||
|
|
||||||
public abstract class MemberCodegen extends ParentCodegenAwareImpl {
|
public abstract class MemberCodegen<T extends JetElement/* TODO: & JetDeclarationContainer*/> extends ParentCodegenAwareImpl {
|
||||||
|
protected final T element;
|
||||||
protected final FieldOwnerContext context;
|
protected final FieldOwnerContext context;
|
||||||
protected final ClassBuilder v;
|
protected final ClassBuilder v;
|
||||||
protected ExpressionCodegen clInit;
|
protected ExpressionCodegen clInit;
|
||||||
@@ -64,15 +65,47 @@ public abstract class MemberCodegen extends ParentCodegenAwareImpl {
|
|||||||
|
|
||||||
public MemberCodegen(
|
public MemberCodegen(
|
||||||
@NotNull GenerationState state,
|
@NotNull GenerationState state,
|
||||||
@Nullable MemberCodegen parentCodegen,
|
@Nullable MemberCodegen<?> parentCodegen,
|
||||||
@NotNull FieldOwnerContext context,
|
@NotNull FieldOwnerContext context,
|
||||||
|
T element,
|
||||||
ClassBuilder builder
|
ClassBuilder builder
|
||||||
) {
|
) {
|
||||||
super(state, parentCodegen);
|
super(state, parentCodegen);
|
||||||
|
this.element = element;
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.v = builder;
|
this.v = builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void generate() {
|
||||||
|
generateDeclaration();
|
||||||
|
|
||||||
|
generateBody();
|
||||||
|
|
||||||
|
generateSyntheticParts();
|
||||||
|
|
||||||
|
generateKotlinAnnotation();
|
||||||
|
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract void generateDeclaration();
|
||||||
|
|
||||||
|
protected abstract void generateBody();
|
||||||
|
|
||||||
|
protected void generateSyntheticParts() {
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract void generateKotlinAnnotation();
|
||||||
|
|
||||||
|
private void done() {
|
||||||
|
if (clInit != null) {
|
||||||
|
clInit.v.visitInsn(RETURN);
|
||||||
|
FunctionCodegen.endVisit(clInit.v, "static initializer", element);
|
||||||
|
}
|
||||||
|
|
||||||
|
v.done();
|
||||||
|
}
|
||||||
|
|
||||||
public void genFunctionOrProperty(
|
public void genFunctionOrProperty(
|
||||||
@NotNull JetTypeParameterListOwner functionOrProperty,
|
@NotNull JetTypeParameterListOwner functionOrProperty,
|
||||||
@NotNull ClassBuilder classBuilder
|
@NotNull ClassBuilder classBuilder
|
||||||
@@ -115,7 +148,7 @@ public abstract class MemberCodegen extends ParentCodegenAwareImpl {
|
|||||||
@NotNull CodegenContext parentContext,
|
@NotNull CodegenContext parentContext,
|
||||||
@NotNull JetClassOrObject aClass,
|
@NotNull JetClassOrObject aClass,
|
||||||
@NotNull GenerationState state,
|
@NotNull GenerationState state,
|
||||||
@Nullable MemberCodegen parentCodegen
|
@Nullable MemberCodegen<?> parentCodegen
|
||||||
) {
|
) {
|
||||||
ClassDescriptor descriptor = state.getBindingContext().get(BindingContext.CLASS, aClass);
|
ClassDescriptor descriptor = state.getBindingContext().get(BindingContext.CLASS, aClass);
|
||||||
|
|
||||||
@@ -131,13 +164,11 @@ public abstract class MemberCodegen extends ParentCodegenAwareImpl {
|
|||||||
ClassBuilder classBuilder = state.getFactory().forClassImplementation(descriptor, aClass.getContainingFile());
|
ClassBuilder classBuilder = state.getFactory().forClassImplementation(descriptor, aClass.getContainingFile());
|
||||||
ClassContext classContext = parentContext.intoClass(descriptor, OwnerKind.IMPLEMENTATION, state);
|
ClassContext classContext = parentContext.intoClass(descriptor, OwnerKind.IMPLEMENTATION, state);
|
||||||
new ImplementationBodyCodegen(aClass, classContext, classBuilder, state, parentCodegen).generate();
|
new ImplementationBodyCodegen(aClass, classContext, classBuilder, state, parentCodegen).generate();
|
||||||
classBuilder.done();
|
|
||||||
|
|
||||||
if (aClass instanceof JetClass && ((JetClass) aClass).isTrait()) {
|
if (aClass instanceof JetClass && ((JetClass) aClass).isTrait()) {
|
||||||
ClassBuilder traitBuilder = state.getFactory().forTraitImplementation(descriptor, state, aClass.getContainingFile());
|
ClassBuilder traitImplBuilder = state.getFactory().forTraitImplementation(descriptor, state, aClass.getContainingFile());
|
||||||
new TraitImplBodyCodegen(aClass, parentContext.intoClass(descriptor, OwnerKind.TRAIT_IMPL, state), traitBuilder, state, parentCodegen)
|
ClassContext traitImplContext = parentContext.intoClass(descriptor, OwnerKind.TRAIT_IMPL, state);
|
||||||
.generate();
|
new TraitImplBodyCodegen(aClass, traitImplContext, traitImplBuilder, state, parentCodegen).generate();
|
||||||
traitBuilder.done();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -151,11 +182,6 @@ public abstract class MemberCodegen extends ParentCodegenAwareImpl {
|
|||||||
genClassOrObject(context, aClass, state, this);
|
genClassOrObject(context, aClass, state, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public ClassBuilder getBuilder() {
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public NameGenerator getInlineNameGenerator() {
|
public NameGenerator getInlineNameGenerator() {
|
||||||
if (inlineNameGenerator == null) {
|
if (inlineNameGenerator == null) {
|
||||||
@@ -183,9 +209,9 @@ public abstract class MemberCodegen extends ParentCodegenAwareImpl {
|
|||||||
return clInit;
|
return clInit;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void generateInitializers(@NotNull List<JetDeclaration> declarations, @NotNull Function0<ExpressionCodegen> createCodegen) {
|
protected void generateInitializers(@NotNull Function0<ExpressionCodegen> createCodegen) {
|
||||||
NotNullLazyValue<ExpressionCodegen> codegen = LockBasedStorageManager.NO_LOCKS.createLazyValue(createCodegen);
|
NotNullLazyValue<ExpressionCodegen> codegen = LockBasedStorageManager.NO_LOCKS.createLazyValue(createCodegen);
|
||||||
for (JetDeclaration declaration : declarations) {
|
for (JetDeclaration declaration : ((JetDeclarationContainer) element).getDeclarations()) {
|
||||||
if (declaration instanceof JetProperty) {
|
if (declaration instanceof JetProperty) {
|
||||||
if (shouldInitializeProperty((JetProperty) declaration)) {
|
if (shouldInitializeProperty((JetProperty) declaration)) {
|
||||||
initializeProperty(codegen.invoke(), (JetProperty) declaration);
|
initializeProperty(codegen.invoke(), (JetProperty) declaration);
|
||||||
@@ -197,7 +223,7 @@ public abstract class MemberCodegen extends ParentCodegenAwareImpl {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void initializeProperty(@NotNull ExpressionCodegen codegen, @NotNull JetProperty property) {
|
private void initializeProperty(@NotNull ExpressionCodegen codegen, @NotNull JetProperty property) {
|
||||||
PropertyDescriptor propertyDescriptor = (PropertyDescriptor) bindingContext.get(VARIABLE, property);
|
PropertyDescriptor propertyDescriptor = (PropertyDescriptor) bindingContext.get(VARIABLE, property);
|
||||||
assert propertyDescriptor != null;
|
assert propertyDescriptor != null;
|
||||||
|
|
||||||
@@ -221,7 +247,7 @@ public abstract class MemberCodegen extends ParentCodegenAwareImpl {
|
|||||||
propValue.store(type, codegen.v);
|
propValue.store(type, codegen.v);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean shouldInitializeProperty(@NotNull JetProperty property) {
|
private boolean shouldInitializeProperty(@NotNull JetProperty property) {
|
||||||
JetExpression initializer = property.getDelegateExpressionOrInitializer();
|
JetExpression initializer = property.getDelegateExpressionOrInitializer();
|
||||||
if (initializer == null) return false;
|
if (initializer == null) return false;
|
||||||
|
|
||||||
@@ -287,9 +313,9 @@ public abstract class MemberCodegen extends ParentCodegenAwareImpl {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void generatePropertyMetadataArrayFieldIfNeeded(@NotNull Type thisAsmType, @NotNull JetDeclarationContainer container) {
|
protected void generatePropertyMetadataArrayFieldIfNeeded(@NotNull Type thisAsmType) {
|
||||||
List<JetProperty> delegatedProperties = new ArrayList<JetProperty>();
|
List<JetProperty> delegatedProperties = new ArrayList<JetProperty>();
|
||||||
for (JetDeclaration declaration : container.getDeclarations()) {
|
for (JetDeclaration declaration : ((JetDeclarationContainer) element).getDeclarations()) {
|
||||||
if (declaration instanceof JetProperty) {
|
if (declaration instanceof JetProperty) {
|
||||||
JetProperty property = (JetProperty) declaration;
|
JetProperty property = (JetProperty) declaration;
|
||||||
if (property.getDelegate() != null) {
|
if (property.getDelegate() != null) {
|
||||||
|
|||||||
@@ -167,7 +167,7 @@ public class PackageCodegen extends GenerationStateAware {
|
|||||||
@NotNull MethodVisitor mv,
|
@NotNull MethodVisitor mv,
|
||||||
@NotNull JvmMethodSignature signature,
|
@NotNull JvmMethodSignature signature,
|
||||||
@NotNull MethodContext context,
|
@NotNull MethodContext context,
|
||||||
@Nullable MemberCodegen parentCodegen
|
@Nullable MemberCodegen<?> parentCodegen
|
||||||
) {
|
) {
|
||||||
throw new IllegalStateException("shouldn't be called");
|
throw new IllegalStateException("shouldn't be called");
|
||||||
}
|
}
|
||||||
@@ -295,7 +295,7 @@ public class PackageCodegen extends GenerationStateAware {
|
|||||||
|
|
||||||
FieldOwnerContext packageFacade = CodegenContext.STATIC.intoPackageFacade(packagePartType, packageFragment);
|
FieldOwnerContext packageFacade = CodegenContext.STATIC.intoPackageFacade(packagePartType, packageFragment);
|
||||||
|
|
||||||
final MemberCodegen memberCodegen = getMemberCodegen(packageFacade);
|
final MemberCodegen<?> memberCodegen = getMemberCodegen(packageFacade);
|
||||||
|
|
||||||
for (final JetDeclaration declaration : file.getDeclarations()) {
|
for (final JetDeclaration declaration : file.getDeclarations()) {
|
||||||
if (declaration instanceof JetNamedFunction || declaration instanceof JetProperty) {
|
if (declaration instanceof JetNamedFunction || declaration instanceof JetProperty) {
|
||||||
@@ -307,8 +307,7 @@ public class PackageCodegen extends GenerationStateAware {
|
|||||||
new Runnable() {
|
new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
memberCodegen.genFunctionOrProperty(
|
memberCodegen.genFunctionOrProperty((JetTypeParameterListOwner) declaration, v.getClassBuilder());
|
||||||
(JetTypeParameterListOwner) declaration, v.getClassBuilder());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@@ -319,12 +318,21 @@ public class PackageCodegen extends GenerationStateAware {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//TODO: FIX: Default method generated at facade without delegation
|
//TODO: FIX: Default method generated at facade without delegation
|
||||||
private MemberCodegen getMemberCodegen(@NotNull FieldOwnerContext packageFacade) {
|
private MemberCodegen<?> getMemberCodegen(@NotNull FieldOwnerContext packageFacade) {
|
||||||
return new MemberCodegen(state, null, packageFacade, null) {
|
return new MemberCodegen<JetFile>(state, null, packageFacade, null, null) {
|
||||||
@NotNull
|
|
||||||
@Override
|
@Override
|
||||||
public ClassBuilder getBuilder() {
|
protected void generateDeclaration() {
|
||||||
return PackageCodegen.this.v.getClassBuilder();
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void generateBody() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void generateKotlinAnnotation() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,64 +24,63 @@ import org.jetbrains.jet.codegen.state.GenerationState;
|
|||||||
import org.jetbrains.jet.lang.psi.*;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
import org.jetbrains.org.objectweb.asm.Type;
|
import org.jetbrains.org.objectweb.asm.Type;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import static org.jetbrains.jet.codegen.AsmUtil.writeKotlinSyntheticClassAnnotation;
|
import static org.jetbrains.jet.codegen.AsmUtil.writeKotlinSyntheticClassAnnotation;
|
||||||
import static org.jetbrains.jet.lang.resolve.java.JvmAnnotationNames.KotlinSyntheticClass;
|
import static org.jetbrains.jet.lang.resolve.java.JvmAnnotationNames.KotlinSyntheticClass;
|
||||||
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
|
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
|
||||||
|
|
||||||
public class PackagePartCodegen extends MemberCodegen {
|
public class PackagePartCodegen extends MemberCodegen<JetFile> {
|
||||||
private final JetFile jetFile;
|
|
||||||
private final Type packagePartType;
|
private final Type packagePartType;
|
||||||
|
|
||||||
public PackagePartCodegen(
|
public PackagePartCodegen(
|
||||||
@NotNull ClassBuilder v,
|
@NotNull ClassBuilder v,
|
||||||
@NotNull JetFile jetFile,
|
@NotNull JetFile file,
|
||||||
@NotNull Type packagePartType,
|
@NotNull Type packagePartType,
|
||||||
@NotNull FieldOwnerContext context,
|
@NotNull FieldOwnerContext context,
|
||||||
@NotNull GenerationState state
|
@NotNull GenerationState state
|
||||||
) {
|
) {
|
||||||
super(state, null, context, v);
|
super(state, null, context, file, v);
|
||||||
this.jetFile = jetFile;
|
|
||||||
this.packagePartType = packagePartType;
|
this.packagePartType = packagePartType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void generate() {
|
@Override
|
||||||
v.defineClass(jetFile, V1_6,
|
protected void generateDeclaration() {
|
||||||
|
v.defineClass(element, V1_6,
|
||||||
ACC_PUBLIC | ACC_FINAL,
|
ACC_PUBLIC | ACC_FINAL,
|
||||||
packagePartType.getInternalName(),
|
packagePartType.getInternalName(),
|
||||||
null,
|
null,
|
||||||
"java/lang/Object",
|
"java/lang/Object",
|
||||||
ArrayUtil.EMPTY_STRING_ARRAY
|
ArrayUtil.EMPTY_STRING_ARRAY
|
||||||
);
|
);
|
||||||
v.visitSource(jetFile.getName(), null);
|
v.visitSource(element.getName(), null);
|
||||||
|
}
|
||||||
|
|
||||||
writeKotlinSyntheticClassAnnotation(v, KotlinSyntheticClass.Kind.PACKAGE_PART);
|
@Override
|
||||||
|
protected void generateBody() {
|
||||||
List<JetDeclaration> declarations = jetFile.getDeclarations();
|
for (JetDeclaration declaration : element.getDeclarations()) {
|
||||||
|
|
||||||
for (JetDeclaration declaration : declarations) {
|
|
||||||
if (declaration instanceof JetNamedFunction || declaration instanceof JetProperty) {
|
if (declaration instanceof JetNamedFunction || declaration instanceof JetProperty) {
|
||||||
genFunctionOrProperty((JetTypeParameterListOwner) declaration, v);
|
genFunctionOrProperty((JetTypeParameterListOwner) declaration, v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state.getClassBuilderMode() == ClassBuilderMode.FULL) {
|
if (state.getClassBuilderMode() == ClassBuilderMode.FULL) {
|
||||||
generateInitializers(declarations, new Function0<ExpressionCodegen>() {
|
generateInitializers(new Function0<ExpressionCodegen>() {
|
||||||
@Override
|
@Override
|
||||||
public ExpressionCodegen invoke() {
|
public ExpressionCodegen invoke() {
|
||||||
return createOrGetClInitCodegen();
|
return createOrGetClInitCodegen();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
generatePropertyMetadataArrayFieldIfNeeded(packagePartType, jetFile);
|
|
||||||
|
|
||||||
if (clInit != null) {
|
|
||||||
clInit.v.visitInsn(RETURN);
|
|
||||||
FunctionCodegen.endVisit(clInit.v, "static initializer for package", jetFile);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
v.done();
|
@Override
|
||||||
|
protected void generateSyntheticParts() {
|
||||||
|
if (state.getClassBuilderMode() == ClassBuilderMode.FULL) {
|
||||||
|
generatePropertyMetadataArrayFieldIfNeeded(packagePartType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void generateKotlinAnnotation() {
|
||||||
|
writeKotlinSyntheticClassAnnotation(v, KotlinSyntheticClass.Kind.PACKAGE_PART);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ package org.jetbrains.jet.codegen;
|
|||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
public interface ParentCodegenAware {
|
public interface ParentCodegenAware {
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
MemberCodegen getParentCodegen();
|
MemberCodegen<?> getParentCodegen();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,17 +22,16 @@ import org.jetbrains.jet.codegen.state.GenerationState;
|
|||||||
import org.jetbrains.jet.codegen.state.GenerationStateAware;
|
import org.jetbrains.jet.codegen.state.GenerationStateAware;
|
||||||
|
|
||||||
public class ParentCodegenAwareImpl extends GenerationStateAware implements ParentCodegenAware {
|
public class ParentCodegenAwareImpl extends GenerationStateAware implements ParentCodegenAware {
|
||||||
|
private final MemberCodegen<?> parentCodegen;
|
||||||
|
|
||||||
@Nullable private final MemberCodegen parentCodegen;
|
public ParentCodegenAwareImpl(@NotNull GenerationState state, @Nullable MemberCodegen<?> parentCodegen) {
|
||||||
|
|
||||||
public ParentCodegenAwareImpl(@NotNull GenerationState state, @Nullable MemberCodegen parentCodegen) {
|
|
||||||
super(state);
|
super(state);
|
||||||
this.parentCodegen = parentCodegen;
|
this.parentCodegen = parentCodegen;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public MemberCodegen getParentCodegen() {
|
public MemberCodegen<?> getParentCodegen() {
|
||||||
return parentCodegen;
|
return parentCodegen;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ public class PropertyCodegen extends GenerationStateAware {
|
|||||||
private final FieldOwnerContext context;
|
private final FieldOwnerContext context;
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private final MemberCodegen classBodyCodegen;
|
private final MemberCodegen<?> classBodyCodegen;
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private final OwnerKind kind;
|
private final OwnerKind kind;
|
||||||
@@ -72,7 +72,7 @@ public class PropertyCodegen extends GenerationStateAware {
|
|||||||
@NotNull FieldOwnerContext context,
|
@NotNull FieldOwnerContext context,
|
||||||
@NotNull ClassBuilder v,
|
@NotNull ClassBuilder v,
|
||||||
@NotNull FunctionCodegen functionCodegen,
|
@NotNull FunctionCodegen functionCodegen,
|
||||||
@Nullable MemberCodegen classBodyCodegen
|
@Nullable MemberCodegen<?> classBodyCodegen
|
||||||
) {
|
) {
|
||||||
super(functionCodegen.getState());
|
super(functionCodegen.getState());
|
||||||
this.v = v;
|
this.v = v;
|
||||||
|
|||||||
@@ -18,9 +18,6 @@ package org.jetbrains.jet.codegen;
|
|||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.org.objectweb.asm.MethodVisitor;
|
|
||||||
import org.jetbrains.org.objectweb.asm.Type;
|
|
||||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
|
|
||||||
import org.jetbrains.jet.codegen.context.CodegenContext;
|
import org.jetbrains.jet.codegen.context.CodegenContext;
|
||||||
import org.jetbrains.jet.codegen.state.GenerationState;
|
import org.jetbrains.jet.codegen.state.GenerationState;
|
||||||
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
||||||
@@ -34,12 +31,15 @@ import org.jetbrains.jet.lang.resolve.java.sam.SingleAbstractMethodUtils;
|
|||||||
import org.jetbrains.jet.lang.resolve.name.FqName;
|
import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||||
import org.jetbrains.jet.lang.types.JetType;
|
import org.jetbrains.jet.lang.types.JetType;
|
||||||
|
import org.jetbrains.org.objectweb.asm.MethodVisitor;
|
||||||
|
import org.jetbrains.org.objectweb.asm.Type;
|
||||||
|
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
|
||||||
|
|
||||||
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
|
|
||||||
import static org.jetbrains.jet.codegen.AsmUtil.NO_FLAG_PACKAGE_PRIVATE;
|
import static org.jetbrains.jet.codegen.AsmUtil.NO_FLAG_PACKAGE_PRIVATE;
|
||||||
import static org.jetbrains.jet.codegen.AsmUtil.writeKotlinSyntheticClassAnnotation;
|
import static org.jetbrains.jet.codegen.AsmUtil.writeKotlinSyntheticClassAnnotation;
|
||||||
import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.OBJECT_TYPE;
|
import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.OBJECT_TYPE;
|
||||||
import static org.jetbrains.jet.lang.resolve.java.JvmAnnotationNames.KotlinSyntheticClass;
|
import static org.jetbrains.jet.lang.resolve.java.JvmAnnotationNames.KotlinSyntheticClass;
|
||||||
|
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
|
||||||
|
|
||||||
public class SamWrapperCodegen extends ParentCodegenAwareImpl {
|
public class SamWrapperCodegen extends ParentCodegenAwareImpl {
|
||||||
private static final String FUNCTION_FIELD_NAME = "function";
|
private static final String FUNCTION_FIELD_NAME = "function";
|
||||||
@@ -49,7 +49,7 @@ public class SamWrapperCodegen extends ParentCodegenAwareImpl {
|
|||||||
public SamWrapperCodegen(
|
public SamWrapperCodegen(
|
||||||
@NotNull GenerationState state,
|
@NotNull GenerationState state,
|
||||||
@NotNull JavaClassDescriptor samInterface,
|
@NotNull JavaClassDescriptor samInterface,
|
||||||
@Nullable MemberCodegen parentCodegen
|
@Nullable MemberCodegen<?> parentCodegen
|
||||||
) {
|
) {
|
||||||
super(state, parentCodegen);
|
super(state, parentCodegen);
|
||||||
this.samInterface = samInterface;
|
this.samInterface = samInterface;
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.OBJECT_TYPE;
|
|||||||
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
|
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
|
||||||
|
|
||||||
// SCRIPT: script code generator
|
// SCRIPT: script code generator
|
||||||
public class ScriptCodegen extends MemberCodegen {
|
public class ScriptCodegen extends MemberCodegen<JetScript> {
|
||||||
|
|
||||||
public static ScriptCodegen createScriptCodegen(
|
public static ScriptCodegen createScriptCodegen(
|
||||||
@NotNull JetScript declaration,
|
@NotNull JetScript declaration,
|
||||||
@@ -65,14 +65,10 @@ public class ScriptCodegen extends MemberCodegen {
|
|||||||
return new ScriptCodegen(declaration, state, scriptContext, state.getEarlierScriptsForReplInterpreter(), builder);
|
return new ScriptCodegen(declaration, state, scriptContext, state.getEarlierScriptsForReplInterpreter(), builder);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private final JetScript scriptDeclaration;
|
private final JetScript scriptDeclaration;
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private final ScriptContext context;
|
private final ScriptContext context;
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private final List<ScriptDescriptor> earlierScripts;
|
private final List<ScriptDescriptor> earlierScripts;
|
||||||
|
private final ScriptDescriptor scriptDescriptor;
|
||||||
|
|
||||||
private ScriptCodegen(
|
private ScriptCodegen(
|
||||||
@NotNull JetScript scriptDeclaration,
|
@NotNull JetScript scriptDeclaration,
|
||||||
@@ -81,33 +77,38 @@ public class ScriptCodegen extends MemberCodegen {
|
|||||||
@Nullable List<ScriptDescriptor> earlierScripts,
|
@Nullable List<ScriptDescriptor> earlierScripts,
|
||||||
@NotNull ClassBuilder builder
|
@NotNull ClassBuilder builder
|
||||||
) {
|
) {
|
||||||
super(state, null, context, builder);
|
super(state, null, context, scriptDeclaration, builder);
|
||||||
this.scriptDeclaration = scriptDeclaration;
|
this.scriptDeclaration = scriptDeclaration;
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.earlierScripts = earlierScripts == null ? Collections.<ScriptDescriptor>emptyList() : earlierScripts;
|
this.earlierScripts = earlierScripts == null ? Collections.<ScriptDescriptor>emptyList() : earlierScripts;
|
||||||
|
this.scriptDescriptor = context.getScriptDescriptor();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void generate() {
|
@Override
|
||||||
ScriptDescriptor scriptDescriptor = context.getScriptDescriptor();
|
protected void generateDeclaration() {
|
||||||
ClassDescriptor classDescriptorForScript = context.getContextDescriptor();
|
Type classType = bindingContext.get(ASM_TYPE, context.getContextDescriptor());
|
||||||
Type classType = bindingContext.get(ASM_TYPE, classDescriptorForScript);
|
|
||||||
assert classType != null;
|
assert classType != null;
|
||||||
|
|
||||||
ClassBuilder classBuilder = getBuilder();
|
v.defineClass(scriptDeclaration,
|
||||||
classBuilder.defineClass(scriptDeclaration,
|
V1_6,
|
||||||
V1_6,
|
ACC_PUBLIC,
|
||||||
ACC_PUBLIC,
|
classType.getInternalName(),
|
||||||
classType.getInternalName(),
|
null,
|
||||||
null,
|
"java/lang/Object",
|
||||||
"java/lang/Object",
|
new String[0]);
|
||||||
new String[0]);
|
}
|
||||||
|
|
||||||
genMembers(context, classBuilder);
|
@Override
|
||||||
genFieldsForParameters(scriptDescriptor, classBuilder);
|
protected void generateBody() {
|
||||||
genConstructor(scriptDescriptor, classDescriptorForScript, classBuilder,
|
genMembers(context, v);
|
||||||
|
genFieldsForParameters(scriptDescriptor, v);
|
||||||
|
genConstructor(scriptDescriptor, context.getContextDescriptor(), v,
|
||||||
context.intoFunction(scriptDescriptor.getScriptCodeDescriptor()));
|
context.intoFunction(scriptDescriptor.getScriptCodeDescriptor()));
|
||||||
|
}
|
||||||
|
|
||||||
classBuilder.done();
|
@Override
|
||||||
|
protected void generateKotlinAnnotation() {
|
||||||
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
private void genConstructor(
|
private void genConstructor(
|
||||||
@@ -154,7 +155,7 @@ public class ScriptCodegen extends MemberCodegen {
|
|||||||
frameMap.enter(parameter, argTypes[i + add]);
|
frameMap.enter(parameter, argTypes[i + add]);
|
||||||
}
|
}
|
||||||
|
|
||||||
generateInitializers(scriptDeclaration.getDeclarations(), new Function0<ExpressionCodegen>() {
|
generateInitializers(new Function0<ExpressionCodegen>() {
|
||||||
@Override
|
@Override
|
||||||
public ExpressionCodegen invoke() {
|
public ExpressionCodegen invoke() {
|
||||||
return new ExpressionCodegen(instructionAdapter, frameMap, Type.VOID_TYPE, context, state, ScriptCodegen.this);
|
return new ExpressionCodegen(instructionAdapter, frameMap, Type.VOID_TYPE, context, state, ScriptCodegen.this);
|
||||||
|
|||||||
@@ -23,9 +23,9 @@ import org.jetbrains.jet.codegen.state.GenerationState;
|
|||||||
import org.jetbrains.jet.lang.psi.JetClassOrObject;
|
import org.jetbrains.jet.lang.psi.JetClassOrObject;
|
||||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
||||||
|
|
||||||
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
|
|
||||||
import static org.jetbrains.jet.codegen.AsmUtil.writeKotlinSyntheticClassAnnotation;
|
import static org.jetbrains.jet.codegen.AsmUtil.writeKotlinSyntheticClassAnnotation;
|
||||||
import static org.jetbrains.jet.lang.resolve.java.JvmAnnotationNames.KotlinSyntheticClass;
|
import static org.jetbrains.jet.lang.resolve.java.JvmAnnotationNames.KotlinSyntheticClass;
|
||||||
|
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
|
||||||
|
|
||||||
public class TraitImplBodyCodegen extends ClassBodyCodegen {
|
public class TraitImplBodyCodegen extends ClassBodyCodegen {
|
||||||
|
|
||||||
@@ -34,7 +34,7 @@ public class TraitImplBodyCodegen extends ClassBodyCodegen {
|
|||||||
@NotNull ClassContext context,
|
@NotNull ClassContext context,
|
||||||
@NotNull ClassBuilder v,
|
@NotNull ClassBuilder v,
|
||||||
@NotNull GenerationState state,
|
@NotNull GenerationState state,
|
||||||
@Nullable MemberCodegen parentCodegen
|
@Nullable MemberCodegen<?> parentCodegen
|
||||||
) {
|
) {
|
||||||
super(aClass, context, v, state, parentCodegen);
|
super(aClass, context, v, state, parentCodegen);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -410,7 +410,7 @@ public class InlineCodegen implements ParentCodegenAware, CallGenerator {
|
|||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public MemberCodegen getParentCodegen() {
|
public MemberCodegen<?> getParentCodegen() {
|
||||||
return codegen.getParentCodegen();
|
return codegen.getParentCodegen();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
// SCRIPT: Script declaration
|
// SCRIPT: Script declaration
|
||||||
public class JetScript extends JetDeclarationImpl {
|
public class JetScript extends JetDeclarationImpl implements JetDeclarationContainer {
|
||||||
|
|
||||||
public JetScript(@NotNull ASTNode node) {
|
public JetScript(@NotNull ASTNode node) {
|
||||||
super(node);
|
super(node);
|
||||||
@@ -34,6 +34,7 @@ public class JetScript extends JetDeclarationImpl {
|
|||||||
return findNotNullChildByClass(JetBlockExpression.class);
|
return findNotNullChildByClass(JetBlockExpression.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
@NotNull
|
@NotNull
|
||||||
public List<JetDeclaration> getDeclarations() {
|
public List<JetDeclaration> getDeclarations() {
|
||||||
return PsiTreeUtil.getChildrenOfTypeAsList(getBlockExpression(), JetDeclaration.class);
|
return PsiTreeUtil.getChildrenOfTypeAsList(getBlockExpression(), JetDeclaration.class);
|
||||||
|
|||||||
Reference in New Issue
Block a user