codegen contexts work in terms of descriptors in oppose to asm.type
This commit is contained in:
@@ -145,17 +145,16 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
|
||||
generateBridge(name.getInternalName(), funDescriptor, fun, cv);
|
||||
captureThis = generateBody(funDescriptor, cv, (JetDeclarationWithBody) fun);
|
||||
|
||||
final Type enclosingType = !context.hasThisDescriptor()
|
||||
? null
|
||||
: typeMapper.mapType(context.getThisDescriptor().getDefaultType(), MapTypeMode.VALUE);
|
||||
if (enclosingType == null) {
|
||||
final ClassDescriptor enclosingClass = context.getEnclosingClass();
|
||||
if (enclosingClass == null) {
|
||||
captureThis = null;
|
||||
}
|
||||
|
||||
final Method constructor = generateConstructor(funClass, fun, funDescriptor);
|
||||
|
||||
if (captureThis != null) {
|
||||
cv.newField(fun, ACC_FINAL, "this$0", enclosingType.getDescriptor(), null, null);
|
||||
cv.newField(fun, ACC_FINAL, "this$0", typeMapper.mapType(enclosingClass.getDefaultType(), MapTypeMode.IMPL).getDescriptor(),
|
||||
null, null);
|
||||
}
|
||||
|
||||
if (isConst()) {
|
||||
@@ -207,12 +206,12 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
|
||||
}
|
||||
}
|
||||
|
||||
private Type generateBody(FunctionDescriptor funDescriptor, ClassBuilder cv, JetDeclarationWithBody body) {
|
||||
private ClassDescriptor generateBody(FunctionDescriptor funDescriptor, ClassBuilder cv, JetDeclarationWithBody body) {
|
||||
ClassDescriptor function =
|
||||
closureAnnotator.classDescriptorForFunctionDescriptor(funDescriptor);
|
||||
|
||||
final CodegenContexts.ClosureContext closureContext = context.intoClosure(
|
||||
funDescriptor, function, name, this, typeMapper);
|
||||
funDescriptor, function, this, typeMapper);
|
||||
FunctionCodegen fc = new FunctionCodegen(closureContext, cv, state);
|
||||
JvmMethodSignature jvmMethodSignature = invokeSignature(funDescriptor);
|
||||
fc.generateMethod(body, jvmMethodSignature, false, null, funDescriptor);
|
||||
@@ -315,7 +314,7 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
|
||||
args.add(new Pair<String, Type>("this$0", type));
|
||||
}
|
||||
if (captureReceiver != null) {
|
||||
args.add(new Pair<String, Type>("receiver$0", captureReceiver));
|
||||
args.add(new Pair<String, Type>("receiver$0", typeMapper.mapType(captureReceiver.getDefaultType(), MapTypeMode.VALUE)));
|
||||
}
|
||||
|
||||
boolean putFieldForMyself = false;
|
||||
|
||||
@@ -22,7 +22,6 @@ import org.jetbrains.asm4.Type;
|
||||
import org.jetbrains.asm4.commons.InstructionAdapter;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
||||
import org.jetbrains.jet.lang.resolve.java.JvmClassName;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
@@ -43,33 +42,44 @@ public abstract class CodegenContext {
|
||||
@Nullable
|
||||
private final CodegenContext parentContext;
|
||||
public final ObjectOrClosureCodegen closure;
|
||||
private final boolean hasThis;
|
||||
private final ClassDescriptor thisDescriptor;
|
||||
|
||||
HashMap<DeclarationDescriptor, DeclarationDescriptor> accessors;
|
||||
|
||||
protected StackValue outerExpression;
|
||||
|
||||
protected Type outerWasUsed;
|
||||
protected ClassDescriptor outerWasUsed;
|
||||
|
||||
public CodegenContext(
|
||||
JetTypeMapper typeMapper,
|
||||
@NotNull DeclarationDescriptor contextDescriptor,
|
||||
OwnerKind contextKind,
|
||||
@Nullable CodegenContext parentContext,
|
||||
@Nullable ObjectOrClosureCodegen closureCodegen,
|
||||
boolean hasThis
|
||||
ClassDescriptor thisDescriptor
|
||||
) {
|
||||
this.contextDescriptor = contextDescriptor;
|
||||
this.contextKind = contextKind;
|
||||
this.parentContext = parentContext;
|
||||
closure = closureCodegen;
|
||||
this.hasThis = hasThis;
|
||||
this.thisDescriptor = thisDescriptor;
|
||||
|
||||
final ClassDescriptor enclosingClass = getEnclosingClass();
|
||||
//outerExpression = enclosingClass != null && hasThisDescriptor() && typeMapper != null
|
||||
// ? StackValue.field(typeMapper.mapType(enclosingClass.getDefaultType(),MapTypeMode.VALUE), typeMapper.getJvmClassName(thisDescriptor), "this$0", false)
|
||||
// : null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected abstract ClassDescriptor getThisDescriptor();
|
||||
protected final ClassDescriptor getThisDescriptor() {
|
||||
if (thisDescriptor == null) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
return thisDescriptor;
|
||||
}
|
||||
|
||||
protected final boolean hasThisDescriptor() {
|
||||
return hasThis;
|
||||
return thisDescriptor != null;
|
||||
}
|
||||
|
||||
public DeclarationDescriptor getClassOrNamespaceDescriptor() {
|
||||
@@ -95,7 +105,7 @@ public abstract class CodegenContext {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
outerWasUsed = outerExpression.type;
|
||||
outerWasUsed = getEnclosingClass();
|
||||
return prefix != null ? StackValue.composed(prefix, outerExpression) : outerExpression;
|
||||
}
|
||||
|
||||
@@ -108,16 +118,16 @@ public abstract class CodegenContext {
|
||||
return contextKind;
|
||||
}
|
||||
|
||||
public CodegenContext intoNamespace(NamespaceDescriptor descriptor) {
|
||||
return new CodegenContexts.NamespaceContext(descriptor, this, null);
|
||||
public CodegenContext intoNamespace(NamespaceDescriptor descriptor, JetTypeMapper typeMapper) {
|
||||
return new CodegenContexts.NamespaceContext(typeMapper, descriptor, this, null);
|
||||
}
|
||||
|
||||
public CodegenContext intoNamespacePart(String delegateTo, NamespaceDescriptor descriptor) {
|
||||
return new CodegenContexts.NamespaceContext(descriptor, this, new OwnerKind.StaticDelegateKind(delegateTo));
|
||||
public CodegenContext intoNamespacePart(String delegateTo, NamespaceDescriptor descriptor, JetTypeMapper typeMapper) {
|
||||
return new CodegenContexts.NamespaceContext(typeMapper, descriptor, this, new OwnerKind.StaticDelegateKind(delegateTo));
|
||||
}
|
||||
|
||||
public CodegenContext intoClass(ClassDescriptor descriptor, OwnerKind kind, JetTypeMapper typeMapper) {
|
||||
return new CodegenContexts.ClassContext(descriptor, kind, this, typeMapper);
|
||||
return new CodegenContexts.ClassContext(typeMapper, descriptor, kind, this);
|
||||
}
|
||||
|
||||
public CodegenContext intoAnonymousClass(
|
||||
@@ -126,11 +136,11 @@ public abstract class CodegenContext {
|
||||
OwnerKind kind,
|
||||
JetTypeMapper typeMapper
|
||||
) {
|
||||
return new CodegenContexts.AnonymousClassContext(descriptor, kind, this, closure, typeMapper);
|
||||
return new CodegenContexts.AnonymousClassContext(typeMapper, descriptor, kind, this, closure);
|
||||
}
|
||||
|
||||
public CodegenContexts.MethodContext intoFunction(FunctionDescriptor descriptor) {
|
||||
return new CodegenContexts.MethodContext(descriptor, getContextKind(), this);
|
||||
public CodegenContexts.MethodContext intoFunction(FunctionDescriptor descriptor, JetTypeMapper typeMapper) {
|
||||
return new CodegenContexts.MethodContext(typeMapper, descriptor, getContextKind(), this);
|
||||
}
|
||||
|
||||
public CodegenContexts.ConstructorContext intoConstructor(ConstructorDescriptor descriptor, JetTypeMapper typeMapper) {
|
||||
@@ -139,21 +149,20 @@ public abstract class CodegenContext {
|
||||
.initialize(Collections.<TypeParameterDescriptor>emptyList(), Collections.<ValueParameterDescriptor>emptyList(),
|
||||
Visibilities.PUBLIC);
|
||||
}
|
||||
return new CodegenContexts.ConstructorContext(descriptor, getContextKind(), this, typeMapper);
|
||||
return new CodegenContexts.ConstructorContext(typeMapper, descriptor, getContextKind(), this);
|
||||
}
|
||||
|
||||
public CodegenContext intoScript(@NotNull ScriptDescriptor script, @NotNull ClassDescriptor classDescriptor) {
|
||||
return new CodegenContexts.ScriptContext(script, classDescriptor, OwnerKind.IMPLEMENTATION, this, closure);
|
||||
public CodegenContext intoScript(@NotNull ScriptDescriptor script, @NotNull ClassDescriptor classDescriptor, JetTypeMapper typeMapper) {
|
||||
return new CodegenContexts.ScriptContext(typeMapper, script, classDescriptor, OwnerKind.IMPLEMENTATION, this, closure);
|
||||
}
|
||||
|
||||
public CodegenContexts.ClosureContext intoClosure(
|
||||
FunctionDescriptor funDescriptor,
|
||||
ClassDescriptor classDescriptor,
|
||||
JvmClassName internalClassName,
|
||||
ClosureCodegen closureCodegen,
|
||||
JetTypeMapper typeMapper
|
||||
) {
|
||||
return new CodegenContexts.ClosureContext(funDescriptor, classDescriptor, this, closureCodegen, internalClassName, typeMapper);
|
||||
return new CodegenContexts.ClosureContext(typeMapper, funDescriptor, classDescriptor, this, closureCodegen);
|
||||
}
|
||||
|
||||
public FrameMap prepareFrame(JetTypeMapper mapper) {
|
||||
@@ -192,13 +201,13 @@ public abstract class CodegenContext {
|
||||
return parentContext != null ? parentContext.lookupInContext(d, v, result) : null;
|
||||
}
|
||||
|
||||
public Type enclosingClassType(JetTypeMapper typeMapper) {
|
||||
public ClassDescriptor getEnclosingClass() {
|
||||
CodegenContext cur = getParentContext();
|
||||
while (cur != null && !(cur.getContextDescriptor() instanceof ClassDescriptor)) {
|
||||
cur = cur.getParentContext();
|
||||
}
|
||||
|
||||
return cur == null ? null : typeMapper.mapType(((ClassDescriptor) cur.getContextDescriptor()).getDefaultType(), MapTypeMode.IMPL);
|
||||
return cur == null ? null : (ClassDescriptor) cur.getContextDescriptor();
|
||||
}
|
||||
|
||||
DeclarationDescriptor getAccessor(DeclarationDescriptor descriptor) {
|
||||
@@ -240,4 +249,14 @@ public abstract class CodegenContext {
|
||||
this.accessors.putAll(accessors);
|
||||
}
|
||||
}
|
||||
|
||||
protected void initOuterExpression(JetTypeMapper typeMapper, ClassDescriptor classDescriptor) {
|
||||
final ClassDescriptor enclosingClass = getEnclosingClass();
|
||||
outerExpression = enclosingClass != null
|
||||
? StackValue
|
||||
.field(typeMapper.mapType(enclosingClass.getDefaultType(), MapTypeMode.VALUE), typeMapper.getJvmClassName(
|
||||
classDescriptor), "this$0",
|
||||
false)
|
||||
: null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,17 +18,16 @@ package org.jetbrains.jet.codegen;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.asm4.Type;
|
||||
import org.jetbrains.asm4.commons.InstructionAdapter;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
||||
import org.jetbrains.jet.lang.resolve.java.JvmClassName;
|
||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
import org.jetbrains.jet.lang.types.TypeSubstitutor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author alex.tkachman
|
||||
* @author Stepan Koltsov
|
||||
*/
|
||||
public class CodegenContexts {
|
||||
@@ -76,13 +75,7 @@ public class CodegenContexts {
|
||||
}
|
||||
|
||||
public static final CodegenContext STATIC =
|
||||
new CodegenContext(new FakeDescriptorForStaticContext(), OwnerKind.NAMESPACE, null, null, false) {
|
||||
@NotNull
|
||||
@Override
|
||||
protected ClassDescriptor getThisDescriptor() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
new CodegenContext(null, new FakeDescriptorForStaticContext(), OwnerKind.NAMESPACE, null, null, null) {
|
||||
@Override
|
||||
public boolean isStatic() {
|
||||
return true;
|
||||
@@ -99,13 +92,14 @@ public class CodegenContexts {
|
||||
final CallableDescriptor receiverDescriptor;
|
||||
|
||||
public ReceiverContext(
|
||||
JetTypeMapper typeMapper,
|
||||
CallableDescriptor contextDescriptor,
|
||||
OwnerKind contextKind,
|
||||
CodegenContext parentContext,
|
||||
@Nullable ObjectOrClosureCodegen closureCodegen,
|
||||
boolean hasThis
|
||||
ClassDescriptor thisDescriptor
|
||||
) {
|
||||
super(contextDescriptor, contextKind, parentContext, closureCodegen, hasThis);
|
||||
super(typeMapper, contextDescriptor, contextKind, parentContext, closureCodegen, thisDescriptor);
|
||||
receiverDescriptor = contextDescriptor.getReceiverParameter().exists() ? contextDescriptor : null;
|
||||
}
|
||||
|
||||
@@ -117,17 +111,16 @@ public class CodegenContexts {
|
||||
|
||||
public static class MethodContext extends ReceiverContext {
|
||||
|
||||
public MethodContext(@NotNull FunctionDescriptor contextType, OwnerKind contextKind, CodegenContext parentContext) {
|
||||
super(contextType instanceof PropertyAccessorDescriptor
|
||||
? ((PropertyAccessorDescriptor) contextType).getCorrespondingProperty()
|
||||
: contextType, contextKind, parentContext, null, parentContext.hasThisDescriptor());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected ClassDescriptor getThisDescriptor() {
|
||||
//noinspection ConstantConditions
|
||||
return getParentContext().getThisDescriptor();
|
||||
public MethodContext(
|
||||
JetTypeMapper typeMapper,
|
||||
@NotNull FunctionDescriptor contextType,
|
||||
OwnerKind contextKind,
|
||||
CodegenContext parentContext
|
||||
) {
|
||||
super(typeMapper, contextType instanceof PropertyAccessorDescriptor
|
||||
? ((PropertyAccessorDescriptor) contextType).getCorrespondingProperty()
|
||||
: contextType, contextKind, parentContext, null,
|
||||
parentContext.hasThisDescriptor() ? parentContext.getThisDescriptor() : null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -136,12 +129,6 @@ public class CodegenContexts {
|
||||
return getParentContext().lookupInContext(d, v, result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type enclosingClassType(JetTypeMapper typeMapper) {
|
||||
//noinspection ConstantConditions
|
||||
return getParentContext().enclosingClassType(typeMapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isStatic() {
|
||||
//noinspection ConstantConditions
|
||||
@@ -162,17 +149,15 @@ public class CodegenContexts {
|
||||
|
||||
public static class ConstructorContext extends MethodContext {
|
||||
public ConstructorContext(
|
||||
JetTypeMapper typeMapper,
|
||||
ConstructorDescriptor contextDescriptor,
|
||||
OwnerKind kind,
|
||||
CodegenContext parent,
|
||||
JetTypeMapper typeMapper
|
||||
CodegenContext parent
|
||||
) {
|
||||
super(contextDescriptor, kind, parent);
|
||||
super(typeMapper, contextDescriptor, kind, parent);
|
||||
|
||||
final Type type = enclosingClassType(typeMapper);
|
||||
outerExpression = type != null
|
||||
? local1
|
||||
: null;
|
||||
final ClassDescriptor type = getEnclosingClass();
|
||||
outerExpression = type != null ? local1 : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -187,31 +172,22 @@ public class CodegenContexts {
|
||||
}
|
||||
|
||||
public static class ScriptContext extends CodegenContext {
|
||||
|
||||
@NotNull
|
||||
private final ClassDescriptor classDescriptor;
|
||||
@NotNull
|
||||
private final ScriptDescriptor scriptDescriptor;
|
||||
|
||||
public ScriptContext(
|
||||
JetTypeMapper typeMapper,
|
||||
@NotNull ScriptDescriptor scriptDescriptor,
|
||||
@NotNull ClassDescriptor contextDescriptor,
|
||||
@NotNull OwnerKind contextKind,
|
||||
@Nullable CodegenContext parentContext,
|
||||
@Nullable ObjectOrClosureCodegen closureCodegen
|
||||
) {
|
||||
super(contextDescriptor, contextKind, parentContext, closureCodegen, true);
|
||||
super(typeMapper, contextDescriptor, contextKind, parentContext, closureCodegen, contextDescriptor);
|
||||
|
||||
this.classDescriptor = contextDescriptor;
|
||||
this.scriptDescriptor = scriptDescriptor;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected ClassDescriptor getThisDescriptor() {
|
||||
return classDescriptor;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ScriptDescriptor getScriptDescriptor() {
|
||||
return scriptDescriptor;
|
||||
@@ -225,23 +201,13 @@ public class CodegenContexts {
|
||||
|
||||
public static class ClassContext extends CodegenContext {
|
||||
public ClassContext(
|
||||
JetTypeMapper typeMapper,
|
||||
ClassDescriptor contextDescriptor,
|
||||
OwnerKind contextKind,
|
||||
CodegenContext parentContext,
|
||||
JetTypeMapper typeMapper
|
||||
CodegenContext parentContext
|
||||
) {
|
||||
super(contextDescriptor, contextKind, parentContext, null, true);
|
||||
|
||||
final Type type = enclosingClassType(typeMapper);
|
||||
outerExpression = type != null
|
||||
? StackValue.field(type, typeMapper.getJvmClassName(contextDescriptor), "this$0", false)
|
||||
: null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected ClassDescriptor getThisDescriptor() {
|
||||
return (ClassDescriptor) getContextDescriptor();
|
||||
super(typeMapper, contextDescriptor, contextKind, parentContext, null, contextDescriptor);
|
||||
initOuterExpression(typeMapper, contextDescriptor);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -252,25 +218,14 @@ public class CodegenContexts {
|
||||
|
||||
public static class AnonymousClassContext extends CodegenContext {
|
||||
public AnonymousClassContext(
|
||||
JetTypeMapper typeMapper,
|
||||
ClassDescriptor contextDescriptor,
|
||||
OwnerKind contextKind,
|
||||
CodegenContext parentContext,
|
||||
@NotNull ObjectOrClosureCodegen closure,
|
||||
JetTypeMapper typeMapper
|
||||
@NotNull ObjectOrClosureCodegen closure
|
||||
) {
|
||||
super(contextDescriptor, contextKind, parentContext, closure, true);
|
||||
|
||||
final Type type = enclosingClassType(typeMapper);
|
||||
Type owner = closure.state.getInjector().getJetTypeMapper().mapType(contextDescriptor.getDefaultType(), MapTypeMode.IMPL);
|
||||
outerExpression = type != null
|
||||
? StackValue.field(type, JvmClassName.byType(owner), "this$0", false)
|
||||
: null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected ClassDescriptor getThisDescriptor() {
|
||||
return (ClassDescriptor) getContextDescriptor();
|
||||
super(typeMapper, contextDescriptor, contextKind, parentContext, closure, contextDescriptor);
|
||||
initOuterExpression(typeMapper, contextDescriptor);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -288,26 +243,16 @@ public class CodegenContexts {
|
||||
private final ClassDescriptor classDescriptor;
|
||||
|
||||
public ClosureContext(
|
||||
JetTypeMapper typeMapper,
|
||||
FunctionDescriptor contextDescriptor,
|
||||
ClassDescriptor classDescriptor,
|
||||
CodegenContext parentContext,
|
||||
@NotNull ObjectOrClosureCodegen closureCodegen,
|
||||
JvmClassName internalClassName,
|
||||
JetTypeMapper typeMapper
|
||||
@NotNull ObjectOrClosureCodegen closureCodegen
|
||||
) {
|
||||
super(contextDescriptor, OwnerKind.IMPLEMENTATION, parentContext, closureCodegen, true);
|
||||
super(typeMapper, contextDescriptor, OwnerKind.IMPLEMENTATION, parentContext, closureCodegen, classDescriptor);
|
||||
this.classDescriptor = classDescriptor;
|
||||
|
||||
final Type type = enclosingClassType(typeMapper);
|
||||
outerExpression = type != null
|
||||
? StackValue.field(type, internalClassName, "this$0", false)
|
||||
: null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected ClassDescriptor getThisDescriptor() {
|
||||
return classDescriptor;
|
||||
initOuterExpression(typeMapper, classDescriptor);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -328,14 +273,8 @@ public class CodegenContexts {
|
||||
}
|
||||
|
||||
public static class NamespaceContext extends CodegenContext {
|
||||
public NamespaceContext(NamespaceDescriptor contextDescriptor, CodegenContext parent, OwnerKind kind) {
|
||||
super(contextDescriptor, kind != null ? kind : OwnerKind.NAMESPACE, parent, null, false);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected ClassDescriptor getThisDescriptor() {
|
||||
throw new UnsupportedOperationException();
|
||||
public NamespaceContext(JetTypeMapper typeMapper, NamespaceDescriptor contextDescriptor, CodegenContext parent, OwnerKind kind) {
|
||||
super(typeMapper, contextDescriptor, kind != null ? kind : OwnerKind.NAMESPACE, parent, null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -853,10 +853,10 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
v.load(0, TYPE_OBJECT);
|
||||
}
|
||||
|
||||
if (closure.isCaptureReceiver() != null) {
|
||||
if (closure.isCaptureReceiver()) {
|
||||
k++;
|
||||
v.load(context.getContextDescriptor().getContainingDeclaration() instanceof NamespaceDescriptor ? 0 : 1,
|
||||
closure.isCaptureReceiver());
|
||||
typeMapper.mapType(closure.getCaptureReceiver().getDefaultType(), MapTypeMode.IMPL));
|
||||
}
|
||||
|
||||
for (int i = 0; i < closure.getArgs().size(); i++) {
|
||||
@@ -883,8 +883,9 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
}
|
||||
|
||||
if (closureCodegen.captureReceiver != null) {
|
||||
v.load(context.isStatic() ? 0 : 1, closureCodegen.captureReceiver);
|
||||
consArgTypes.add(closureCodegen.captureReceiver);
|
||||
final Type asmType = typeMapper.mapType(closureCodegen.captureReceiver.getDefaultType(), MapTypeMode.IMPL);
|
||||
v.load(context.isStatic() ? 0 : 1, asmType);
|
||||
consArgTypes.add(asmType);
|
||||
}
|
||||
|
||||
for (Map.Entry<DeclarationDescriptor, EnclosedValueDescriptor> entry : closureCodegen.closure.entrySet()) {
|
||||
|
||||
@@ -74,7 +74,7 @@ public class FunctionCodegen {
|
||||
@Nullable String propertyTypeSignature, FunctionDescriptor functionDescriptor
|
||||
) {
|
||||
|
||||
CodegenContexts.MethodContext funContext = owner.intoFunction(functionDescriptor);
|
||||
CodegenContexts.MethodContext funContext = owner.intoFunction(functionDescriptor, state.getInjector().getJetTypeMapper());
|
||||
|
||||
final JetExpression bodyExpression = f.getBodyExpression();
|
||||
generatedMethod(bodyExpression, jvmMethod, needJetAnnotations, propertyTypeSignature, funContext, functionDescriptor, f);
|
||||
|
||||
+20
-5
@@ -19,8 +19,9 @@
|
||||
*/
|
||||
package org.jetbrains.jet.codegen;
|
||||
|
||||
import org.jetbrains.asm4.Type;
|
||||
import org.jetbrains.asm4.commons.Method;
|
||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor;
|
||||
import org.jetbrains.jet.lang.resolve.java.JvmClassName;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -29,11 +30,17 @@ import java.util.List;
|
||||
public class GeneratedAnonymousClassDescriptor {
|
||||
private final JvmClassName classname;
|
||||
private final Method constructor;
|
||||
private final Type captureThis;
|
||||
private final Type captureReceiver;
|
||||
|
||||
private final ClassDescriptor captureThis;
|
||||
private final ClassifierDescriptor captureReceiver;
|
||||
private final List<StackValue> args = new ArrayList<StackValue>();
|
||||
|
||||
public GeneratedAnonymousClassDescriptor(JvmClassName classname, Method constructor, Type captureThis, Type captureReceiver) {
|
||||
public GeneratedAnonymousClassDescriptor(
|
||||
JvmClassName classname,
|
||||
Method constructor,
|
||||
ClassDescriptor captureThis,
|
||||
ClassifierDescriptor captureReceiver
|
||||
) {
|
||||
this.classname = classname;
|
||||
this.constructor = constructor;
|
||||
this.captureThis = captureThis;
|
||||
@@ -60,7 +67,15 @@ public class GeneratedAnonymousClassDescriptor {
|
||||
return captureThis != null;
|
||||
}
|
||||
|
||||
public Type isCaptureReceiver() {
|
||||
public boolean isCaptureReceiver() {
|
||||
return captureReceiver != null;
|
||||
}
|
||||
|
||||
public ClassDescriptor getCaptureThis() {
|
||||
return captureThis;
|
||||
}
|
||||
|
||||
public ClassifierDescriptor getCaptureReceiver() {
|
||||
return captureReceiver;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -702,10 +702,11 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
int k = hasOuterThis ? 2 : 1;
|
||||
if (closure.captureReceiver != null) {
|
||||
iv.load(0, JetTypeMapper.TYPE_OBJECT);
|
||||
iv.load(1, closure.captureReceiver);
|
||||
final Type asmType = typeMapper.mapType(closure.captureReceiver.getDefaultType(), MapTypeMode.IMPL);
|
||||
iv.load(1, asmType);
|
||||
iv.putfield(typeMapper.mapType(descriptor.getDefaultType(), MapTypeMode.VALUE).getInternalName(), "receiver$0",
|
||||
closure.captureReceiver.getDescriptor());
|
||||
k += closure.captureReceiver.getSize();
|
||||
asmType.getDescriptor());
|
||||
k += asmType.getSize();
|
||||
}
|
||||
|
||||
for (DeclarationDescriptor varDescr : closure.closure.keySet()) {
|
||||
@@ -872,7 +873,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
}
|
||||
|
||||
if (closure.captureReceiver != null) {
|
||||
consArgTypes.add(insert++, new JvmMethodParameterSignature(closure.captureReceiver, "", JvmMethodParameterKind.RECEIVER));
|
||||
final Type asmType = typeMapper.mapType(closure.captureReceiver.getDefaultType(), MapTypeMode.IMPL);
|
||||
consArgTypes.add(insert++, new JvmMethodParameterSignature(asmType, "", JvmMethodParameterKind.RECEIVER));
|
||||
}
|
||||
|
||||
for (DeclarationDescriptor descriptor : closure.closure.keySet()) {
|
||||
|
||||
@@ -122,19 +122,19 @@ public class NamespaceCodegen {
|
||||
NamespaceDescriptor descriptor = state.getBindingContext().get(BindingContext.FILE_TO_NAMESPACE, file);
|
||||
for (JetDeclaration declaration : file.getDeclarations()) {
|
||||
if (declaration instanceof JetProperty) {
|
||||
final CodegenContext context = CodegenContexts.STATIC.intoNamespace(descriptor);
|
||||
final CodegenContext context = CodegenContexts.STATIC.intoNamespace(descriptor, state.getInjector().getJetTypeMapper());
|
||||
state.getInjector().getMemberCodegen().generateFunctionOrProperty(
|
||||
(JetTypeParameterListOwner) declaration, context, v.getClassBuilder());
|
||||
}
|
||||
else if (declaration instanceof JetNamedFunction) {
|
||||
if (!multiFile) {
|
||||
final CodegenContext context = CodegenContexts.STATIC.intoNamespace(descriptor);
|
||||
final CodegenContext context = CodegenContexts.STATIC.intoNamespace(descriptor, state.getInjector().getJetTypeMapper());
|
||||
state.getInjector().getMemberCodegen().generateFunctionOrProperty(
|
||||
(JetTypeParameterListOwner) declaration, context, v.getClassBuilder());
|
||||
}
|
||||
}
|
||||
else if (declaration instanceof JetClassOrObject) {
|
||||
final CodegenContext context = CodegenContexts.STATIC.intoNamespace(descriptor);
|
||||
final CodegenContext context = CodegenContexts.STATIC.intoNamespace(descriptor, state.getInjector().getJetTypeMapper());
|
||||
state.getInjector().getClassCodegen().generate(context, (JetClassOrObject) declaration);
|
||||
}
|
||||
else if (declaration instanceof JetScript) {
|
||||
@@ -169,12 +169,14 @@ public class NamespaceCodegen {
|
||||
for (JetDeclaration declaration : file.getDeclarations()) {
|
||||
if (declaration instanceof JetNamedFunction) {
|
||||
{
|
||||
final CodegenContext context = CodegenContexts.STATIC.intoNamespace(descriptor);
|
||||
final CodegenContext context =
|
||||
CodegenContexts.STATIC.intoNamespace(descriptor, state.getInjector().getJetTypeMapper());
|
||||
state.getInjector().getMemberCodegen()
|
||||
.generateFunctionOrProperty((JetTypeParameterListOwner) declaration, context, builder);
|
||||
}
|
||||
{
|
||||
final CodegenContext context = CodegenContexts.STATIC.intoNamespacePart(className, descriptor);
|
||||
final CodegenContext context =
|
||||
CodegenContexts.STATIC.intoNamespacePart(className, descriptor, state.getInjector().getJetTypeMapper());
|
||||
state.getInjector().getMemberCodegen()
|
||||
.generateFunctionOrProperty((JetTypeParameterListOwner) declaration, context, v.getClassBuilder());
|
||||
}
|
||||
|
||||
@@ -32,8 +32,8 @@ import java.util.Map;
|
||||
* @author alex.tkachman
|
||||
*/
|
||||
public class ObjectOrClosureCodegen {
|
||||
protected Type captureThis;
|
||||
protected Type captureReceiver;
|
||||
protected ClassDescriptor captureThis;
|
||||
protected ClassifierDescriptor captureReceiver;
|
||||
|
||||
public final GenerationState state;
|
||||
private final ExpressionCodegen exprContext;
|
||||
@@ -129,7 +129,8 @@ public class ObjectOrClosureCodegen {
|
||||
closure.put(d, answer);
|
||||
|
||||
assert captureReceiver == null;
|
||||
captureReceiver = type;
|
||||
captureReceiver =
|
||||
fcontext.getReceiverDescriptor().getReceiverParameter().getType().getConstructor().getDeclarationDescriptor();
|
||||
|
||||
return innerValue;
|
||||
}
|
||||
|
||||
@@ -100,7 +100,8 @@ public class ScriptCodegen {
|
||||
ClassDescriptor classDescriptorForScript = closureAnnotator.classDescriptorForScriptDescriptor(scriptDescriptor);
|
||||
|
||||
CodegenContexts.ScriptContext context =
|
||||
(CodegenContexts.ScriptContext) CodegenContexts.STATIC.intoScript(scriptDescriptor, classDescriptorForScript);
|
||||
(CodegenContexts.ScriptContext) CodegenContexts.STATIC
|
||||
.intoScript(scriptDescriptor, classDescriptorForScript, state.getInjector().getJetTypeMapper());
|
||||
|
||||
JvmClassName className = closureAnnotator.classNameForClassDescriptor(classDescriptorForScript);
|
||||
|
||||
@@ -116,7 +117,8 @@ public class ScriptCodegen {
|
||||
genMembers(scriptDeclaration, context, classBuilder);
|
||||
genFieldsForParameters(scriptDescriptor, classBuilder);
|
||||
genConstructor(scriptDeclaration, scriptDescriptor, classDescriptorForScript, classBuilder,
|
||||
context.intoFunction(scriptDescriptor.getScriptCodeDescriptor()), earlierScripts);
|
||||
context.intoFunction(scriptDescriptor.getScriptCodeDescriptor(), state.getInjector().getJetTypeMapper()),
|
||||
earlierScripts);
|
||||
|
||||
classBuilder.done();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user