initial super.property

This commit is contained in:
Alex Tkachman
2011-11-04 13:11:41 +01:00
parent 2755fb8538
commit df87493e4d
12 changed files with 204 additions and 38 deletions
@@ -69,7 +69,7 @@ public class ClosureCodegen extends FunctionOrClosureCodegen {
signatureWriter.visitEnd(); signatureWriter.visitEnd();
cv.defineClass(V1_6, cv.defineClass(V1_6,
ACC_PUBLIC, ACC_PUBLIC/*|ACC_SUPER*/,
name, name,
null, null,
funClass, funClass,
@@ -128,6 +128,23 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
throw new UnsupportedOperationException("Codegen for " + expression + " is not yet implemented"); throw new UnsupportedOperationException("Codegen for " + expression + " is not yet implemented");
} }
@Override
public StackValue visitNamedFunction(JetNamedFunction function, StackValue data) {
throw new UnsupportedOperationException("Codegen for named functions is not yet implemented");
}
@Override
public StackValue visitSuperExpression(JetSuperExpression expression, StackValue data) {
// final DeclarationDescriptor descriptor = bindingContext.get(BindingContext.REFERENCE_TARGET, expression.getInstanceReference());
// if (descriptor instanceof ClassDescriptor) {
// return generateThisOrOuter((ClassDescriptor) descriptor);
// }
// else {
// return thisExpression();
// }
return StackValue.none();
}
@Override @Override
public StackValue visitParenthesizedExpression(JetParenthesizedExpression expression, StackValue receiver) { public StackValue visitParenthesizedExpression(JetParenthesizedExpression expression, StackValue receiver) {
return genQualified(receiver, expression.getExpression()); return genQualified(receiver, expression.getExpression());
@@ -285,7 +302,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
// if(hND != null) // if(hND != null)
// invokeFunctionNoParams(hND, Type.BOOLEAN_TYPE, v); // invokeFunctionNoParams(hND, Type.BOOLEAN_TYPE, v);
// else // else
intermediateValueForProperty((PropertyDescriptor) hasNextDescriptor, false, false).put(Type.BOOLEAN_TYPE, v); intermediateValueForProperty((PropertyDescriptor) hasNextDescriptor, false, false, false).put(Type.BOOLEAN_TYPE, v);
} }
v.ifeq(end); v.ifeq(end);
@@ -793,16 +810,17 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
} }
else { else {
boolean isStatic = container instanceof NamespaceDescriptorImpl; boolean isStatic = container instanceof NamespaceDescriptorImpl;
final boolean directToField = expression.getReferencedNameElementType() == JetTokens.FIELD_IDENTIFIER; final boolean directToField = expression.getReferencedNameElementType() == JetTokens.FIELD_IDENTIFIER && contextKind() != OwnerKind.TRAIT_IMPL ;
JetExpression r = getReceiverForSelector(expression); JetExpression r = getReceiverForSelector(expression);
final boolean forceInterface = r != null && !(r instanceof JetThisExpression); final boolean forceInterface = r != null && !(r instanceof JetThisExpression);
final StackValue iValue = intermediateValueForProperty(propertyDescriptor, directToField, forceInterface); final boolean isSuper = r instanceof JetSuperExpression;
final StackValue iValue = intermediateValueForProperty(propertyDescriptor, directToField, forceInterface, isSuper);
if (!isStatic) { if (!isStatic) {
if (receiver == StackValue.none()) { if (receiver == StackValue.none()) {
receiver = generateThisOrOuter((ClassDescriptor) propertyDescriptor.getContainingDeclaration()); receiver = generateThisOrOuter((ClassDescriptor) propertyDescriptor.getContainingDeclaration());
} }
JetType receiverType = bindingContext.get(BindingContext.EXPRESSION_TYPE, r); JetType receiverType = bindingContext.get(BindingContext.EXPRESSION_TYPE, r);
receiver.put(receiverType != null ? typeMapper.mapType(receiverType) : JetTypeMapper.TYPE_OBJECT, v); receiver.put(receiverType != null && !isSuper? typeMapper.mapType(receiverType) : JetTypeMapper.TYPE_OBJECT, v);
if(receiverType != null) { if(receiverType != null) {
ClassDescriptor propReceiverDescriptor = (ClassDescriptor) propertyDescriptor.getContainingDeclaration(); ClassDescriptor propReceiverDescriptor = (ClassDescriptor) propertyDescriptor.getContainingDeclaration();
if(!CodegenUtil.isInterface(propReceiverDescriptor) && CodegenUtil.isInterface(receiverType.getConstructor().getDeclarationDescriptor())) { if(!CodegenUtil.isInterface(propReceiverDescriptor) && CodegenUtil.isInterface(receiverType.getConstructor().getDeclarationDescriptor())) {
@@ -895,11 +913,11 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
StackValue.onStack(typeMapper.mapType(functionDescriptor.getReturnType())).coerce(type, v); StackValue.onStack(typeMapper.mapType(functionDescriptor.getReturnType())).coerce(type, v);
} }
public StackValue intermediateValueForProperty(PropertyDescriptor propertyDescriptor, final boolean forceField, boolean forceInterface) { public StackValue intermediateValueForProperty(PropertyDescriptor propertyDescriptor, final boolean forceField, boolean forceInterface, boolean isSuper) {
DeclarationDescriptor containingDeclaration = propertyDescriptor.getContainingDeclaration(); DeclarationDescriptor containingDeclaration = propertyDescriptor.getContainingDeclaration();
boolean isStatic = containingDeclaration instanceof NamespaceDescriptorImpl; boolean isStatic = containingDeclaration instanceof NamespaceDescriptorImpl;
propertyDescriptor = propertyDescriptor.getOriginal(); propertyDescriptor = propertyDescriptor.getOriginal();
boolean isInsideClass = !forceInterface && containingDeclaration == context.getContextClass(); boolean isInsideClass = !forceInterface && containingDeclaration == context.getContextClass() && contextKind() != OwnerKind.TRAIT_IMPL;
Method getter; Method getter;
Method setter; Method setter;
if (forceField) { if (forceField) {
@@ -909,10 +927,10 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
else { else {
//noinspection ConstantConditions //noinspection ConstantConditions
getter = isInsideClass && (propertyDescriptor.getGetter() == null || propertyDescriptor.getGetter().isDefault()) getter = isInsideClass && (propertyDescriptor.getGetter() == null || propertyDescriptor.getGetter().isDefault())
? null : typeMapper.mapGetterSignature(propertyDescriptor); ? null : typeMapper.mapGetterSignature(propertyDescriptor, OwnerKind.IMPLEMENTATION);
//noinspection ConstantConditions //noinspection ConstantConditions
setter = isInsideClass && (propertyDescriptor.getSetter() == null || propertyDescriptor.getSetter().isDefault()) setter = isInsideClass && (propertyDescriptor.getSetter() == null || propertyDescriptor.getSetter().isDefault())
? null : typeMapper.mapSetterSignature(propertyDescriptor); ? null : typeMapper.mapSetterSignature(propertyDescriptor, OwnerKind.IMPLEMENTATION);
} }
String owner; String owner;
@@ -931,7 +949,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
} }
} }
return StackValue.property(propertyDescriptor.getName(), owner, typeMapper.mapType(propertyDescriptor.getOutType()), isStatic, isInterface, getter, setter); return StackValue.property(propertyDescriptor.getName(), owner, typeMapper.mapType(propertyDescriptor.getOutType()), isStatic, isInterface, isSuper, getter, setter);
} }
@Override @Override
@@ -1009,10 +1027,10 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
private DeclarationDescriptor resolveCalleeDescriptor(JetCallExpression call) { private DeclarationDescriptor resolveCalleeDescriptor(JetCallExpression call) {
JetExpression callee = call.getCalleeExpression(); JetExpression callee = call.getCalleeExpression();
if (!(callee instanceof JetSimpleNameExpression)) { if (!(callee instanceof JetReferenceExpression)) {
throw new UnsupportedOperationException("Don't know how to generate a call to " + callee); throw new UnsupportedOperationException("Don't know how to generate a call to " + callee);
} }
DeclarationDescriptor funDescriptor = bindingContext.get(BindingContext.REFERENCE_TARGET, (JetSimpleNameExpression) callee); DeclarationDescriptor funDescriptor = bindingContext.get(BindingContext.REFERENCE_TARGET, (JetReferenceExpression) callee);
if (funDescriptor == null) { if (funDescriptor == null) {
throw new CompilationException("Cannot resolve: " + callee.getText()); throw new CompilationException("Cannot resolve: " + callee.getText());
} }
@@ -1883,7 +1901,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
Type type = JetTypeMapper.psiClassType(javaClass); Type type = JetTypeMapper.psiClassType(javaClass);
v.anew(type); v.anew(type);
v.dup(); v.dup();
final CallableMethod callableMethod = typeMapper.mapToCallableMethod(constructor); final CallableMethod callableMethod = JetTypeMapper.mapToCallableMethod(constructor);
invokeMethodWithArguments(callableMethod, expression, StackValue.none()); invokeMethodWithArguments(callableMethod, expression, StackValue.none());
return type; return type;
} }
@@ -2071,6 +2089,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
return generateThisOrOuter((ClassDescriptor) descriptor); return generateThisOrOuter((ClassDescriptor) descriptor);
} }
else { else {
// estension function or ???
return thisExpression(); return thisExpression();
} }
} }
@@ -2481,7 +2500,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
final DeclarationDescriptor descriptor = bindingContext.get(BindingContext.REFERENCE_TARGET, (JetSimpleNameExpression) call); final DeclarationDescriptor descriptor = bindingContext.get(BindingContext.REFERENCE_TARGET, (JetSimpleNameExpression) call);
if (descriptor instanceof PropertyDescriptor) { if (descriptor instanceof PropertyDescriptor) {
v.load(subjectLocal, subjectType); v.load(subjectLocal, subjectType);
conditionValue = intermediateValueForProperty((PropertyDescriptor) descriptor, false, false); conditionValue = intermediateValueForProperty((PropertyDescriptor) descriptor, false, false, false);
} }
else { else {
throw new UnsupportedOperationException("unknown simple name resolve result: " + descriptor); throw new UnsupportedOperationException("unknown simple name resolve result: " + descriptor);
@@ -95,7 +95,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
v.defineClass(Opcodes.V1_6, v.defineClass(Opcodes.V1_6,
Opcodes.ACC_PUBLIC | (isAbstract ? Opcodes.ACC_ABSTRACT : 0) | (isInterface Opcodes.ACC_PUBLIC | (isAbstract ? Opcodes.ACC_ABSTRACT : 0) | (isInterface
? Opcodes.ACC_INTERFACE ? Opcodes.ACC_INTERFACE
: 0), : 0/*Opcodes.ACC_SUPER*/),
jvmName(), jvmName(),
null, null,
superClass, superClass,
@@ -652,7 +652,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
if(propertyDescriptor.getOutType().isNullable()) if(propertyDescriptor.getOutType().isNullable())
type = JetTypeMapper.boxType(type); type = JetTypeMapper.boxType(type);
codegen.gen(initializer, type); codegen.gen(initializer, type);
codegen.intermediateValueForProperty(propertyDescriptor, false, false).store(iv); codegen.intermediateValueForProperty(propertyDescriptor, false, false, false).store(iv);
} }
} }
@@ -627,18 +627,29 @@ public class JetTypeMapper {
answer.append(p.getName()); // TODO: BOUND! answer.append(p.getName()); // TODO: BOUND!
} }
public Method mapGetterSignature(PropertyDescriptor descriptor) { public Method mapGetterSignature(PropertyDescriptor descriptor, OwnerKind kind) {
Type returnType = mapType(descriptor.getOutType()); Type returnType = mapType(descriptor.getOutType());
return new Method(PropertyCodegen.getterName(descriptor.getName()), returnType, new Type[0]); if(kind != OwnerKind.TRAIT_IMPL)
return new Method(PropertyCodegen.getterName(descriptor.getName()), returnType, new Type[0]);
else {
ClassDescriptor containingDeclaration = (ClassDescriptor) descriptor.getContainingDeclaration();
return new Method(PropertyCodegen.getterName(descriptor.getName()), returnType, new Type[] { mapType(containingDeclaration.getDefaultType()) });
}
} }
public Method mapSetterSignature(PropertyDescriptor descriptor) { public Method mapSetterSignature(PropertyDescriptor descriptor, OwnerKind kind) {
final JetType inType = descriptor.getInType(); final JetType inType = descriptor.getInType();
if (inType == null) { if (inType == null) {
return null; return null;
} }
Type paramType = mapType(inType); Type paramType = mapType(inType);
return new Method(PropertyCodegen.setterName(descriptor.getName()), Type.VOID_TYPE, new Type[] { paramType }); if(kind != OwnerKind.TRAIT_IMPL) {
return new Method(PropertyCodegen.setterName(descriptor.getName()), Type.VOID_TYPE, new Type[] { paramType });
}
else {
ClassDescriptor containingDeclaration = (ClassDescriptor) descriptor.getContainingDeclaration();
return new Method(PropertyCodegen.setterName(descriptor.getName()), Type.VOID_TYPE, new Type[] { mapType(containingDeclaration.getDefaultType()), paramType });
}
} }
private Method mapConstructorSignature(ConstructorDescriptor descriptor, List<Type> valueParameterTypes) { private Method mapConstructorSignature(ConstructorDescriptor descriptor, List<Type> valueParameterTypes) {
@@ -32,7 +32,7 @@ public class NamespaceCodegen {
this.state = state; this.state = state;
v.defineClass(V1_6, v.defineClass(V1_6,
ACC_PUBLIC, ACC_PUBLIC/*|ACC_SUPER*/,
getJVMClassName(fqName), getJVMClassName(fqName),
null, null,
//"jet/lang/Namespace", //"jet/lang/Namespace",
@@ -93,7 +93,7 @@ public class NamespaceCodegen {
if (initializer != null && !(initializer instanceof JetConstantExpression)) { if (initializer != null && !(initializer instanceof JetConstantExpression)) {
final PropertyDescriptor descriptor = (PropertyDescriptor) state.getBindingContext().get(BindingContext.VARIABLE, declaration); final PropertyDescriptor descriptor = (PropertyDescriptor) state.getBindingContext().get(BindingContext.VARIABLE, declaration);
codegen.genToJVMStack(initializer); codegen.genToJVMStack(initializer);
codegen.intermediateValueForProperty(descriptor, true, false).store(new InstructionAdapter(mv)); codegen.intermediateValueForProperty(descriptor, true, false, false).store(new InstructionAdapter(mv));
} }
} }
} }
@@ -37,8 +37,9 @@ public class PropertyCodegen {
throw new UnsupportedOperationException("expect a property to have a property descriptor"); throw new UnsupportedOperationException("expect a property to have a property descriptor");
} }
final PropertyDescriptor propertyDescriptor = (PropertyDescriptor) descriptor; final PropertyDescriptor propertyDescriptor = (PropertyDescriptor) descriptor;
if (kind == OwnerKind.NAMESPACE || kind == OwnerKind.IMPLEMENTATION) { if (kind == OwnerKind.NAMESPACE || kind == OwnerKind.IMPLEMENTATION || kind ==OwnerKind.TRAIT_IMPL ) {
generateBackingField(p, propertyDescriptor); if(kind != OwnerKind.TRAIT_IMPL)
generateBackingField(p, propertyDescriptor);
generateGetter(p, propertyDescriptor); generateGetter(p, propertyDescriptor);
generateSetter(p, propertyDescriptor); generateSetter(p, propertyDescriptor);
} }
@@ -81,7 +82,7 @@ public class PropertyCodegen {
final JetPropertyAccessor getter = p.getGetter(); final JetPropertyAccessor getter = p.getGetter();
if (getter != null) { if (getter != null) {
if (getter.getBodyExpression() != null) { if (getter.getBodyExpression() != null) {
functionCodegen.generateMethod(getter, state.getTypeMapper().mapGetterSignature(propertyDescriptor), propertyDescriptor.getGetter()); functionCodegen.generateMethod(getter, state.getTypeMapper().mapGetterSignature(propertyDescriptor, kind), propertyDescriptor.getGetter());
} }
else if (!getter.hasModifier(JetTokens.PRIVATE_KEYWORD)) { else if (!getter.hasModifier(JetTokens.PRIVATE_KEYWORD)) {
generateDefaultGetter(p, getter); generateDefaultGetter(p, getter);
@@ -102,7 +103,7 @@ public class PropertyCodegen {
if (setter.getBodyExpression() != null) { if (setter.getBodyExpression() != null) {
final PropertySetterDescriptor setterDescriptor = propertyDescriptor.getSetter(); final PropertySetterDescriptor setterDescriptor = propertyDescriptor.getSetter();
assert setterDescriptor != null; assert setterDescriptor != null;
functionCodegen.generateMethod(setter, state.getTypeMapper().mapSetterSignature(propertyDescriptor), setterDescriptor); functionCodegen.generateMethod(setter, state.getTypeMapper().mapSetterSignature(propertyDescriptor, kind), setterDescriptor);
} }
else if (!p.hasModifier(JetTokens.PRIVATE_KEYWORD)) { else if (!p.hasModifier(JetTokens.PRIVATE_KEYWORD)) {
generateDefaultSetter(p, setter); generateDefaultSetter(p, setter);
@@ -120,6 +121,10 @@ public class PropertyCodegen {
} }
public void generateDefaultGetter(PropertyDescriptor propertyDescriptor, int flags, PsiElement origin) { public void generateDefaultGetter(PropertyDescriptor propertyDescriptor, int flags, PsiElement origin) {
if (kind == OwnerKind.TRAIT_IMPL) {
return;
}
if (kind == OwnerKind.NAMESPACE) { if (kind == OwnerKind.NAMESPACE) {
flags |= Opcodes.ACC_STATIC; flags |= Opcodes.ACC_STATIC;
} }
@@ -129,7 +134,7 @@ public class PropertyCodegen {
if(isTrait && !(kind instanceof OwnerKind.DelegateKind)) if(isTrait && !(kind instanceof OwnerKind.DelegateKind))
flags |= Opcodes.ACC_ABSTRACT; flags |= Opcodes.ACC_ABSTRACT;
final String signature = state.getTypeMapper().mapGetterSignature(propertyDescriptor).getDescriptor(); final String signature = state.getTypeMapper().mapGetterSignature(propertyDescriptor, kind).getDescriptor();
String getterName = getterName(propertyDescriptor.getName()); String getterName = getterName(propertyDescriptor.getName());
MethodVisitor mv = v.newMethod(origin, flags, getterName, signature, null, null); MethodVisitor mv = v.newMethod(origin, flags, getterName, signature, null, null);
if (!isTrait || kind instanceof OwnerKind.DelegateKind) { if (!isTrait || kind instanceof OwnerKind.DelegateKind) {
@@ -162,6 +167,10 @@ public class PropertyCodegen {
} }
public void generateDefaultSetter(PropertyDescriptor propertyDescriptor, int flags, PsiElement origin) { public void generateDefaultSetter(PropertyDescriptor propertyDescriptor, int flags, PsiElement origin) {
if (kind == OwnerKind.TRAIT_IMPL) {
return;
}
if (kind == OwnerKind.NAMESPACE) { if (kind == OwnerKind.NAMESPACE) {
flags |= Opcodes.ACC_STATIC; flags |= Opcodes.ACC_STATIC;
} }
@@ -171,7 +180,7 @@ public class PropertyCodegen {
if(isTrait && !(kind instanceof OwnerKind.DelegateKind)) if(isTrait && !(kind instanceof OwnerKind.DelegateKind))
flags |= Opcodes.ACC_ABSTRACT; flags |= Opcodes.ACC_ABSTRACT;
final String signature = state.getTypeMapper().mapSetterSignature(propertyDescriptor).getDescriptor(); final String signature = state.getTypeMapper().mapSetterSignature(propertyDescriptor, kind).getDescriptor();
MethodVisitor mv = v.newMethod(origin, flags, setterName(propertyDescriptor.getName()), signature, null, null); MethodVisitor mv = v.newMethod(origin, flags, setterName(propertyDescriptor.getName()), signature, null, null);
if (!isTrait || kind instanceof OwnerKind.DelegateKind) { if (!isTrait || kind instanceof OwnerKind.DelegateKind) {
mv.visitCode(); mv.visitCode();
@@ -96,8 +96,8 @@ public abstract class StackValue {
return new InstanceField(type, owner, name); return new InstanceField(type, owner, name);
} }
public static StackValue property(String name, String owner, Type type, boolean isStatic, boolean isInterface, Method getter, Method setter) { public static StackValue property(String name, String owner, Type type, boolean isStatic, boolean isInterface, boolean isSuper, Method getter, Method setter) {
return new Property(name, owner, getter, setter, isStatic, isInterface, type); return new Property(name, owner, getter, setter, isStatic, isInterface, isSuper, type);
} }
public static StackValue expression(Type type, JetExpression expression, ExpressionCodegen generator) { public static StackValue expression(Type type, JetExpression expression, ExpressionCodegen generator) {
@@ -623,8 +623,9 @@ public abstract class StackValue {
private final String owner; private final String owner;
private final boolean isStatic; private final boolean isStatic;
private final boolean isInterface; private final boolean isInterface;
private boolean isSuper;
public Property(String name, String owner, Method getter, Method setter, boolean aStatic, boolean isInterface, Type type) { public Property(String name, String owner, Method getter, Method setter, boolean aStatic, boolean isInterface, boolean isSuper, Type type) {
super(type); super(type);
this.name = name; this.name = name;
this.owner = owner; this.owner = owner;
@@ -632,26 +633,37 @@ public abstract class StackValue {
this.setter = setter; this.setter = setter;
isStatic = aStatic; isStatic = aStatic;
this.isInterface = isInterface; this.isInterface = isInterface;
this.isSuper = isSuper;
} }
@Override @Override
public void put(Type type, InstructionAdapter v) { public void put(Type type, InstructionAdapter v) {
if (getter == null) { if(isSuper && isInterface) {
v.visitFieldInsn(isStatic ? Opcodes.GETSTATIC : Opcodes.GETFIELD, owner, name, this.type.getDescriptor()); v.visitMethodInsn(Opcodes.INVOKESTATIC, owner + "$$TImpl", getter.getName(), getter.getDescriptor().replace("(","(L" + owner + ";"));
} }
else { else {
v.visitMethodInsn(isStatic ? Opcodes.INVOKESTATIC : isInterface ? Opcodes.INVOKEINTERFACE : Opcodes.INVOKEVIRTUAL, owner, getter.getName(), getter.getDescriptor()); 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); coerce(type, v);
} }
@Override @Override
public void store(InstructionAdapter v) { public void store(InstructionAdapter v) {
if (setter == null) { if(isSuper && isInterface) {
v.visitFieldInsn(isStatic ? Opcodes.PUTSTATIC : Opcodes.PUTFIELD, owner, name, this.type.getDescriptor()); v.visitMethodInsn(Opcodes.INVOKESTATIC, owner + "$$TImpl", setter.getName(), setter.getDescriptor().replace("(","(L" + owner + ";"));
} }
else { else {
v.visitMethodInsn(isStatic ? Opcodes.INVOKESTATIC : isInterface ? Opcodes.INVOKEINTERFACE : Opcodes.INVOKEVIRTUAL, owner, setter.getName(), setter.getDescriptor()); 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());
}
} }
} }
@@ -46,7 +46,7 @@ public class TraitImplBodyCodegen extends ClassBodyCodegen {
@Override @Override
protected void generateDeclaration() { protected void generateDeclaration() {
v.defineClass(Opcodes.V1_6, v.defineClass(Opcodes.V1_6,
Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL, Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL/*| Opcodes.ACC_SUPER*/,
jvmName(), jvmName(),
null, null,
"java/lang/Object", "java/lang/Object",
@@ -0,0 +1,22 @@
open class M() {
open var b: Int = 0
}
class N() : M() {
val a : Int
get() {
super.b = super.b + 1
return super.b + 1
}
override var b: Int = a + 1
val superb : Int
get() = super.b
}
fun box(): String {
val n = N()
System.out?.println("a: " + n.a + " b: " + n.b + " superb: " + n.superb)
if (n.b == 3 && n.a == 4 && n.superb == 3) return "OK";
return "fail";
}
@@ -0,0 +1,29 @@
trait M {
var backingB : Int
var b : Int
get() = backingB
set(value: Int) {
backingB = value
}
}
class N() : M {
override var backingB : Int = 0
val a : Int
get() {
super.b = super.b + 1
return super.b + 1
}
override var b: Int = a + 1
val superb : Int
get() = super.b
}
fun box(): String {
val n = N()
System.out?.println("a: " + n.a + " b: " + n.b + " superb: " + n.superb)
if (n.b == 3 && n.a == 4 && n.superb == 3) return "OK";
return "fail";
}
@@ -80,4 +80,55 @@ public class FunctionGenTest extends CodegenTestCase {
public void testKt395 () { public void testKt395 () {
blackBoxFile("regressions/kt395.jet"); blackBoxFile("regressions/kt395.jet");
} }
/*
public void testFunction () throws InvocationTargetException, IllegalAccessException {
loadText("fun Any.foo() : fun(): String {\n" +
" return { \"239\" + this }\n" +
"}\n" +
"fun box() : String {\n" +
" return if((10.foo())() == \"23910\") \"OK\" else \"fail\"" +
"}" +
"");
System.out.println(generateToText());
Method foo = generateFunction();
assertTrue((Boolean) foo.invoke(null, "lala"));
assertFalse((Boolean) foo.invoke(null, "mama"));
}
fun Any.foo() : fun() : Unit {
return {}
}
fun Any.foo1() : fun(i : Int) : Unit {
return {}
}
fun foo2() : fun(i : fun()) : Unit {
return {}
}
fun fooT1<T>(t : T) : fun() : T {
return {t}
}
fun fooT2<T>() : fun(t : T) : T {
return {it}
}
fun main(args : Array<String>) {
args.foo()()
args.foo1()(1)
foo2()({})
(foo2()){}
val a = fooT1(1)()
a : Int
val b = fooT2<Int>()(1)
b : Int
fooT2()(1) // : Any?
}
*/
} }
@@ -0,0 +1,13 @@
package org.jetbrains.jet.codegen;
public class SuperGenTest extends CodegenTestCase {
public void testBasicProperty () {
blackBoxFile("/super/basicproperty.jet");
System.out.println(generateToText());
}
public void testTraitProperty () {
blackBoxFile("/super/traitproperty.jet");
System.out.println(generateToText());
}
}