diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/AccessorForPropertyDescriptor.java b/compiler/backend/src/org/jetbrains/jet/codegen/AccessorForPropertyDescriptor.java index 1d37ec8d7f2..97df1657f93 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/AccessorForPropertyDescriptor.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/AccessorForPropertyDescriptor.java @@ -30,7 +30,7 @@ import java.util.Collections; public class AccessorForPropertyDescriptor extends PropertyDescriptorImpl { public AccessorForPropertyDescriptor(PropertyDescriptor pd, DeclarationDescriptor containingDeclaration, int index) { - super(containingDeclaration, Collections.emptyList(), Modality.FINAL, Visibilities.PUBLIC, + super(containingDeclaration, Collections.emptyList(), Modality.FINAL, Visibilities.LOCAL, pd.isVar(), Name.identifier(pd.getName() + "$b$" + index), Kind.DECLARATION); @@ -41,7 +41,7 @@ public class AccessorForPropertyDescriptor extends PropertyDescriptorImpl { public static class Getter extends PropertyGetterDescriptorImpl { public Getter(AccessorForPropertyDescriptor property) { - super(property, Collections.emptyList(), Modality.FINAL, Visibilities.PUBLIC, + super(property, Collections.emptyList(), Modality.FINAL, Visibilities.LOCAL, false, false, Kind.DECLARATION); initialize(property.getType()); @@ -50,7 +50,7 @@ public class AccessorForPropertyDescriptor extends PropertyDescriptorImpl { public static class Setter extends PropertySetterDescriptorImpl { public Setter(AccessorForPropertyDescriptor property) { - super(property, Collections.emptyList(), Modality.FINAL, Visibilities.PUBLIC, + super(property, Collections.emptyList(), Modality.FINAL, Visibilities.LOCAL, false, false, Kind.DECLARATION); initializeDefault(); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/AsmUtil.java b/compiler/backend/src/org/jetbrains/jet/codegen/AsmUtil.java index 2601e3608ba..66e9bcf7bb6 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/AsmUtil.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/AsmUtil.java @@ -130,11 +130,14 @@ public class AsmUtil { } } - public static boolean isAbstract(FunctionDescriptor functionDescriptor, OwnerKind kind) { + public static boolean isAbstractMethod(FunctionDescriptor functionDescriptor, OwnerKind kind) { return (functionDescriptor.getModality() == Modality.ABSTRACT || isInterface(functionDescriptor.getContainingDeclaration())) - && !isStatic(kind) - && kind != OwnerKind.TRAIT_IMPL; + && !isStaticMethod(kind, functionDescriptor); + } + + public static boolean isStaticMethod(OwnerKind kind, FunctionDescriptor functionDescriptor) { + return isStatic(kind) || kind == OwnerKind.TRAIT_IMPL || JetTypeMapper.isAccessor(functionDescriptor); } public static boolean isStatic(OwnerKind kind) { @@ -142,9 +145,6 @@ public class AsmUtil { } public static int getMethodAsmFlags(FunctionDescriptor functionDescriptor, OwnerKind kind) { - boolean isStatic = isStatic(kind); - boolean isAbstract = isAbstract(functionDescriptor, kind); - int flags = getCommonCallableFlags(functionDescriptor); if (functionDescriptor.getModality() == Modality.FINAL && !(functionDescriptor instanceof ConstructorDescriptor)) { @@ -155,19 +155,21 @@ public class AsmUtil { } } - if (isStatic || kind == OwnerKind.TRAIT_IMPL) { + if (isStaticMethod(kind, functionDescriptor)) { flags |= ACC_STATIC; } - if (isAbstract) flags |= ACC_ABSTRACT; + if (isAbstractMethod(functionDescriptor, kind)) { + flags |= ACC_ABSTRACT; + } + + if (JetTypeMapper.isAccessor(functionDescriptor)) { + flags |= ACC_SYNTHETIC; + } return flags; } - public static int getConstructorAsmFlags(FunctionDescriptor functionDescriptor) { - return getCommonCallableFlags(functionDescriptor); - } - private static int getCommonCallableFlags(FunctionDescriptor functionDescriptor) { int flags = getVisibilityAccessFlag(functionDescriptor); flags |= getVarargsFlag(functionDescriptor); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/CodegenUtil.java b/compiler/backend/src/org/jetbrains/jet/codegen/CodegenUtil.java index 80f943f8bf5..c6a41ce6d3a 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/CodegenUtil.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/CodegenUtil.java @@ -262,4 +262,14 @@ public class CodegenUtil { } return false; } + + public static boolean couldUseDirectAccessToProperty(PropertyDescriptor propertyDescriptor, boolean forGetter, boolean isInsideClass) { + PropertyAccessorDescriptor accessorDescriptor = forGetter ? propertyDescriptor.getGetter() : propertyDescriptor.getSetter(); + boolean isExtensionProperty = propertyDescriptor.getReceiverParameter() != null; + return isInsideClass && + !isExtensionProperty && + (accessorDescriptor == null || + accessorDescriptor.isDefault() && + (!DescriptorUtils.isExternallyAccessible(propertyDescriptor) || accessorDescriptor.getModality() == Modality.FINAL)); + } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index 9ef874313eb..5cdd9a1f6ba 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -297,6 +297,11 @@ public class ExpressionCodegen extends JetVisitor implem } private ClassDescriptor getSuperCallLabelTarget(JetSuperExpression expression) { + return getSuperCallLabelTarget(expression, bindingContext, context); + } + + @NotNull + private static ClassDescriptor getSuperCallLabelTarget(JetSuperExpression expression, BindingContext bindingContext, CodegenContext context) { PsiElement labelPsi = bindingContext.get(BindingContext.LABEL_TARGET, expression.getTargetLabel()); ClassDescriptor labelTarget = (ClassDescriptor) bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, labelPsi); DeclarationDescriptor descriptor = bindingContext.get(BindingContext.REFERENCE_TARGET, expression.getInstanceReference()); @@ -305,7 +310,7 @@ public class ExpressionCodegen extends JetVisitor implem return labelTarget; } assert descriptor instanceof ClassDescriptor : "Don't know how to generate super-call to not a class"; - ClassDescriptor target = getParentContextSubclassOf((ClassDescriptor) descriptor).getThisDescriptor(); + ClassDescriptor target = getParentContextSubclassOf((ClassDescriptor) descriptor, context).getThisDescriptor(); return target; } @@ -1552,12 +1557,11 @@ public class ExpressionCodegen extends JetVisitor implem if (descriptor instanceof PropertyDescriptor) { PropertyDescriptor propertyDescriptor = (PropertyDescriptor) descriptor; - boolean isStatic = container instanceof NamespaceDescriptor; boolean directToField = expression.getReferencedNameElementType() == JetTokens.FIELD_IDENTIFIER && contextKind() != OwnerKind.TRAIT_IMPL; JetExpression r = getReceiverForSelector(expression); boolean isSuper = r instanceof JetSuperExpression; - propertyDescriptor = accessablePropertyDescriptor(propertyDescriptor); + propertyDescriptor = accessablePropertyDescriptor(context, propertyDescriptor); StackValue.Property iValue = intermediateValueForProperty(propertyDescriptor, directToField, isSuper ? (JetSuperExpression) r : null); if (directToField) { @@ -1662,6 +1666,19 @@ public class ExpressionCodegen extends JetVisitor implem boolean forceField, @Nullable JetSuperExpression superExpression ) { + return intermediateValueForProperty(propertyDescriptor, forceField, superExpression, state, context, false); + } + + @NotNull + public static StackValue.Property intermediateValueForProperty( + PropertyDescriptor propertyDescriptor, + boolean forceField, + @Nullable JetSuperExpression superExpression, + @NotNull GenerationState state, + @NotNull CodegenContext context, + @NotNull boolean forceSpecialFlag + ) { + JetTypeMapper typeMapper = state.getTypeMapper(); DeclarationDescriptor containingDeclaration = propertyDescriptor.getContainingDeclaration(); assert containingDeclaration != null; @@ -1670,23 +1687,18 @@ public class ExpressionCodegen extends JetVisitor implem boolean isSuper = superExpression != null; boolean isInsideClass = isCallInsideSameClassAsDeclared(propertyDescriptor, context); boolean isInsideModule = isCallInsideSameModuleAsDeclared(propertyDescriptor, context); - boolean isExtensionProperty = propertyDescriptor.getReceiverParameter() != null; CallableMethod callableGetter = null; CallableMethod callableSetter = null; if (!forceField) { //noinspection ConstantConditions - if (isInsideClass && - !isExtensionProperty && - (propertyDescriptor.getGetter() == null || - !DescriptorUtils.isExternallyAccessible(propertyDescriptor) || - propertyDescriptor.getGetter().isDefault() && propertyDescriptor.getGetter().getModality() == Modality.FINAL)) { + if (couldUseDirectAccessToProperty(propertyDescriptor, true, isInsideClass)) { callableGetter = null; } else { if (isSuper && !isInterface(containingDeclaration)) { - ClassDescriptor owner = getSuperCallLabelTarget(superExpression); + ClassDescriptor owner = getSuperCallLabelTarget(superExpression, state.getBindingContext(), context); CodegenContext c = context.findParentContextWithDescriptor(owner); assert c != null : "Couldn't find a context for a super-call: " + propertyDescriptor; if (c != context.getParentContext()) { @@ -1694,23 +1706,20 @@ public class ExpressionCodegen extends JetVisitor implem } } - propertyDescriptor = accessablePropertyDescriptor(propertyDescriptor); + propertyDescriptor = accessablePropertyDescriptor(context, propertyDescriptor); if (propertyDescriptor.getGetter() != null) { - callableGetter = typeMapper.mapToCallableMethod(propertyDescriptor.getGetter(), isSuper, isInsideClass, isInsideModule, OwnerKind.IMPLEMENTATION); + callableGetter = typeMapper.mapToCallableMethod(propertyDescriptor.getGetter(), isSuper || forceSpecialFlag, isInsideClass, isInsideModule, OwnerKind.IMPLEMENTATION); } } if (propertyDescriptor.isVar()) { if (propertyDescriptor.getSetter() != null) { - if (isInsideClass && !isExtensionProperty && - (!DescriptorUtils.isExternallyAccessible(propertyDescriptor) || - propertyDescriptor.getSetter().isDefault() && - propertyDescriptor.getSetter().getModality() == Modality.FINAL)) { + if (couldUseDirectAccessToProperty(propertyDescriptor, false, isInsideClass)) { callableSetter = null; } else { - callableSetter = typeMapper.mapToCallableMethod(propertyDescriptor.getSetter(), isSuper, isInsideClass, isInsideModule, OwnerKind.IMPLEMENTATION); + callableSetter = typeMapper.mapToCallableMethod(propertyDescriptor.getSetter(), isSuper || forceSpecialFlag, isInsideClass, isInsideModule, OwnerKind.IMPLEMENTATION); } } } @@ -1721,13 +1730,13 @@ public class ExpressionCodegen extends JetVisitor implem propertyDescriptor = unwrapFakeOverride(propertyDescriptor); if (callableMethod == null) { - owner = typeMapper.getOwner(propertyDescriptor, contextKind(), isInsideModule); + owner = typeMapper.getOwner(propertyDescriptor, context.getContextKind(), isInsideModule); } else { owner = callableMethod.getOwner(); } - return StackValue.property(propertyDescriptor, owner, asmType(propertyDescriptor.getOriginal().getType()), + return StackValue.property(propertyDescriptor, owner, typeMapper.mapType(propertyDescriptor.getOriginal().getType()), isStatic, callableGetter, callableSetter, state); } @@ -1814,7 +1823,7 @@ public class ExpressionCodegen extends JetVisitor implem } } - private PropertyDescriptor accessablePropertyDescriptor(PropertyDescriptor propertyDescriptor) { + private static PropertyDescriptor accessablePropertyDescriptor(CodegenContext context, PropertyDescriptor propertyDescriptor) { PropertySetterDescriptor setter = propertyDescriptor.getSetter(); PropertyGetterDescriptor getter = propertyDescriptor.getGetter(); @@ -1919,7 +1928,8 @@ public class ExpressionCodegen extends JetVisitor implem } // Find the first parent of the current context which corresponds to a subclass of a given class - private CodegenContext getParentContextSubclassOf(ClassDescriptor descriptor) { + @NotNull + private static CodegenContext getParentContextSubclassOf(ClassDescriptor descriptor, CodegenContext context) { CodegenContext c = context; while (true) { if ((c instanceof ClassContext || c instanceof AnonymousClassContext) && diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java index 280533b870f..1cd9ca64071 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java @@ -127,7 +127,7 @@ public class FunctionCodegen extends GenerationStateAware { genJetAnnotations(mv, functionDescriptor, jvmSignature); } - if (isAbstract(functionDescriptor, methodContext.getContextKind())) return; + if (isAbstractMethod(functionDescriptor, methodContext.getContextKind())) return; if (state.getClassBuilderMode() == ClassBuilderMode.STUBS) { genStubCode(mv); @@ -227,13 +227,13 @@ public class FunctionCodegen extends GenerationStateAware { List params = jvmMethodSignature.getKotlinParameterTypes(); int shift = 0; - boolean isStatic = isStatic(ownerKind) || ownerKind == OwnerKind.TRAIT_IMPL; + boolean isStatic = AsmUtil.isStaticMethod(ownerKind, functionDescriptor); if (!isStatic) { //add this if (thisType != null) { mv.visitLocalVariable("this", thisType.getDescriptor(), null, methodBegin, methodEnd, shift); } else { - //sometimes there is no thisType for callable reference + //TODO: provide thisType for callable reference } shift++; } @@ -334,14 +334,13 @@ public class FunctionCodegen extends GenerationStateAware { ) { if (functionDescriptor instanceof PropertyAccessorDescriptor) { - assert jvmSignature instanceof JvmPropertyAccessorSignature; + assert jvmSignature instanceof JvmPropertyAccessorSignature : "jvmSignature for property should have JvmPropertyAccessorSignature type"; PropertyCodegen.generateJetPropertyAnnotation(mv, (JvmPropertyAccessorSignature) jvmSignature, ((PropertyAccessorDescriptor) functionDescriptor).getCorrespondingProperty(), functionDescriptor.getVisibility()); } else if (functionDescriptor instanceof SimpleFunctionDescriptor) { - if (jvmSignature instanceof JvmPropertyAccessorSignature) { - throw new IllegalStateException(); - } + assert !(jvmSignature instanceof JvmPropertyAccessorSignature) : "jvmSignature for function shouldn't have JvmPropertyAccessorSignature type"; + Modality modality = functionDescriptor.getModality(); JetMethodAnnotationWriter aw = JetMethodAnnotationWriter.visitAnnotation(mv); int kotlinFlags = getFlagsForVisibility(functionDescriptor.getVisibility()); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionGenerationStrategy.java b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionGenerationStrategy.java index 985c7084d1d..fd81638252c 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionGenerationStrategy.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionGenerationStrategy.java @@ -86,6 +86,7 @@ public abstract class FunctionGenerationStrategy { public abstract static class CodegenBased extends FunctionGenerationStrategy { private final GenerationState state; + protected final T callableDescriptor; public CodegenBased(@NotNull GenerationState state, T callableDescriptor) { diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java index 8cda8848e74..94abe4747b4 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java @@ -36,7 +36,6 @@ import org.jetbrains.jet.codegen.context.ConstructorContext; import org.jetbrains.jet.codegen.context.MethodContext; import org.jetbrains.jet.codegen.signature.*; import org.jetbrains.jet.codegen.signature.kotlin.JetMethodAnnotationWriter; -import org.jetbrains.jet.codegen.signature.kotlin.JetValueParameterAnnotationWriter; import org.jetbrains.jet.codegen.state.GenerationState; import org.jetbrains.jet.codegen.state.JetTypeMapper; import org.jetbrains.jet.codegen.state.JetTypeMapperMode; @@ -79,9 +78,14 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { private JetType superClassType; private final Type classAsmType; + private final FunctionCodegen functionCodegen; + private final PropertyCodegen propertyCodegen; + public ImplementationBodyCodegen(JetClassOrObject aClass, CodegenContext context, ClassBuilder v, GenerationState state) { super(aClass, context, v, state); - classAsmType = typeMapper.mapType(descriptor.getDefaultType(), JetTypeMapperMode.IMPL); + this.classAsmType = typeMapper.mapType(descriptor.getDefaultType(), JetTypeMapperMode.IMPL); + this.functionCodegen = new FunctionCodegen(context, v, state); + this.propertyCodegen = new PropertyCodegen(context, v, this.functionCodegen); } @Override @@ -440,7 +444,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { generateTraitMethods(); - generateAccessors(); + generateSyntheticAccessors(); generateEnumMethods(); @@ -798,13 +802,13 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } } - private void generateAccessors() { + private void generateSyntheticAccessors() { for (Map.Entry entry : context.getAccessors().entrySet()) { - genAccessor(entry); + generateSyntheticAccessor(entry); } } - private void genAccessor(Map.Entry entry) { + private void generateSyntheticAccessor(Map.Entry entry) { if (entry.getValue() instanceof FunctionDescriptor) { FunctionDescriptor bridge = (FunctionDescriptor) entry.getValue(); FunctionDescriptor original = (FunctionDescriptor) entry.getKey(); @@ -817,7 +821,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { Type[] argTypes = method.getArgumentTypes(); String owner = typeMapper.getOwner(original, OwnerKind.IMPLEMENTATION, isCallInsideSameModuleAsDeclared(original, context)).getInternalName(); - MethodVisitor mv = v.newMethod(null, ACC_BRIDGE | ACC_SYNTHETIC | ACC_STATIC, bridge.getName().getName(), + MethodVisitor mv = v.newMethod(null, ACC_SYNTHETIC | ACC_STATIC, bridge.getName().getName(), method.getDescriptor(), null, null); if (state.getClassBuilderMode() == ClassBuilderMode.STUBS) { genStubCode(mv); @@ -850,86 +854,46 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } else if (entry.getValue() instanceof PropertyDescriptor) { PropertyDescriptor bridge = (PropertyDescriptor) entry.getValue(); - PropertyDescriptor original = (PropertyDescriptor) entry.getKey(); - - { - Method method = typeMapper.mapGetterSignature(bridge, OwnerKind.IMPLEMENTATION).getAsmMethod(); - JvmPropertyAccessorSignature originalSignature = typeMapper.mapGetterSignature(original, OwnerKind.IMPLEMENTATION); - Method originalMethod = originalSignature.getAsmMethod(); - MethodVisitor mv = - v.newMethod(null, ACC_BRIDGE | ACC_SYNTHETIC | ACC_STATIC, method.getName(), method.getDescriptor(), null, null); - PropertyGetterDescriptor getter = bridge.getGetter(); - assert getter != null; - PropertyCodegen.generateJetPropertyAnnotation(mv, - originalSignature, - original, - getter.getVisibility()); - if (state.getClassBuilderMode() == ClassBuilderMode.STUBS) { - genStubCode(mv); - } - else if (state.getClassBuilderMode() == ClassBuilderMode.FULL) { - mv.visitCode(); - - InstructionAdapter iv = new InstructionAdapter(mv); + final PropertyDescriptor original = (PropertyDescriptor) entry.getKey(); + final StackValue.Property property = ExpressionCodegen.intermediateValueForProperty(original, false, null, state, context, true); + PropertyGetterDescriptor getter = bridge.getGetter(); + assert getter != null; + functionCodegen.generateMethod(null, typeMapper.mapGetterSignature(bridge, OwnerKind.IMPLEMENTATION), false, getter, + new FunctionGenerationStrategy.CodegenBased(state, getter) { + @Override + public void doGenerateBody(ExpressionCodegen codegen, JvmMethodSignature signature) { + InstructionAdapter iv = codegen.v; iv.load(0, OBJECT_TYPE); - boolean hasBackingField = Boolean.TRUE.equals(bindingContext.get(BindingContext.BACKING_FIELD_REQUIRED, original)); - boolean isInsideModule = isCallInsideSameModuleAsDeclared(original, context); - if (original.getVisibility() == Visibilities.PRIVATE && hasBackingField) { - iv.getfield(typeMapper.getOwner(original, OwnerKind.IMPLEMENTATION, isInsideModule).getInternalName(), original.getName().getName(), - originalMethod.getReturnType().getDescriptor()); - } - else { - iv.invokespecial(typeMapper.getOwner(original, OwnerKind.IMPLEMENTATION, isInsideModule).getInternalName(), - originalMethod.getName(), originalMethod.getDescriptor()); - } - - iv.areturn(method.getReturnType()); - FunctionCodegen.endVisit(iv, "accessor", null); + property.put(property.type, iv); + iv.areturn(signature.getAsmMethod().getReturnType()); } - } + }); + if (bridge.isVar()) { - Method method = typeMapper.mapSetterSignature(bridge, OwnerKind.IMPLEMENTATION).getAsmMethod(); - JvmPropertyAccessorSignature originalSignature2 = typeMapper.mapSetterSignature(original, OwnerKind.IMPLEMENTATION); - Method originalMethod = originalSignature2.getAsmMethod(); - MethodVisitor mv = - v.newMethod(null, ACC_STATIC | ACC_BRIDGE | ACC_FINAL, method.getName(), method.getDescriptor(), null, null); PropertySetterDescriptor setter = bridge.getSetter(); assert setter != null; - PropertyCodegen.generateJetPropertyAnnotation(mv, - originalSignature2, - original, - setter.getVisibility()); - if (state.getClassBuilderMode() == ClassBuilderMode.STUBS) { - genStubCode(mv); - } - else if (state.getClassBuilderMode() == ClassBuilderMode.FULL) { - mv.visitCode(); - InstructionAdapter iv = new InstructionAdapter(mv); + functionCodegen.generateMethod(null, typeMapper.mapSetterSignature(bridge, OwnerKind.IMPLEMENTATION), false, setter, + new FunctionGenerationStrategy.CodegenBased(state, setter) { + @Override + public void doGenerateBody(ExpressionCodegen codegen, JvmMethodSignature signature) { + InstructionAdapter iv = codegen.v; - iv.load(0, OBJECT_TYPE); - Type[] argTypes = method.getArgumentTypes(); - for (int i = 1, reg = 1; i < argTypes.length; i++) { - Type argType = argTypes[i]; - iv.load(reg, argType); - //noinspection AssignmentToForLoopParameter - reg += argType.getSize(); - } - boolean isInsideModule = isCallInsideSameModuleAsDeclared(original, context); - if (original.getVisibility() == Visibilities.PRIVATE && original.getModality() == Modality.FINAL) { - iv.putfield(typeMapper.getOwner(original, OwnerKind.IMPLEMENTATION, isInsideModule).getInternalName(), original.getName().getName(), - originalMethod.getArgumentTypes()[0].getDescriptor()); - } - else { - iv.invokespecial(typeMapper.getOwner(original, OwnerKind.IMPLEMENTATION, isInsideModule).getInternalName(), - originalMethod.getName(), originalMethod.getDescriptor()); - } + iv.load(0, OBJECT_TYPE); + Type[] argTypes = signature.getAsmMethod().getArgumentTypes(); + for (int i = 1, reg = 1; i < argTypes.length; i++) { + Type argType = argTypes[i]; + iv.load(reg, argType); + //noinspection AssignmentToForLoopParameter + reg += argType.getSize(); + } + property.store(property.type, iv); - iv.areturn(method.getReturnType()); - FunctionCodegen.endVisit(iv, "accessor", null); - } + iv.areturn(signature.getAsmMethod().getReturnType()); + } + }); } } else { @@ -979,26 +943,21 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { assert constructorDescriptor != null; - FunctionCodegen functionCodegen = new FunctionCodegen(context, v, state); - functionCodegen.generateMethod(null, constructorMethod, true, constructorDescriptor, constructorContext, - new FunctionGenerationStrategy.CodegenBased(state, constructorDescriptor) { + new FunctionGenerationStrategy.CodegenBased(state, constructorDescriptor) { - @NotNull - @Override - protected FrameMap createFrameMap( - @NotNull JetTypeMapper typeMapper, @NotNull CodegenContext context - ) { - return new ConstructorFrameMap(callableMethod, callableDescriptor); - } + @NotNull + @Override + protected FrameMap createFrameMap(@NotNull JetTypeMapper typeMapper, @NotNull CodegenContext context) { + return new ConstructorFrameMap(callableMethod, callableDescriptor); + } - @Override - public void doGenerateBody( - ExpressionCodegen codegen, JvmMethodSignature signature - ) { - generatePrimaryConstructorImpl(callableDescriptor, codegen, closure); - } - }); + @Override + public void doGenerateBody(ExpressionCodegen codegen, JvmMethodSignature signature) { + generatePrimaryConstructorImpl(callableDescriptor, codegen, closure); + } + } + ); FunctionCodegen.generateDefaultIfNeeded(constructorContext, state, v, constructorMethod.getAsmMethod(), constructorDescriptor, OwnerKind.IMPLEMENTATION, DefaultParameterValueLoader.DEFAULT); @@ -1642,9 +1601,6 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } protected void generateDelegates(ClassDescriptor toClass, StackValue field) { - FunctionCodegen functionCodegen = new FunctionCodegen(context, v, state); - PropertyCodegen propertyCodegen = new PropertyCodegen(context, v, functionCodegen); - for (DeclarationDescriptor declaration : descriptor.getDefaultType().getMemberScope().getAllDescriptors()) { if (declaration instanceof CallableMemberDescriptor) { CallableMemberDescriptor callableMemberDescriptor = (CallableMemberDescriptor) declaration; diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/state/JetTypeMapper.java b/compiler/backend/src/org/jetbrains/jet/codegen/state/JetTypeMapper.java index c3df5ff1e4b..3df691f617f 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/state/JetTypeMapper.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/state/JetTypeMapper.java @@ -550,7 +550,7 @@ public class JetTypeMapper extends BindingTraceAware { thisClass, receiverParameterType, null); } - private static boolean isAccessor(@NotNull CallableMemberDescriptor descriptor) { + public static boolean isAccessor(@NotNull CallableMemberDescriptor descriptor) { return descriptor instanceof AccessorForFunctionDescriptor || descriptor instanceof AccessorForPropertyDescriptor || descriptor instanceof AccessorForPropertyDescriptor.Getter || diff --git a/compiler/testData/codegen/box/properties/accessToPrivateProperty.kt b/compiler/testData/codegen/box/properties/accessToPrivateProperty.kt index 5d2ef0419a6..7418ab956a4 100644 --- a/compiler/testData/codegen/box/properties/accessToPrivateProperty.kt +++ b/compiler/testData/codegen/box/properties/accessToPrivateProperty.kt @@ -33,7 +33,7 @@ class C { class D { private var foo = 1 set(i: Int) { - foo = i + 1 + $foo = i + 1 } fun foo() { diff --git a/compiler/testData/codegen/box/properties/kt3118.kt b/compiler/testData/codegen/box/properties/kt3118.kt new file mode 100644 index 00000000000..b95ea4ad3b4 --- /dev/null +++ b/compiler/testData/codegen/box/properties/kt3118.kt @@ -0,0 +1,12 @@ +package testing + +class Test { + private val hello: String + get() { return "hello" } + + fun sayHello() : String = hello +} + +fun box(): String { + return if (Test().sayHello() == "hello") "OK" else "fail" +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/properties/kt3551.kt b/compiler/testData/codegen/box/properties/kt3551.kt new file mode 100644 index 00000000000..d0873ebd93c --- /dev/null +++ b/compiler/testData/codegen/box/properties/kt3551.kt @@ -0,0 +1,23 @@ +class Identifier() { + private var myNullable : Boolean = false + set(l : Boolean) { + //do nothing + } + + fun getValue() : Boolean { + return myNullable + } + + class object { + fun init(isNullable : Boolean) : Identifier { + val id = Identifier() + id.myNullable = isNullable + return id + } + } +} + +fun box() : String { + val id = Identifier.init(true) + return if (id.getValue() == false) return "OK" else "fail" +} diff --git a/compiler/testData/codegen/box/properties/kt3556.kt b/compiler/testData/codegen/box/properties/kt3556.kt new file mode 100644 index 00000000000..adce0368131 --- /dev/null +++ b/compiler/testData/codegen/box/properties/kt3556.kt @@ -0,0 +1,10 @@ +class Test { + val a : String = "1" + private val b : String get() = a + + fun outer() : Int { + return b.length + } +} + +fun box() = if (Test().outer() == 1) "OK" else "fail" diff --git a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java index 6c6efcd6d59..d20a784e404 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java @@ -3386,6 +3386,21 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest("compiler/testData/codegen/box/properties/kt2892.kt"); } + @TestMetadata("kt3118.kt") + public void testKt3118() throws Exception { + doTest("compiler/testData/codegen/box/properties/kt3118.kt"); + } + + @TestMetadata("kt3551.kt") + public void testKt3551() throws Exception { + doTest("compiler/testData/codegen/box/properties/kt3551.kt"); + } + + @TestMetadata("kt3556.kt") + public void testKt3556() throws Exception { + doTest("compiler/testData/codegen/box/properties/kt3556.kt"); + } + @TestMetadata("kt613.kt") public void testKt613() throws Exception { doTest("compiler/testData/codegen/box/properties/kt613.kt");