diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java index 3964ec06a6d..d0a313ea52e 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java @@ -777,8 +777,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { private Type genPropertyOnStack(InstructionAdapter iv, PropertyDescriptor propertyDescriptor, int index) { iv.load(index, classAsmType); - Method - method = typeMapper.mapGetterSignature(propertyDescriptor, OwnerKind.IMPLEMENTATION).getAsmMethod(); + //noinspection ConstantConditions + Method method = typeMapper.mapSignature(propertyDescriptor.getGetter()).getAsmMethod(); iv.invokevirtual(classAsmType.getInternalName(), method.getName(), method.getDescriptor()); return method.getReturnType(); @@ -957,7 +957,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { PropertyGetterDescriptor getter = bridge.getGetter(); assert getter != null; - functionCodegen.generateMethod(null, typeMapper.mapGetterSignature(bridge, OwnerKind.IMPLEMENTATION), getter, + functionCodegen.generateMethod(null, typeMapper.mapSignature(getter), getter, new FunctionGenerationStrategy.CodegenBased(state, getter) { @Override public void doGenerateBody(@NotNull ExpressionCodegen codegen, @NotNull JvmMethodSignature signature) { @@ -977,7 +977,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { PropertySetterDescriptor setter = bridge.getSetter(); assert setter != null; - functionCodegen.generateMethod(null, typeMapper.mapSetterSignature(bridge, OwnerKind.IMPLEMENTATION), setter, + functionCodegen.generateMethod(null, typeMapper.mapSignature(setter), setter, new FunctionGenerationStrategy.CodegenBased(state, setter) { @Override public void doGenerateBody(@NotNull ExpressionCodegen codegen, @NotNull JvmMethodSignature signature) { @@ -1443,9 +1443,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { int flags = ACC_PUBLIC; // TODO. - TraitImplDelegateInfo delegateInfo = getTraitImplDelegateInfo(fun); - Method methodToGenerate = delegateInfo.methodToGenerate; - Method methodInTrait = delegateInfo.methodInTrait; + Method methodToGenerate = typeMapper.mapSignature(fun).getAsmMethod(); + Method methodInTrait = typeMapper.mapSignature(fun.getOriginal()).getAsmMethod(); PsiElement origin = descriptorToDeclaration(bindingContext, fun); MethodVisitor mv = v.newMethod(origin, flags, methodToGenerate.getName(), methodToGenerate.getDescriptor(), null, null); @@ -1483,44 +1482,6 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { FunctionCodegen.generateBridgeIfNeeded(context, state, v, methodToGenerate, fun); } - private static class TraitImplDelegateInfo { - private final Method methodToGenerate; - private final Method methodInTrait; - - private TraitImplDelegateInfo(@NotNull Method methodToGenerate, @NotNull Method methodInTrait) { - this.methodToGenerate = methodToGenerate; - this.methodInTrait = methodInTrait; - } - } - - @NotNull - private TraitImplDelegateInfo getTraitImplDelegateInfo(@NotNull FunctionDescriptor fun) { - if (fun instanceof PropertyAccessorDescriptor) { - PropertyDescriptor property = ((PropertyAccessorDescriptor) fun).getCorrespondingProperty(); - PropertyDescriptor original = property.getOriginal(); - if (fun instanceof PropertyGetterDescriptor) { - JvmMethodSignature toGenerate = typeMapper.mapGetterSignature(property, OwnerKind.IMPLEMENTATION); - JvmMethodSignature inTrait = typeMapper.mapGetterSignature(original, OwnerKind.IMPLEMENTATION); - return new TraitImplDelegateInfo( - toGenerate.getAsmMethod(), inTrait.getAsmMethod()); - } - else if (fun instanceof PropertySetterDescriptor) { - JvmMethodSignature toGenerate = typeMapper.mapSetterSignature(property, OwnerKind.IMPLEMENTATION); - JvmMethodSignature inTrait = typeMapper.mapSetterSignature(original, OwnerKind.IMPLEMENTATION); - return new TraitImplDelegateInfo( - toGenerate.getAsmMethod(), inTrait.getAsmMethod()); - } - else { - throw new IllegalStateException("Accessor is neither getter, nor setter, what is it? " + fun); - } - } - else { - Method function = typeMapper.mapSignature(fun).getAsmMethod(); - Method functionOriginal = typeMapper.mapSignature(fun.getOriginal()).getAsmMethod(); - return new TraitImplDelegateInfo(function, functionOriginal); - } - } - private void generateDelegatorToConstructorCall( InstructionAdapter iv, ExpressionCodegen codegen, ConstructorDescriptor constructorDescriptor diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java index addc6bcf5bf..86b65004341 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java @@ -253,9 +253,9 @@ public class PropertyCodegen extends GenerationStateAware { //TODO: Now it's not enough information to properly resolve property from bytecode without generated getter and setter //if (!defaultGetter || isExternallyAccessible(propertyDescriptor)) { - JvmMethodSignature signature = typeMapper.mapGetterSignature(propertyDescriptor, kind); PropertyGetterDescriptor getterDescriptor = propertyDescriptor.getGetter(); getterDescriptor = getterDescriptor != null ? getterDescriptor : DescriptorFactory.createDefaultGetter(propertyDescriptor); + JvmMethodSignature signature = typeMapper.mapSignature(getterDescriptor, kind); if (kind != OwnerKind.TRAIT_IMPL || !defaultGetter) { FunctionGenerationStrategy strategy; @@ -283,10 +283,9 @@ public class PropertyCodegen extends GenerationStateAware { //TODO: Now it's not enough information to properly resolve property from bytecode without generated getter and setter if (/*!defaultSetter || isExternallyAccessible(propertyDescriptor) &&*/ propertyDescriptor.isVar()) { - JvmMethodSignature signature = typeMapper.mapSetterSignature(propertyDescriptor, kind); PropertySetterDescriptor setterDescriptor = propertyDescriptor.getSetter(); - setterDescriptor = - setterDescriptor != null ? setterDescriptor : DescriptorFactory.createDefaultSetter(propertyDescriptor); + setterDescriptor = setterDescriptor != null ? setterDescriptor : DescriptorFactory.createDefaultSetter(propertyDescriptor); + JvmMethodSignature signature = typeMapper.mapSignature(setterDescriptor, kind); if (kind != OwnerKind.TRAIT_IMPL || !defaultSetter) { FunctionGenerationStrategy strategy; @@ -405,17 +404,21 @@ public class PropertyCodegen extends GenerationStateAware { return JvmAbi.SETTER_PREFIX + StringUtil.capitalizeWithJavaBeanConvention(propertyName.asString()); } - public void genDelegate(PropertyDescriptor delegate, PropertyDescriptor overridden, StackValue field) { + public void genDelegate(@NotNull PropertyDescriptor delegate, @NotNull PropertyDescriptor overridden, @NotNull StackValue field) { ClassDescriptor toClass = (ClassDescriptor) overridden.getContainingDeclaration(); - functionCodegen.genDelegate(delegate.getGetter(), toClass, field, - typeMapper.mapGetterSignature(delegate, OwnerKind.IMPLEMENTATION), - typeMapper.mapGetterSignature(overridden.getOriginal(), OwnerKind.IMPLEMENTATION)); + PropertyGetterDescriptor getter = delegate.getGetter(); + if (getter != null) { + //noinspection ConstantConditions + functionCodegen.genDelegate(getter, toClass, field, + typeMapper.mapSignature(getter), typeMapper.mapSignature(overridden.getGetter().getOriginal())); + } - if (delegate.isVar()) { - functionCodegen.genDelegate(delegate.getSetter(), toClass, field, - typeMapper.mapSetterSignature(delegate, OwnerKind.IMPLEMENTATION), - typeMapper.mapSetterSignature(overridden.getOriginal(), OwnerKind.IMPLEMENTATION)); + PropertySetterDescriptor setter = delegate.getSetter(); + if (setter != null) { + //noinspection ConstantConditions + functionCodegen.genDelegate(setter, toClass, field, + typeMapper.mapSignature(setter), typeMapper.mapSignature(overridden.getSetter().getOriginal())); } } } 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 b5a93d97245..1fb6b380986 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/state/JetTypeMapper.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/state/JetTypeMapper.java @@ -55,6 +55,7 @@ import static org.jetbrains.jet.codegen.AsmUtil.getTraitImplThisParameterType; import static org.jetbrains.jet.codegen.CodegenUtil.*; import static org.jetbrains.jet.codegen.FunctionTypesUtil.getFunctionTraitClassName; import static org.jetbrains.jet.codegen.binding.CodegenBinding.*; +import static org.jetbrains.jet.lang.resolve.DescriptorUtils.isAnnotationClass; import static org.jetbrains.jet.lang.resolve.DescriptorUtils.isAnonymousObject; import static org.jetbrains.jet.lang.resolve.java.descriptor.JavaPackageFragmentDescriptor.Kind.CLASS_STATICS; @@ -547,8 +548,17 @@ public class JetTypeMapper extends BindingTraceAware { @NotNull private static String mapFunctionName(@NotNull FunctionDescriptor descriptor) { if (descriptor instanceof PropertyAccessorDescriptor) { - return getPropertyAccessorName(((PropertyAccessorDescriptor) descriptor).getCorrespondingProperty(), - descriptor instanceof PropertyGetterDescriptor); + PropertyDescriptor property = ((PropertyAccessorDescriptor) descriptor).getCorrespondingProperty(); + if (isAnnotationClass(property.getContainingDeclaration())) { + return property.getName().asString(); + } + + if (descriptor instanceof PropertyGetterDescriptor) { + return PropertyCodegen.getterName(property.getName()); + } + else { + return PropertyCodegen.setterName(property.getName()); + } } else if (isLocalNamedFun(descriptor) || descriptor instanceof AnonymousFunctionDescriptor || @@ -583,7 +593,12 @@ public class JetTypeMapper extends BindingTraceAware { writeVoidReturn(sw); } else { - writeFormalTypeParameters(f.getTypeParameters(), sw); + if (f instanceof PropertyAccessorDescriptor) { + writeFormalTypeParameters(((PropertyAccessorDescriptor) f).getCorrespondingProperty().getTypeParameters(), sw); + } + else { + writeFormalTypeParameters(f.getTypeParameters(), sw); + } sw.writeParametersStart(); writeThisIfNeeded(f, kind, sw); @@ -596,7 +611,12 @@ public class JetTypeMapper extends BindingTraceAware { sw.writeReturnType(); JetType returnType = f.getReturnType(); assert returnType != null : "Function " + f + " has no return type"; - mapReturnType(returnType, sw); + if (f instanceof PropertyGetterDescriptor) { + mapType(returnType, sw, JetTypeMapperMode.VALUE, Variance.OUT_VARIANCE, false); + } + else { + mapReturnType(returnType, sw); + } sw.writeReturnTypeEnd(); } @@ -629,13 +649,7 @@ public class JetTypeMapper extends BindingTraceAware { signatureVisitor.writeAsmType(type); signatureVisitor.writeParameterTypeEnd(); } - else { - writeThisForAccessorIfNeeded(descriptor, signatureVisitor); - } - } - - private void writeThisForAccessorIfNeeded(@NotNull CallableMemberDescriptor descriptor, @NotNull BothSignatureWriter signatureVisitor) { - if (isAccessor(descriptor) && descriptor.getExpectedThisObject() != null) { + else if (isAccessor(descriptor) && descriptor.getExpectedThisObject() != null) { signatureVisitor.writeParameterType(JvmMethodParameterKind.THIS); mapType(((ClassifierDescriptor) descriptor.getContainingDeclaration()).getDefaultType(), signatureVisitor, JetTypeMapperMode.VALUE); signatureVisitor.writeParameterTypeEnd(); @@ -698,53 +712,6 @@ public class JetTypeMapper extends BindingTraceAware { } } - @NotNull - public static String getPropertyAccessorName(@NotNull PropertyDescriptor descriptor, boolean isGetter) { - DeclarationDescriptor parentDescriptor = descriptor.getContainingDeclaration(); - boolean isAnnotation = parentDescriptor instanceof ClassDescriptor && - ((ClassDescriptor) parentDescriptor).getKind() == ClassKind.ANNOTATION_CLASS; - return isAnnotation ? descriptor.getName().asString() : - isGetter ? PropertyCodegen.getterName(descriptor.getName()) : PropertyCodegen.setterName(descriptor.getName()); - } - - @NotNull - public JvmMethodSignature mapGetterSignature(PropertyDescriptor descriptor, OwnerKind kind) { - BothSignatureWriter signatureWriter = new BothSignatureWriter(BothSignatureWriter.Mode.METHOD); - - writeFormalTypeParameters(descriptor.getTypeParameters(), signatureWriter); - - signatureWriter.writeParametersStart(); - writeThisIfNeeded(descriptor, kind, signatureWriter); - writeReceiverIfNeeded(descriptor.getReceiverParameter(), signatureWriter); - - signatureWriter.writeReturnType(); - mapType(descriptor.getType(), signatureWriter, JetTypeMapperMode.VALUE, Variance.OUT_VARIANCE, false); - signatureWriter.writeReturnTypeEnd(); - - String name = getPropertyAccessorName(descriptor, true); - return signatureWriter.makeJvmMethodSignature(name); - } - - - @NotNull - public JvmMethodSignature mapSetterSignature(PropertyDescriptor descriptor, OwnerKind kind) { - assert descriptor.isVar(); - - BothSignatureWriter signatureWriter = new BothSignatureWriter(BothSignatureWriter.Mode.METHOD); - - writeFormalTypeParameters(descriptor.getTypeParameters(), signatureWriter); - - signatureWriter.writeParametersStart(); - writeThisIfNeeded(descriptor, kind, signatureWriter); - writeReceiverIfNeeded(descriptor.getReceiverParameter(), signatureWriter); - writeParameter(signatureWriter, descriptor.getType()); - - writeVoidReturn(signatureWriter); - - String name = getPropertyAccessorName(descriptor, false); - return signatureWriter.makeJvmMethodSignature(name); - } - private void writeParameter(@NotNull BothSignatureWriter signatureWriter, @NotNull JetType outType) { signatureWriter.writeParameterType(JvmMethodParameterKind.VALUE); mapType(outType, signatureWriter, JetTypeMapperMode.VALUE); diff --git a/compiler/testData/compileJavaAgainstKotlin/property/GenericProperty.java b/compiler/testData/compileJavaAgainstKotlin/property/GenericProperty.java new file mode 100644 index 00000000000..291a89d013c --- /dev/null +++ b/compiler/testData/compileJavaAgainstKotlin/property/GenericProperty.java @@ -0,0 +1,5 @@ +class GenericProperty { + void foo() { + java.util.Map o = a.APackage.getTest(); + } +} diff --git a/compiler/testData/compileJavaAgainstKotlin/property/GenericProperty.kt b/compiler/testData/compileJavaAgainstKotlin/property/GenericProperty.kt new file mode 100644 index 00000000000..c4aa8df6527 --- /dev/null +++ b/compiler/testData/compileJavaAgainstKotlin/property/GenericProperty.kt @@ -0,0 +1,6 @@ +// Tests that type variables of properties are written to the getter signature + +package a + +val test: Map + get() = java.util.HashMap() diff --git a/compiler/tests/org/jetbrains/jet/jvm/compiler/CompileJavaAgainstKotlinTestGenerated.java b/compiler/tests/org/jetbrains/jet/jvm/compiler/CompileJavaAgainstKotlinTestGenerated.java index 0abc1143e14..2f1757ef9a0 100644 --- a/compiler/tests/org/jetbrains/jet/jvm/compiler/CompileJavaAgainstKotlinTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/jvm/compiler/CompileJavaAgainstKotlinTestGenerated.java @@ -31,7 +31,7 @@ import org.jetbrains.jet.jvm.compiler.AbstractCompileJavaAgainstKotlinTest; /** This class is generated by {@link org.jetbrains.jet.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */ @SuppressWarnings("all") @TestMetadata("compiler/testData/compileJavaAgainstKotlin") -@InnerTestClasses({CompileJavaAgainstKotlinTestGenerated.Class.class, CompileJavaAgainstKotlinTestGenerated.Method.class, CompileJavaAgainstKotlinTestGenerated.StaticFields.class}) +@InnerTestClasses({CompileJavaAgainstKotlinTestGenerated.Class.class, CompileJavaAgainstKotlinTestGenerated.Method.class, CompileJavaAgainstKotlinTestGenerated.Property.class, CompileJavaAgainstKotlinTestGenerated.StaticFields.class}) public class CompileJavaAgainstKotlinTestGenerated extends AbstractCompileJavaAgainstKotlinTest { public void testAllFilesPresentInCompileJavaAgainstKotlin() throws Exception { JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("compiler/testData/compileJavaAgainstKotlin"), Pattern.compile("^(.+)\\.kt$"), true); @@ -188,6 +188,19 @@ public class CompileJavaAgainstKotlinTestGenerated extends AbstractCompileJavaAg } + @TestMetadata("compiler/testData/compileJavaAgainstKotlin/property") + public static class Property extends AbstractCompileJavaAgainstKotlinTest { + public void testAllFilesPresentInProperty() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("compiler/testData/compileJavaAgainstKotlin/property"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("GenericProperty.kt") + public void testGenericProperty() throws Exception { + doTest("compiler/testData/compileJavaAgainstKotlin/property/GenericProperty.kt"); + } + + } + @TestMetadata("compiler/testData/compileJavaAgainstKotlin/staticFields") public static class StaticFields extends AbstractCompileJavaAgainstKotlinTest { public void testAllFilesPresentInStaticFields() throws Exception { @@ -226,6 +239,7 @@ public class CompileJavaAgainstKotlinTestGenerated extends AbstractCompileJavaAg suite.addTestSuite(CompileJavaAgainstKotlinTestGenerated.class); suite.addTestSuite(Class.class); suite.addTestSuite(Method.class); + suite.addTestSuite(Property.class); suite.addTestSuite(StaticFields.class); return suite; }