提交 f6deed26 编写于 作者: A Alex Tkachman

enclosed super properties

上级 e1d94d2d
package org.jetbrains.jet.codegen;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext;
......@@ -11,6 +14,7 @@ import org.objectweb.asm.commons.InstructionAdapter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
/**
......@@ -37,12 +41,12 @@ public abstract class ClassBodyCodegen {
this.v = v;
}
public void generate() {
public final void generate(@Nullable HashMap<DeclarationDescriptor, DeclarationDescriptor> accessors) {
generateDeclaration();
generateClassBody();
generateSyntheticParts();
generateSyntheticParts(accessors);
generateStaticInitializer();
......@@ -51,7 +55,7 @@ public abstract class ClassBodyCodegen {
protected abstract void generateDeclaration();
protected void generateSyntheticParts() {
protected void generateSyntheticParts(HashMap<DeclarationDescriptor, DeclarationDescriptor> accessors) {
}
private void generateClassBody() {
......
package org.jetbrains.jet.codegen;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext;
import java.util.HashMap;
/**
* @author max
* @author alex.tkachman
......@@ -15,29 +19,30 @@ public class ClassCodegen {
this.state = state;
}
public void generate(ClassContext parentContext, JetClassOrObject aClass) {
public void generate(ClassContext context, JetClassOrObject aClass) {
GenerationState.prepareAnonymousClasses((JetElement) aClass, state.getTypeMapper());
ClassDescriptor descriptor = state.getBindingContext().get(BindingContext.CLASS, aClass);
generateImplementation(parentContext, aClass, OwnerKind.IMPLEMENTATION);
final ClassContext contextForInners = parentContext.intoClass(null, descriptor, OwnerKind.IMPLEMENTATION);
final ClassContext contextForInners = context.intoClass(null, descriptor, OwnerKind.IMPLEMENTATION);
for (JetDeclaration declaration : aClass.getDeclarations()) {
if (declaration instanceof JetClass && !(declaration instanceof JetEnumEntry)) {
generate(contextForInners, (JetClass) declaration);
}
}
generateImplementation(context, aClass, OwnerKind.IMPLEMENTATION, contextForInners.accessors);
}
private void generateImplementation(ClassContext parentContext, JetClassOrObject aClass, OwnerKind kind) {
private void generateImplementation(ClassContext context, JetClassOrObject aClass, OwnerKind kind, HashMap<DeclarationDescriptor, DeclarationDescriptor> accessors) {
ClassDescriptor descriptor = state.getBindingContext().get(BindingContext.CLASS, aClass);
ClassBuilder v = state.forClassImplementation(descriptor);
new ImplementationBodyCodegen(aClass, parentContext.intoClass(null, descriptor, kind), v, state).generate();
ClassContext classContext = context.intoClass(null, descriptor, kind);
new ImplementationBodyCodegen(aClass, classContext, v, state).generate(accessors);
if(aClass instanceof JetClass && ((JetClass)aClass).isTrait()) {
v = state.forTraitImplementation(descriptor);
new TraitImplBodyCodegen(aClass, parentContext.intoClass(null, descriptor, OwnerKind.TRAIT_IMPL), v, state).generate();
new TraitImplBodyCodegen(aClass, context.intoClass(null, descriptor, OwnerKind.TRAIT_IMPL), v, state).generate(null);
}
}
......
package org.jetbrains.jet.codegen;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.psi.JetTypeReference;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import org.jetbrains.jet.lang.types.JetType;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.InstructionAdapter;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import static org.jetbrains.jet.lang.diagnostics.Errors.WRONG_GETTER_RETURN_TYPE;
/*
* @author max
......@@ -21,11 +26,12 @@ public class ClassContext {
private final DeclarationDescriptor contextType;
private final OwnerKind contextKind;
private final StackValue thisExpression;
private final ClassContext parentContext;
final ClassContext parentContext;
public final FunctionOrClosureCodegen closure;
private boolean thisWasUsed = false;
HashMap<JetType,Integer> typeInfoConstants;
HashMap<DeclarationDescriptor, DeclarationDescriptor> accessors;
public ClassContext(DeclarationDescriptor contextType, OwnerKind contextKind, StackValue thisExpression, ClassContext parentContext, FunctionOrClosureCodegen closureCodegen) {
this.contextType = contextType;
......@@ -194,4 +200,59 @@ public class ClassContext {
}
return index;
}
DeclarationDescriptor getAccessor(DeclarationDescriptor descriptor) {
if(accessors == null) {
accessors = new HashMap<DeclarationDescriptor,DeclarationDescriptor>();
}
descriptor = descriptor.getOriginal();
DeclarationDescriptor accessor = accessors.get(descriptor);
if(accessor != null)
return accessor;
if(descriptor instanceof FunctionDescriptor) {
FunctionDescriptorImpl myAccessor = new FunctionDescriptorImpl(contextType,
Collections.<AnnotationDescriptor>emptyList(),
descriptor.getName() + "$bridge$" + accessors.size());
FunctionDescriptor fd = (FunctionDescriptor) descriptor;
myAccessor.initialize(fd.getReceiverParameter().exists() ? fd.getReceiverParameter().getType() : null,
fd.getExpectedThisObject(),
fd.getTypeParameters(),
fd.getValueParameters(),
fd.getReturnType(),
fd.getModality(),
fd.getVisibility());
accessor = myAccessor;
}
else if(descriptor instanceof PropertyDescriptor) {
PropertyDescriptor pd = (PropertyDescriptor) descriptor;
PropertyDescriptor myAccessor = new PropertyDescriptor(contextType,
Collections.<AnnotationDescriptor>emptyList(),
pd.getModality(),
pd.getVisibility(),
pd.isVar(),
pd.getReceiverParameter().exists() ? pd.getReceiverParameter().getType() : null,
pd.getExpectedThisObject(),
pd.getName() + "$bridge$" + accessors.size(),
pd.getInType(),
pd.getOutType());
PropertyGetterDescriptor pgd = new PropertyGetterDescriptor(
myAccessor, Collections.<AnnotationDescriptor>emptyList(), myAccessor.getModality(),
myAccessor.getVisibility(),
myAccessor.getOutType(), false, false);
PropertySetterDescriptor psd = new PropertySetterDescriptor(
myAccessor.getModality(),
myAccessor.getVisibility(),
myAccessor,
Collections.<AnnotationDescriptor>emptyList(),
false, false);
myAccessor.initialize(Collections.<TypeParameterDescriptor>emptyList(), pgd, psd);
accessor = myAccessor;
}
else {
throw new UnsupportedOperationException();
}
accessors.put(descriptor, accessor);
return accessor;
}
}
......@@ -302,7 +302,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
// if(hND != null)
// invokeFunctionNoParams(hND, Type.BOOLEAN_TYPE, v);
// else
intermediateValueForProperty((PropertyDescriptor) hasNextDescriptor, false, false, false).put(Type.BOOLEAN_TYPE, v);
intermediateValueForProperty((PropertyDescriptor) hasNextDescriptor, false, null).put(Type.BOOLEAN_TYPE, v);
}
v.ifeq(end);
......@@ -813,9 +813,8 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
boolean isStatic = container instanceof NamespaceDescriptorImpl;
final boolean directToField = expression.getReferencedNameElementType() == JetTokens.FIELD_IDENTIFIER && contextKind() != OwnerKind.TRAIT_IMPL ;
JetExpression r = getReceiverForSelector(expression);
final boolean forceInterface = r != null && !(r instanceof JetThisExpression);
final boolean isSuper = r instanceof JetSuperExpression;
final StackValue iValue = intermediateValueForProperty(propertyDescriptor, directToField, forceInterface, isSuper);
final StackValue iValue = intermediateValueForProperty(propertyDescriptor, directToField, isSuper ? (JetSuperExpression)r : null);
if (!isStatic) {
if (receiver == StackValue.none()) {
receiver = generateThisOrOuter((ClassDescriptor) propertyDescriptor.getContainingDeclaration());
......@@ -913,11 +912,13 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
StackValue.onStack(typeMapper.mapType(functionDescriptor.getReturnType())).coerce(type, v);
}
public StackValue intermediateValueForProperty(PropertyDescriptor propertyDescriptor, final boolean forceField, boolean forceInterface, boolean isSuper) {
public StackValue intermediateValueForProperty(PropertyDescriptor propertyDescriptor, final boolean forceField, @Nullable JetSuperExpression superExpression) {
boolean isSuper = superExpression != null;
DeclarationDescriptor containingDeclaration = propertyDescriptor.getContainingDeclaration();
boolean isStatic = containingDeclaration instanceof NamespaceDescriptorImpl;
propertyDescriptor = propertyDescriptor.getOriginal();
boolean isInsideClass = !forceInterface && containingDeclaration == context.getContextClass() && contextKind() != OwnerKind.TRAIT_IMPL;
boolean isInsideClass = containingDeclaration == context.getContextClass() && contextKind() != OwnerKind.TRAIT_IMPL;
Method getter;
Method setter;
if (forceField) {
......@@ -926,11 +927,33 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
}
else {
//noinspection ConstantConditions
getter = isInsideClass && (propertyDescriptor.getGetter() == null || propertyDescriptor.getGetter().isDefault())
? null : typeMapper.mapGetterSignature(propertyDescriptor, OwnerKind.IMPLEMENTATION);
if (isInsideClass && (propertyDescriptor.getGetter() == null || propertyDescriptor.getGetter().isDefault())) {
getter = null;
}
else {
if(isSuper) {
PsiElement enclosingElement = bindingContext.get(BindingContext.LABEL_TARGET, superExpression.getTargetLabel());
ClassDescriptor enclosed = (ClassDescriptor) bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, enclosingElement);
if(!CodegenUtil.isInterface(propertyDescriptor.getContainingDeclaration())) {
if(enclosed != null && enclosed != context.getContextClass()) {
ClassContext c = context;
while(c.getContextDescriptor() != enclosed) {
c = c.getParentContext();
}
propertyDescriptor = (PropertyDescriptor) c.getAccessor(propertyDescriptor);
isSuper = false;
}
}
}
getter = typeMapper.mapGetterSignature(propertyDescriptor, OwnerKind.IMPLEMENTATION);
}
//noinspection ConstantConditions
setter = isInsideClass && (propertyDescriptor.getSetter() == null || propertyDescriptor.getSetter().isDefault())
? null : typeMapper.mapSetterSignature(propertyDescriptor, OwnerKind.IMPLEMENTATION);
if (isInsideClass && (propertyDescriptor.getSetter() == null || propertyDescriptor.getSetter().isDefault())) {
setter = null;
}
else {
setter = typeMapper.mapSetterSignature(propertyDescriptor, OwnerKind.IMPLEMENTATION);
}
}
String owner;
......@@ -973,8 +996,21 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
boolean superCall = false;
if (expression.getParent() instanceof JetQualifiedExpression) {
final JetExpression receiverExpression = ((JetQualifiedExpression) expression.getParent()).getReceiverExpression();
if(receiverExpression instanceof JetSuperExpression) {
if (receiverExpression instanceof JetSuperExpression) {
superCall = true;
JetSuperExpression superExpression = (JetSuperExpression) receiverExpression;
PsiElement enclosingElement = bindingContext.get(BindingContext.LABEL_TARGET, superExpression.getTargetLabel());
ClassDescriptor enclosed = (ClassDescriptor) bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, enclosingElement);
if(!CodegenUtil.isInterface(fd.getContainingDeclaration())) {
if(enclosed != null && enclosed != context.getContextClass()) {
ClassContext c = context;
while(c.getContextDescriptor() != enclosed) {
c = c.getParentContext();
}
fd = c.getAccessor((FunctionDescriptor) fd);
superCall = false;
}
}
}
}
......@@ -2459,7 +2495,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
final DeclarationDescriptor descriptor = bindingContext.get(BindingContext.REFERENCE_TARGET, (JetSimpleNameExpression) call);
if (descriptor instanceof PropertyDescriptor) {
v.load(subjectLocal, subjectType);
conditionValue = intermediateValueForProperty((PropertyDescriptor) descriptor, false, false, false);
conditionValue = intermediateValueForProperty((PropertyDescriptor) descriptor, false, null);
}
else {
throw new UnsupportedOperationException("unknown simple name resolve result: " + descriptor);
......
......@@ -122,7 +122,7 @@ public class GenerationState {
closure.name = nameAndVisitor.getFirst();
final ClassContext objectContext = closure.context.intoClass(closure, getBindingContext().get(BindingContext.CLASS, objectDeclaration), OwnerKind.IMPLEMENTATION);
new ImplementationBodyCodegen(objectDeclaration, objectContext, nameAndVisitor.getSecond(), this).generate();
new ImplementationBodyCodegen(objectDeclaration, objectContext, nameAndVisitor.getSecond(), this).generate(null);
ConstructorDescriptor constructorDescriptor = closure.state.getBindingContext().get(BindingContext.CONSTRUCTOR, objectDeclaration);
CallableMethod callableMethod = closure.state.getTypeMapper().mapToCallableMethod(constructorDescriptor, OwnerKind.IMPLEMENTATION);
......
......@@ -154,9 +154,10 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
}
@Override
protected void generateSyntheticParts() {
protected void generateSyntheticParts(HashMap<DeclarationDescriptor, DeclarationDescriptor> accessors) {
generateFieldForObjectInstance();
generateFieldForClassObject();
generateAccessors(accessors);
try {
generatePrimaryConstructor();
......@@ -168,6 +169,81 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
generateGetTypeInfo();
}
private void generateAccessors(HashMap<DeclarationDescriptor, DeclarationDescriptor> accessors) {
if(accessors != null) {
for (Map.Entry<DeclarationDescriptor, DeclarationDescriptor> entry : accessors.entrySet()) {
if(entry.getValue() instanceof FunctionDescriptor) {
FunctionDescriptor bridge = (FunctionDescriptor) entry.getValue();
FunctionDescriptor original = (FunctionDescriptor) entry.getKey();
Method method = state.getTypeMapper().mapSignature(bridge.getName(), bridge);
Method originalMethod = state.getTypeMapper().mapSignature(original.getName(), original);
Type[] argTypes = method.getArgumentTypes();
MethodVisitor mv = v.newMethod(null, Opcodes.ACC_PUBLIC|Opcodes.ACC_BRIDGE|Opcodes.ACC_FINAL, bridge.getName(), method.getDescriptor(), null, null);
mv.visitCode();
InstructionAdapter iv = new InstructionAdapter(mv);
iv.load(0, JetTypeMapper.TYPE_OBJECT);
for (int i = 0, reg = 1; i < argTypes.length; i++) {
Type argType = argTypes[i];
iv.load(reg, argType);
//noinspection AssignmentToForLoopParameter
reg += argType.getSize();
}
iv.invokespecial(state.getTypeMapper().getOwner(original, OwnerKind.IMPLEMENTATION), originalMethod.getName(), originalMethod.getDescriptor());
iv.areturn(method.getReturnType());
mv.visitMaxs(0,0);
mv.visitEnd();
}
else if(entry.getValue() instanceof PropertyDescriptor) {
PropertyDescriptor bridge = (PropertyDescriptor) entry.getValue();
PropertyDescriptor original = (PropertyDescriptor) entry.getKey();
Method method = state.getTypeMapper().mapGetterSignature(bridge, OwnerKind.IMPLEMENTATION);
Method originalMethod = state.getTypeMapper().mapGetterSignature(original, OwnerKind.IMPLEMENTATION);
MethodVisitor mv = v.newMethod(null, Opcodes.ACC_PUBLIC|Opcodes.ACC_BRIDGE|Opcodes.ACC_FINAL, method.getName(), method.getDescriptor(), null, null);
mv.visitCode();
InstructionAdapter iv = new InstructionAdapter(mv);
iv.load(0, JetTypeMapper.TYPE_OBJECT);
iv.invokespecial(state.getTypeMapper().getOwner(original, OwnerKind.IMPLEMENTATION), originalMethod.getName(), originalMethod.getDescriptor());
iv.areturn(method.getReturnType());
mv.visitMaxs(0,0);
mv.visitEnd();
method = state.getTypeMapper().mapSetterSignature(bridge, OwnerKind.IMPLEMENTATION);
originalMethod = state.getTypeMapper().mapSetterSignature(original, OwnerKind.IMPLEMENTATION);
mv = v.newMethod(null, Opcodes.ACC_PUBLIC|Opcodes.ACC_BRIDGE|Opcodes.ACC_FINAL, method.getName(), method.getDescriptor(), null, null);
mv.visitCode();
iv = new InstructionAdapter(mv);
iv.load(0, JetTypeMapper.TYPE_OBJECT);
Type[] argTypes = method.getArgumentTypes();
for (int i = 0, reg = 1; i < argTypes.length; i++) {
Type argType = argTypes[i];
iv.load(reg, argType);
//noinspection AssignmentToForLoopParameter
reg += argType.getSize();
}
iv.invokespecial(state.getTypeMapper().getOwner(original, OwnerKind.IMPLEMENTATION), originalMethod.getName(), originalMethod.getDescriptor());
iv.areturn(method.getReturnType());
mv.visitMaxs(0,0);
mv.visitEnd();
}
else {
throw new UnsupportedOperationException();
}
}
}
}
private void generateFieldForObjectInstance() {
if (isNonLiteralObject()) {
Type type = state.getTypeMapper().jetImplementationType(descriptor);
......@@ -654,7 +730,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
if(propertyDescriptor.getOutType().isNullable())
type = JetTypeMapper.boxType(type);
codegen.gen(initializer, type);
codegen.intermediateValueForProperty(propertyDescriptor, false, false, false).store(iv);
codegen.intermediateValueForProperty(propertyDescriptor, false, null).store(iv);
}
}
......
......@@ -6,6 +6,7 @@ import jet.JetObject;
import jet.typeinfo.TypeInfo;
import jet.typeinfo.TypeInfoProjection;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext;
......@@ -19,6 +20,8 @@ import org.objectweb.asm.commons.Method;
import java.util.*;
import static org.objectweb.asm.Opcodes.*;
/**
* @author yole
* @author alex.tkachman
......@@ -319,14 +322,14 @@ public class JetTypeMapper {
if (functionParent instanceof NamespaceDescriptor) {
assert !superCall;
owner = NamespaceCodegen.getJVMClassName(DescriptorRenderer.getFQName(functionParent));
invokeOpcode = Opcodes.INVOKESTATIC;
invokeOpcode = INVOKESTATIC;
thisClass = null;
}
else if (functionDescriptor instanceof ConstructorDescriptor) {
assert !superCall;
ClassDescriptor containingClass = (ClassDescriptor) functionParent;
owner = jvmName(containingClass, OwnerKind.IMPLEMENTATION);
invokeOpcode = Opcodes.INVOKESPECIAL;
invokeOpcode = INVOKESPECIAL;
thisClass = null;
}
else if (functionParent instanceof ClassDescriptor) {
......@@ -486,16 +489,16 @@ public class JetTypeMapper {
List<Type> valueParameterTypes = new ArrayList<Type>();
final Method method = mapConstructorSignature(descriptor, valueParameterTypes);
String owner = jvmName(descriptor.getContainingDeclaration(), kind);
return new CallableMethod(owner, method, Opcodes.INVOKESPECIAL, valueParameterTypes);
return new CallableMethod(owner, method, INVOKESPECIAL, valueParameterTypes);
}
static int getAccessModifiers(JetDeclaration p, int defaultFlags) {
int flags = 0;
if (p.hasModifier(JetTokens.PUBLIC_KEYWORD)) {
flags |= Opcodes.ACC_PUBLIC;
flags |= ACC_PUBLIC;
}
else if (p.hasModifier(JetTokens.PRIVATE_KEYWORD)) {
flags |= Opcodes.ACC_PRIVATE;
flags |= ACC_PRIVATE;
}
else {
flags |= defaultFlags;
......
......@@ -93,7 +93,7 @@ public class NamespaceCodegen {
if (initializer != null && !(initializer instanceof JetConstantExpression)) {
final PropertyDescriptor descriptor = (PropertyDescriptor) state.getBindingContext().get(BindingContext.VARIABLE, declaration);
codegen.genToJVMStack(initializer);
codegen.intermediateValueForProperty(descriptor, true, false, false).store(new InstructionAdapter(mv));
codegen.intermediateValueForProperty(descriptor, true, null).store(new InstructionAdapter(mv));
}
}
}
......
......@@ -642,12 +642,12 @@ public abstract class StackValue {
v.visitMethodInsn(Opcodes.INVOKESTATIC, owner + "$$TImpl", getter.getName(), getter.getDescriptor().replace("(","(L" + owner + ";"));
}
else {
if (getter == null) {
v.visitFieldInsn(isStatic ? Opcodes.GETSTATIC : Opcodes.GETFIELD, owner, name, this.type.getDescriptor());
}
else {
if (getter == null) {
v.visitFieldInsn(isStatic ? Opcodes.GETSTATIC : Opcodes.GETFIELD, owner, name, this.type.getDescriptor());
}
else {
v.visitMethodInsn(isStatic ? Opcodes.INVOKESTATIC : isSuper ? Opcodes.INVOKESPECIAL : isInterface ? Opcodes.INVOKEINTERFACE : Opcodes.INVOKEVIRTUAL, owner, getter.getName(), getter.getDescriptor());
}
}
}
coerce(type, v);
}
......@@ -658,10 +658,10 @@ public abstract class StackValue {
v.visitMethodInsn(Opcodes.INVOKESTATIC, owner + "$$TImpl", setter.getName(), setter.getDescriptor().replace("(","(L" + owner + ";"));
}
else {
if (setter == null) {
v.visitFieldInsn(isStatic ? Opcodes.PUTSTATIC : Opcodes.PUTFIELD, owner, name, this.type.getDescriptor());
}
else {
if (setter == null) {
v.visitFieldInsn(isStatic ? Opcodes.PUTSTATIC : Opcodes.PUTFIELD, owner, name, this.type.getDescriptor());
}
else {
v.visitMethodInsn(isStatic ? Opcodes.INVOKESTATIC : isSuper ? Opcodes.INVOKESPECIAL : isInterface ? Opcodes.INVOKEINTERFACE : Opcodes.INVOKEVIRTUAL, owner, setter.getName(), setter.getDescriptor());
}
}
......
trait BK {
fun x() : Int = 50
}
trait K : BK {
override fun x() : Int = super.x() * 2
}
open class M() {
open fun x() : Int = 10
open var y = 500
}
open class N() : M(), K {
override fun x() : Int = 20
override var y = 200
open class C() : K {
fun test1() = x()
fun test2() = super<M>@N.x()
fun test3() = super<K>@N.x()
fun test4() = super<K>.x()
fun test5() = y
fun test6() : Int {
super<M>@N.y += 200
return super<M>@N.y
}
}
}
fun box(): String {
if (N().C().test1() != 100) return "test1 fail";
if (N().C().test2() != 10) return "test2 fail";
if (N().C().test3() != 100) return "test3 fail";
if (N().C().test4() != 100) return "test4 fail";
if (N().C().test5() != 200) return "test5 fail";
if (N().C().test6() != 700) return "test6 fail";
return "OK";
}
\ No newline at end of file
......@@ -15,4 +15,9 @@ public class SuperGenTest extends CodegenTestCase {
blackBoxFile("/super/basicmethod.jet");
System.out.println(generateToText());
}
public void testEnclosedMethod () {
blackBoxFile("/super/enclosed.jet");
System.out.println(generateToText());
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册