initial super.property
This commit is contained in:
@@ -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());
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user