@NotNull CodegenContext.getThisDescriptor()

This commit is contained in:
Alex Tkachman
2012-08-23 20:05:11 +03:00
parent 05c7f80a14
commit b2d9e02b2c
4 changed files with 53 additions and 35 deletions
@@ -144,10 +144,10 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
generateBridge(name.getInternalName(), funDescriptor, fun, cv); generateBridge(name.getInternalName(), funDescriptor, fun, cv);
captureThis = generateBody(funDescriptor, cv, (JetDeclarationWithBody) fun); captureThis = generateBody(funDescriptor, cv, (JetDeclarationWithBody) fun);
ClassDescriptor thisDescriptor = context.getThisDescriptor();
final Type enclosingType = thisDescriptor == null final Type enclosingType = !context.hasThisDescriptor()
? null ? null
: typeMapper.mapType(thisDescriptor.getDefaultType(), MapTypeMode.VALUE); : typeMapper.mapType(context.getThisDescriptor().getDefaultType(), MapTypeMode.VALUE);
if (enclosingType == null) { if (enclosingType == null) {
captureThis = null; captureThis = null;
} }
@@ -43,6 +43,7 @@ public abstract class CodegenContext {
@Nullable @Nullable
private final CodegenContext parentContext; private final CodegenContext parentContext;
public final ObjectOrClosureCodegen closure; public final ObjectOrClosureCodegen closure;
private final boolean hasThis;
HashMap<DeclarationDescriptor, DeclarationDescriptor> accessors; HashMap<DeclarationDescriptor, DeclarationDescriptor> accessors;
@@ -54,16 +55,23 @@ public abstract class CodegenContext {
@NotNull DeclarationDescriptor contextDescriptor, @NotNull DeclarationDescriptor contextDescriptor,
OwnerKind contextKind, OwnerKind contextKind,
@Nullable CodegenContext parentContext, @Nullable CodegenContext parentContext,
@Nullable ObjectOrClosureCodegen closureCodegen @Nullable ObjectOrClosureCodegen closureCodegen,
boolean hasThis
) { ) {
this.contextDescriptor = contextDescriptor; this.contextDescriptor = contextDescriptor;
this.contextKind = contextKind; this.contextKind = contextKind;
this.parentContext = parentContext; this.parentContext = parentContext;
closure = closureCodegen; closure = closureCodegen;
this.hasThis = hasThis;
} }
@NotNull
protected abstract ClassDescriptor getThisDescriptor(); protected abstract ClassDescriptor getThisDescriptor();
protected final boolean hasThisDescriptor() {
return hasThis;
}
public DeclarationDescriptor getClassOrNamespaceDescriptor() { public DeclarationDescriptor getClassOrNamespaceDescriptor() {
CodegenContext c = this; CodegenContext c = this;
while (true) { while (true) {
@@ -219,7 +227,7 @@ public abstract class CodegenContext {
public StackValue getReceiverExpression(JetTypeMapper typeMapper) { public StackValue getReceiverExpression(JetTypeMapper typeMapper) {
assert getReceiverDescriptor() != null; assert getReceiverDescriptor() != null;
Type asmType = typeMapper.mapType(getReceiverDescriptor().getReceiverParameter().getType(), MapTypeMode.VALUE); Type asmType = typeMapper.mapType(getReceiverDescriptor().getReceiverParameter().getType(), MapTypeMode.VALUE);
return getThisDescriptor() != null ? StackValue.local(1, asmType) : StackValue.local(0, asmType); return hasThisDescriptor() ? StackValue.local(1, asmType) : StackValue.local(0, asmType);
} }
public abstract boolean isStatic(); public abstract boolean isStatic();
@@ -75,22 +75,24 @@ public class CodegenContexts {
} }
} }
public static final CodegenContext STATIC = new CodegenContext(new FakeDescriptorForStaticContext(), OwnerKind.NAMESPACE, null, null) { public static final CodegenContext STATIC =
@Override new CodegenContext(new FakeDescriptorForStaticContext(), OwnerKind.NAMESPACE, null, null, false) {
protected ClassDescriptor getThisDescriptor() { @NotNull
return null; @Override
} protected ClassDescriptor getThisDescriptor() {
throw new UnsupportedOperationException();
}
@Override @Override
public boolean isStatic() { public boolean isStatic() {
return true; return true;
} }
@Override @Override
public String toString() { public String toString() {
return "ROOT"; return "ROOT";
} }
}; };
private static final StackValue local1 = StackValue.local(1, JetTypeMapper.TYPE_OBJECT); private static final StackValue local1 = StackValue.local(1, JetTypeMapper.TYPE_OBJECT);
public abstract static class ReceiverContext extends CodegenContext { public abstract static class ReceiverContext extends CodegenContext {
@@ -100,9 +102,10 @@ public class CodegenContexts {
CallableDescriptor contextDescriptor, CallableDescriptor contextDescriptor,
OwnerKind contextKind, OwnerKind contextKind,
CodegenContext parentContext, CodegenContext parentContext,
@Nullable ObjectOrClosureCodegen closureCodegen @Nullable ObjectOrClosureCodegen closureCodegen,
boolean hasThis
) { ) {
super(contextDescriptor, contextKind, parentContext, closureCodegen); super(contextDescriptor, contextKind, parentContext, closureCodegen, hasThis);
receiverDescriptor = contextDescriptor.getReceiverParameter().exists() ? contextDescriptor : null; receiverDescriptor = contextDescriptor.getReceiverParameter().exists() ? contextDescriptor : null;
} }
@@ -117,9 +120,10 @@ public class CodegenContexts {
public MethodContext(@NotNull FunctionDescriptor contextType, OwnerKind contextKind, CodegenContext parentContext) { public MethodContext(@NotNull FunctionDescriptor contextType, OwnerKind contextKind, CodegenContext parentContext) {
super(contextType instanceof PropertyAccessorDescriptor super(contextType instanceof PropertyAccessorDescriptor
? ((PropertyAccessorDescriptor) contextType).getCorrespondingProperty() ? ((PropertyAccessorDescriptor) contextType).getCorrespondingProperty()
: contextType, contextKind, parentContext, null); : contextType, contextKind, parentContext, null, parentContext.hasThisDescriptor());
} }
@NotNull
@Override @Override
protected ClassDescriptor getThisDescriptor() { protected ClassDescriptor getThisDescriptor() {
//noinspection ConstantConditions //noinspection ConstantConditions
@@ -196,12 +200,13 @@ public class CodegenContexts {
@Nullable CodegenContext parentContext, @Nullable CodegenContext parentContext,
@Nullable ObjectOrClosureCodegen closureCodegen @Nullable ObjectOrClosureCodegen closureCodegen
) { ) {
super(contextDescriptor, contextKind, parentContext, closureCodegen); super(contextDescriptor, contextKind, parentContext, closureCodegen, true);
this.classDescriptor = contextDescriptor; this.classDescriptor = contextDescriptor;
this.scriptDescriptor = scriptDescriptor; this.scriptDescriptor = scriptDescriptor;
} }
@NotNull
@Override @Override
protected ClassDescriptor getThisDescriptor() { protected ClassDescriptor getThisDescriptor() {
return classDescriptor; return classDescriptor;
@@ -225,7 +230,7 @@ public class CodegenContexts {
CodegenContext parentContext, CodegenContext parentContext,
JetTypeMapper typeMapper JetTypeMapper typeMapper
) { ) {
super(contextDescriptor, contextKind, parentContext, null); super(contextDescriptor, contextKind, parentContext, null, true);
final Type type = enclosingClassType(typeMapper); final Type type = enclosingClassType(typeMapper);
outerExpression = type != null outerExpression = type != null
@@ -233,6 +238,7 @@ public class CodegenContexts {
: null; : null;
} }
@NotNull
@Override @Override
protected ClassDescriptor getThisDescriptor() { protected ClassDescriptor getThisDescriptor() {
return (ClassDescriptor) getContextDescriptor(); return (ClassDescriptor) getContextDescriptor();
@@ -252,7 +258,7 @@ public class CodegenContexts {
@NotNull ObjectOrClosureCodegen closure, @NotNull ObjectOrClosureCodegen closure,
JetTypeMapper typeMapper JetTypeMapper typeMapper
) { ) {
super(contextDescriptor, contextKind, parentContext, closure); super(contextDescriptor, contextKind, parentContext, closure, true);
final Type type = enclosingClassType(typeMapper); final Type type = enclosingClassType(typeMapper);
Type owner = closure.state.getInjector().getJetTypeMapper().mapType(contextDescriptor.getDefaultType(), MapTypeMode.IMPL); Type owner = closure.state.getInjector().getJetTypeMapper().mapType(contextDescriptor.getDefaultType(), MapTypeMode.IMPL);
@@ -261,6 +267,7 @@ public class CodegenContexts {
: null; : null;
} }
@NotNull
@Override @Override
protected ClassDescriptor getThisDescriptor() { protected ClassDescriptor getThisDescriptor() {
return (ClassDescriptor) getContextDescriptor(); return (ClassDescriptor) getContextDescriptor();
@@ -288,7 +295,7 @@ public class CodegenContexts {
JvmClassName internalClassName, JvmClassName internalClassName,
JetTypeMapper typeMapper JetTypeMapper typeMapper
) { ) {
super(contextDescriptor, OwnerKind.IMPLEMENTATION, parentContext, closureCodegen); super(contextDescriptor, OwnerKind.IMPLEMENTATION, parentContext, closureCodegen, true);
this.classDescriptor = classDescriptor; this.classDescriptor = classDescriptor;
final Type type = enclosingClassType(typeMapper); final Type type = enclosingClassType(typeMapper);
@@ -297,6 +304,7 @@ public class CodegenContexts {
: null; : null;
} }
@NotNull
@Override @Override
protected ClassDescriptor getThisDescriptor() { protected ClassDescriptor getThisDescriptor() {
return classDescriptor; return classDescriptor;
@@ -321,12 +329,13 @@ public class CodegenContexts {
public static class NamespaceContext extends CodegenContext { public static class NamespaceContext extends CodegenContext {
public NamespaceContext(NamespaceDescriptor contextDescriptor, CodegenContext parent, OwnerKind kind) { public NamespaceContext(NamespaceDescriptor contextDescriptor, CodegenContext parent, OwnerKind kind) {
super(contextDescriptor, kind != null ? kind : OwnerKind.NAMESPACE, parent, null); super(contextDescriptor, kind != null ? kind : OwnerKind.NAMESPACE, parent, null, false);
} }
@NotNull
@Override @Override
protected ClassDescriptor getThisDescriptor() { protected ClassDescriptor getThisDescriptor() {
return null; throw new UnsupportedOperationException();
} }
@Override @Override
@@ -1300,7 +1300,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
} }
boolean isInterface; boolean isInterface;
boolean isInsideClass = containingDeclaration == context.getThisDescriptor(); boolean isInsideClass = context.hasThisDescriptor() && containingDeclaration == context.getThisDescriptor();
if (isInsideClass || isStatic) { if (isInsideClass || isStatic) {
owner = typeMapper.getOwner(functionDescriptor, contextKind()); owner = typeMapper.getOwner(functionDescriptor, contextKind());
isInterface = false; isInterface = false;
@@ -1334,10 +1334,12 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
boolean isFakeOverride = propertyDescriptor.getKind() == CallableMemberDescriptor.Kind.FAKE_OVERRIDE; boolean isFakeOverride = propertyDescriptor.getKind() == CallableMemberDescriptor.Kind.FAKE_OVERRIDE;
PropertyDescriptor initialDescriptor = propertyDescriptor; PropertyDescriptor initialDescriptor = propertyDescriptor;
propertyDescriptor = initialDescriptor.getOriginal(); propertyDescriptor = initialDescriptor.getOriginal();
boolean isInsideClass = !isFakeOverride && (((containingDeclaration == context.getThisDescriptor()) || boolean isInsideClass = !isFakeOverride &&
(context.getParentContext() instanceof CodegenContexts.NamespaceContext) && (((containingDeclaration == null && !context.hasThisDescriptor() ||
context.getParentContext().getContextDescriptor() == containingDeclaration) context.hasThisDescriptor() && containingDeclaration == context.getThisDescriptor()) ||
&& contextKind() != OwnerKind.TRAIT_IMPL); (context.getParentContext() instanceof CodegenContexts.NamespaceContext) &&
context.getParentContext().getContextDescriptor() == containingDeclaration)
&& contextKind() != OwnerKind.TRAIT_IMPL);
Method getter = null; Method getter = null;
Method setter = null; Method setter = null;
if (!forceField) { if (!forceField) {
@@ -1436,7 +1438,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
&& propertyDescriptor.getContainingDeclaration() instanceof ClassDescriptor) { && propertyDescriptor.getContainingDeclaration() instanceof ClassDescriptor) {
if (context.getClassOrNamespaceDescriptor() != propertyDescriptor.getContainingDeclaration()) { if (context.getClassOrNamespaceDescriptor() != propertyDescriptor.getContainingDeclaration()) {
DeclarationDescriptor enclosed = propertyDescriptor.getContainingDeclaration(); DeclarationDescriptor enclosed = propertyDescriptor.getContainingDeclaration();
if (enclosed != context.getThisDescriptor()) { if (!context.hasThisDescriptor() || enclosed != context.getThisDescriptor()) {
CodegenContext c = context; CodegenContext c = context;
while (c != null && c.getContextDescriptor() != enclosed) { while (c != null && c.getContextDescriptor() != enclosed) {
c = c.getParentContext(); c = c.getParentContext();
@@ -1796,7 +1798,6 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
assert cur != null; assert cur != null;
final ClassDescriptor thisDescriptor = cur.getThisDescriptor(); final ClassDescriptor thisDescriptor = cur.getThisDescriptor();
assert thisDescriptor != null;
if (DescriptorUtils.isSubclass(thisDescriptor, calleeContainingClass)) { if (DescriptorUtils.isSubclass(thisDescriptor, calleeContainingClass)) {
if (!isObject || (thisDescriptor == calleeContainingClass)) { if (!isObject || (thisDescriptor == calleeContainingClass)) {
return castToRequiredTypeOfInterfaceIfNeeded(result, thisDescriptor, calleeContainingClass); return castToRequiredTypeOfInterfaceIfNeeded(result, thisDescriptor, calleeContainingClass);