From ad6837883675a671231bf0b6ae9f74742dcef185 Mon Sep 17 00:00:00 2001 From: Denis Zharkov Date: Thu, 8 Oct 2015 14:19:01 +0300 Subject: [PATCH] Support loading methods from Java as common properties overrides --- .../synthetic/JavaSyntheticPropertiesScope.kt | 22 +-- .../properties/commonProperties/J.java | 24 ++++ .../commonProperties/commonProperties.kt | 37 +++++ .../tests/j+k/properties/interface.kt | 32 +++++ .../tests/j+k/properties/interface.txt | 40 ++++++ .../tests/j+k/properties/isName.kt | 27 ++++ .../tests/j+k/properties/isName.txt | 41 ++++++ .../diagnostics/tests/j+k/properties/val.kt | 25 ++++ .../diagnostics/tests/j+k/properties/val.txt | 41 ++++++ .../diagnostics/tests/j+k/properties/var.kt | 42 ++++++ .../diagnostics/tests/j+k/properties/var.txt | 59 ++++++++ .../customClassMutableCollection.txt | 2 +- .../customClassMutableList.txt | 2 +- .../invalidFqName.txt | 2 +- .../wrongTypeParametersCount.txt | 2 +- .../checkers/JetDiagnosticsTestGenerated.java | 33 +++++ .../BlackBoxWithJavaCodegenTestGenerated.java | 6 + .../load/java/FieldOverridabilityCondition.kt | 5 +- .../load/java/builtinsPropertiesUtil.kt | 30 ++-- .../descriptors/JavaPropertyDescriptor.java | 13 +- .../lazy/descriptors/JavaDescriptorUtil.kt | 24 ++++ .../descriptors/LazyJavaClassMemberScope.kt | 135 +++++++++++++----- .../load/java/propertiesConventionUtil.kt | 47 ++++++ .../kotlin/resolve/DescriptorFactory.java | 23 ++- .../internal/KFunctionFromReferenceImpl.kt | 4 +- 25 files changed, 628 insertions(+), 90 deletions(-) create mode 100644 compiler/testData/codegen/boxWithJava/properties/commonProperties/J.java create mode 100644 compiler/testData/codegen/boxWithJava/properties/commonProperties/commonProperties.kt create mode 100644 compiler/testData/diagnostics/tests/j+k/properties/interface.kt create mode 100644 compiler/testData/diagnostics/tests/j+k/properties/interface.txt create mode 100644 compiler/testData/diagnostics/tests/j+k/properties/isName.kt create mode 100644 compiler/testData/diagnostics/tests/j+k/properties/isName.txt create mode 100644 compiler/testData/diagnostics/tests/j+k/properties/val.kt create mode 100644 compiler/testData/diagnostics/tests/j+k/properties/val.txt create mode 100644 compiler/testData/diagnostics/tests/j+k/properties/var.kt create mode 100644 compiler/testData/diagnostics/tests/j+k/properties/var.txt create mode 100644 core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/JavaDescriptorUtil.kt create mode 100644 core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/propertiesConventionUtil.kt diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/synthetic/JavaSyntheticPropertiesScope.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/synthetic/JavaSyntheticPropertiesScope.kt index 0abe34cbc9f..58b266e3149 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/synthetic/JavaSyntheticPropertiesScope.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/synthetic/JavaSyntheticPropertiesScope.kt @@ -62,28 +62,10 @@ interface SyntheticJavaPropertyDescriptor : PropertyDescriptor { } fun propertyNameByGetMethodName(methodName: Name): Name? - = propertyNameFromAccessorMethodName(methodName, "get") ?: propertyNameFromAccessorMethodName(methodName, "is", removePrefix = false) + = org.jetbrains.kotlin.load.java.propertyNameByGetMethodName(methodName) fun propertyNameBySetMethodName(methodName: Name, withIsPrefix: Boolean): Name? - = propertyNameFromAccessorMethodName(methodName, "set", addPrefix = if (withIsPrefix) "is" else null) - - private fun propertyNameFromAccessorMethodName(methodName: Name, prefix: String, removePrefix: Boolean = true, addPrefix: String? = null): Name? { - if (methodName.isSpecial()) return null - val identifier = methodName.getIdentifier() - if (!identifier.startsWith(prefix)) return null - if (identifier.length() == prefix.length()) return null - if (identifier[prefix.length()] in 'a'..'z') return null - - if (addPrefix != null) { - assert(removePrefix) - return Name.identifier(addPrefix + identifier.removePrefix(prefix)) - } - - if (!removePrefix) return methodName - val name = identifier.removePrefix(prefix).decapitalizeSmart(asciiOnly = true) - if (!Name.isValidIdentifier(name)) return null - return Name.identifier(name) - } + = org.jetbrains.kotlin.load.java.propertyNameBySetMethodName(methodName, withIsPrefix) } } diff --git a/compiler/testData/codegen/boxWithJava/properties/commonProperties/J.java b/compiler/testData/codegen/boxWithJava/properties/commonProperties/J.java new file mode 100644 index 00000000000..675f3fc9cb3 --- /dev/null +++ b/compiler/testData/codegen/boxWithJava/properties/commonProperties/J.java @@ -0,0 +1,24 @@ +public class J extends A { + + public boolean okField = false; + + public int getValProp() { + return 123; + } + + public int getVarProp() { + return 456; + } + + public void setVarProp(int x) { + okField = true; + } + + public int isProp() { + return 789; + } + + public void setProp(int x) { + okField = true; + } +} diff --git a/compiler/testData/codegen/boxWithJava/properties/commonProperties/commonProperties.kt b/compiler/testData/codegen/boxWithJava/properties/commonProperties/commonProperties.kt new file mode 100644 index 00000000000..b2ea7cddc25 --- /dev/null +++ b/compiler/testData/codegen/boxWithJava/properties/commonProperties/commonProperties.kt @@ -0,0 +1,37 @@ +open class A { + open val valProp: Int = -1 + open var varProp: Int = -1 + open var isProp: Int = -1 +} + +fun box(): String { + val j = J() + val a: A = j + + if (j.valProp != 123) return "fail 1" + if (a.valProp != 123) return "fail 2" + + j.varProp = -1 + if (!j.okField) return "fail 3" + j.okField = false + + a.varProp = -1 + if (!j.okField) return "fail 4" + j.okField = false + + if (j.varProp != 456) return "fail 5" + if (a.varProp != 456) return "fail 6" + + j.isProp = -1 + if (!j.okField) return "fail 7" + j.okField = false + + a.isProp = -1 + if (!j.okField) return "fail 8" + j.okField = false + + if (j.isProp != 789) return "fail 9" + if (a.isProp != 789) return "fail 10" + + return "OK" +} diff --git a/compiler/testData/diagnostics/tests/j+k/properties/interface.kt b/compiler/testData/diagnostics/tests/j+k/properties/interface.kt new file mode 100644 index 00000000000..7c3c81e57f5 --- /dev/null +++ b/compiler/testData/diagnostics/tests/j+k/properties/interface.kt @@ -0,0 +1,32 @@ +// FILE: A.java + +public interface A extends B { + public int getFoo(); + public void setFoo(int x); +} + +// FILE: BImpl.java + +public class BImpl implements B { + public int getFoo() {} + public void setFoo(int x) {} +} + +// FILE: main.kt + +interface B { + var foo: Int +} + +interface C1 : A { + override var foo: Int +} + +class D : C1, BImpl() + +fun foo() { + BImpl().foo = BImpl().foo + 1 + D().foo = D().foo + 2 +} + + diff --git a/compiler/testData/diagnostics/tests/j+k/properties/interface.txt b/compiler/testData/diagnostics/tests/j+k/properties/interface.txt new file mode 100644 index 00000000000..bc9c8efb9c2 --- /dev/null +++ b/compiler/testData/diagnostics/tests/j+k/properties/interface.txt @@ -0,0 +1,40 @@ +package + +public fun foo(): kotlin.Unit + +public interface A : B { + public abstract override /*1*/ var foo: kotlin.Int + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public interface B { + public abstract var foo: kotlin.Int + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public open class BImpl : B { + public constructor BImpl() + public open override /*1*/ var foo: kotlin.Int + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public interface C1 : A { + public abstract override /*1*/ var foo: kotlin.Int + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final class D : C1, BImpl { + public constructor D() + public open override /*2*/ /*fake_override*/ var foo: kotlin.Int + public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/testData/diagnostics/tests/j+k/properties/isName.kt b/compiler/testData/diagnostics/tests/j+k/properties/isName.kt new file mode 100644 index 00000000000..e990adaad05 --- /dev/null +++ b/compiler/testData/diagnostics/tests/j+k/properties/isName.kt @@ -0,0 +1,27 @@ +// FILE: A.java + +public class A extends B { + public int isFoo() { return 0; } + public void setFoo(int x) {} +} + +// FILE: F.java + +public class F extends B { + public final int isFoo() { return 0; } + public final void setFoo(int x) {} +} + +// FILE: main.kt + +open class B { + open var isFoo: Int = 1 +} + +class C1 : A() { + override var isFoo: Int = 2 +} + +class C2 : F() { + override var isFoo: Int = 3 +} diff --git a/compiler/testData/diagnostics/tests/j+k/properties/isName.txt b/compiler/testData/diagnostics/tests/j+k/properties/isName.txt new file mode 100644 index 00000000000..d59b57b4853 --- /dev/null +++ b/compiler/testData/diagnostics/tests/j+k/properties/isName.txt @@ -0,0 +1,41 @@ +package + +public open class A : B { + public constructor A() + public open override /*1*/ var isFoo: kotlin.Int + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public open class B { + public constructor B() + public open var isFoo: kotlin.Int + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final class C1 : A { + public constructor C1() + public open override /*1*/ var isFoo: kotlin.Int + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final class C2 : F { + public constructor C2() + public open override /*1*/ var isFoo: kotlin.Int + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public open class F : B { + public constructor F() + public final override /*1*/ var isFoo: kotlin.Int + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/testData/diagnostics/tests/j+k/properties/val.kt b/compiler/testData/diagnostics/tests/j+k/properties/val.kt new file mode 100644 index 00000000000..16d31136602 --- /dev/null +++ b/compiler/testData/diagnostics/tests/j+k/properties/val.kt @@ -0,0 +1,25 @@ +// FILE: A.java + +public class A extends B { + public int getFoo() { return 0; } +} + +// FILE: F.java + +public class F extends B { + public final int getFoo() { return 0; } +} + +// FILE: main.kt + +open class B { + open val foo: Int = 1 +} + +class C1 : A() { + override val foo: Int = 2 +} + +class C2 : F() { + override val foo: Int = 3 +} diff --git a/compiler/testData/diagnostics/tests/j+k/properties/val.txt b/compiler/testData/diagnostics/tests/j+k/properties/val.txt new file mode 100644 index 00000000000..9b3b67a9640 --- /dev/null +++ b/compiler/testData/diagnostics/tests/j+k/properties/val.txt @@ -0,0 +1,41 @@ +package + +public open class A : B { + public constructor A() + public open override /*1*/ val foo: kotlin.Int + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public open class B { + public constructor B() + public open val foo: kotlin.Int = 1 + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final class C1 : A { + public constructor C1() + public open override /*1*/ val foo: kotlin.Int = 2 + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final class C2 : F { + public constructor C2() + public open override /*1*/ val foo: kotlin.Int = 3 + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public open class F : B { + public constructor F() + public final override /*1*/ val foo: kotlin.Int + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/testData/diagnostics/tests/j+k/properties/var.kt b/compiler/testData/diagnostics/tests/j+k/properties/var.kt new file mode 100644 index 00000000000..df5441b39b8 --- /dev/null +++ b/compiler/testData/diagnostics/tests/j+k/properties/var.kt @@ -0,0 +1,42 @@ +// FILE: A.java + +public class A extends B { + public int getFoo() { return 0; } + public void setFoo(int x) {} +} + +// FILE: F.java + +public class F extends B { + public final int getFoo() { return 0; } + public final void setFoo(int x) {} +} + +// FILE: ConflictingModality.java + +public class ConflictingModality extends B { + public final int getFoo() { return 0; } + public abstract void setFoo(int x) {} +} + +// FILE: ConflictingVisibility.java + +public class ConflictingVisibility extends B { + public int getFoo() { return 0; } + protected void setFoo(int x) {} +} + +// FILE: main.kt + +open class B { + // check that final is not overridden + open protected var foo: Int = 1 +} + +class C1 : A() { + override var foo: Int = 2 +} + +class C2 : F() { + override var foo: Int = 3 +} diff --git a/compiler/testData/diagnostics/tests/j+k/properties/var.txt b/compiler/testData/diagnostics/tests/j+k/properties/var.txt new file mode 100644 index 00000000000..4dc7c742b92 --- /dev/null +++ b/compiler/testData/diagnostics/tests/j+k/properties/var.txt @@ -0,0 +1,59 @@ +package + +public open class A : B { + public constructor A() + public open override /*1*/ var foo: kotlin.Int + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public open class B { + public constructor B() + protected open var foo: kotlin.Int + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final class C1 : A { + public constructor C1() + public open override /*1*/ var foo: kotlin.Int + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final class C2 : F { + public constructor C2() + public open override /*1*/ var foo: kotlin.Int + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public open class ConflictingModality : B { + public constructor ConflictingModality() + protected open override /*1*/ /*fake_override*/ var foo: kotlin.Int + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public final fun getFoo(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public abstract fun setFoo(/*0*/ x: kotlin.Int): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public open class ConflictingVisibility : B { + public constructor ConflictingVisibility() + public open override /*1*/ var foo: kotlin.Int + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public open class F : B { + public constructor F() + public final override /*1*/ var foo: kotlin.Int + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/testData/diagnostics/testsWithStdLib/purelyImplementedCollection/customClassMutableCollection.txt b/compiler/testData/diagnostics/testsWithStdLib/purelyImplementedCollection/customClassMutableCollection.txt index 27b5657da54..9c989387fae 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/purelyImplementedCollection/customClassMutableCollection.txt +++ b/compiler/testData/diagnostics/testsWithStdLib/purelyImplementedCollection/customClassMutableCollection.txt @@ -5,7 +5,7 @@ public fun foo(): kotlin.Unit @kotlin.jvm.PurelyImplements(value = "kotlin.MutableCollection") public/*package*/ open class A : java.util.AbstractCollection, kotlin.MutableCollection { public/*package*/ constructor A() - @java.lang.Override() public open override /*2*/ val size: kotlin.Int + public open override /*2*/ val size: kotlin.Int public open override /*2*/ /*fake_override*/ fun add(/*0*/ e: T): kotlin.Boolean public open override /*2*/ /*fake_override*/ fun addAll(/*0*/ c: kotlin.Collection): kotlin.Boolean public open override /*2*/ /*fake_override*/ fun clear(): kotlin.Unit diff --git a/compiler/testData/diagnostics/testsWithStdLib/purelyImplementedCollection/customClassMutableList.txt b/compiler/testData/diagnostics/testsWithStdLib/purelyImplementedCollection/customClassMutableList.txt index fc225ba93ef..f4fd781f3db 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/purelyImplementedCollection/customClassMutableList.txt +++ b/compiler/testData/diagnostics/testsWithStdLib/purelyImplementedCollection/customClassMutableList.txt @@ -6,7 +6,7 @@ public fun foo(): kotlin.Unit @kotlin.jvm.PurelyImplements(value = "kotlin.MutableList") public/*package*/ open class A : java.util.AbstractList, kotlin.MutableList { public/*package*/ constructor A() protected/*protected and package*/ final override /*1*/ /*fake_override*/ var modCount: kotlin.Int - @java.lang.Override() public open override /*2*/ val size: kotlin.Int + public open override /*2*/ val size: kotlin.Int public open override /*2*/ /*fake_override*/ fun add(/*0*/ e: T): kotlin.Boolean public open override /*2*/ /*fake_override*/ fun add(/*0*/ index: kotlin.Int, /*1*/ element: T): kotlin.Unit public open override /*2*/ /*fake_override*/ fun addAll(/*0*/ c: kotlin.Collection): kotlin.Boolean diff --git a/compiler/testData/diagnostics/testsWithStdLib/purelyImplementedCollection/invalidFqName.txt b/compiler/testData/diagnostics/testsWithStdLib/purelyImplementedCollection/invalidFqName.txt index 57937b5375e..d13ffb77cf1 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/purelyImplementedCollection/invalidFqName.txt +++ b/compiler/testData/diagnostics/testsWithStdLib/purelyImplementedCollection/invalidFqName.txt @@ -6,7 +6,7 @@ public val y: B @kotlin.jvm.PurelyImplements(value = "") public open class A : java.util.AbstractList { public constructor A() protected/*protected and package*/ final override /*1*/ /*fake_override*/ var modCount: kotlin.Int - @java.lang.Override() public open override /*1*/ val size: kotlin.Int + public open override /*1*/ val size: kotlin.Int public open override /*1*/ /*fake_override*/ fun add(/*0*/ e: T!): kotlin.Boolean public open override /*1*/ /*fake_override*/ fun add(/*0*/ index: kotlin.Int, /*1*/ element: T!): kotlin.Unit public open override /*1*/ /*fake_override*/ fun addAll(/*0*/ c: kotlin.Collection): kotlin.Boolean diff --git a/compiler/testData/diagnostics/testsWithStdLib/purelyImplementedCollection/wrongTypeParametersCount.txt b/compiler/testData/diagnostics/testsWithStdLib/purelyImplementedCollection/wrongTypeParametersCount.txt index f4f35405f7d..fee19e9a763 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/purelyImplementedCollection/wrongTypeParametersCount.txt +++ b/compiler/testData/diagnostics/testsWithStdLib/purelyImplementedCollection/wrongTypeParametersCount.txt @@ -6,7 +6,7 @@ public fun foo(): kotlin.Unit @kotlin.jvm.PurelyImplements(value = "kotlin.MutableList") public/*package*/ open class A : java.util.AbstractList { public/*package*/ constructor A() protected/*protected and package*/ final override /*1*/ /*fake_override*/ var modCount: kotlin.Int - @java.lang.Override() public open override /*1*/ val size: kotlin.Int + public open override /*1*/ val size: kotlin.Int public open override /*1*/ /*fake_override*/ fun add(/*0*/ e: T!): kotlin.Boolean public open override /*1*/ /*fake_override*/ fun add(/*0*/ index: kotlin.Int, /*1*/ element: T!): kotlin.Unit public open override /*1*/ /*fake_override*/ fun addAll(/*0*/ c: kotlin.Collection): kotlin.Boolean diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java index 2d2db52c52f..988140e48c3 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java @@ -9087,6 +9087,39 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest { } } + @TestMetadata("compiler/testData/diagnostics/tests/j+k/properties") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Properties extends AbstractJetDiagnosticsTest { + public void testAllFilesPresentInProperties() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/tests/j+k/properties"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("interface.kt") + public void testInterface() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/j+k/properties/interface.kt"); + doTest(fileName); + } + + @TestMetadata("isName.kt") + public void testIsName() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/j+k/properties/isName.kt"); + doTest(fileName); + } + + @TestMetadata("val.kt") + public void testVal() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/j+k/properties/val.kt"); + doTest(fileName); + } + + @TestMetadata("var.kt") + public void testVar() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/j+k/properties/var.kt"); + doTest(fileName); + } + } + @TestMetadata("compiler/testData/diagnostics/tests/j+k/types") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxWithJavaCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxWithJavaCodegenTestGenerated.java index e1830d27b5e..a58bba23eb1 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxWithJavaCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxWithJavaCodegenTestGenerated.java @@ -359,6 +359,12 @@ public class BlackBoxWithJavaCodegenTestGenerated extends AbstractBlackBoxCodege doTestWithJava(fileName); } + @TestMetadata("commonProperties") + public void testCommonProperties() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithJava/properties/commonProperties/"); + doTestWithJava(fileName); + } + @TestMetadata("substituteJavaSuperField") public void testSubstituteJavaSuperField() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithJava/properties/substituteJavaSuperField/"); diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/FieldOverridabilityCondition.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/FieldOverridabilityCondition.kt index 34638f58832..fabe36efff7 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/FieldOverridabilityCondition.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/FieldOverridabilityCondition.kt @@ -18,6 +18,7 @@ package org.jetbrains.kotlin.load.java import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.descriptors.PropertyDescriptor +import org.jetbrains.kotlin.load.java.lazy.descriptors.isJavaField import org.jetbrains.kotlin.resolve.ExternalOverridabilityCondition class FieldOverridabilityCondition : ExternalOverridabilityCondition { @@ -26,8 +27,4 @@ class FieldOverridabilityCondition : ExternalOverridabilityCondition { return subDescriptor.isJavaField == superDescriptor.isJavaField } - - // Currently getter is null iff it's loaded from Java field - private val PropertyDescriptor.isJavaField: Boolean - get() = getter == null } diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/builtinsPropertiesUtil.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/builtinsPropertiesUtil.kt index 902ac655526..672b2ac1345 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/builtinsPropertiesUtil.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/builtinsPropertiesUtil.kt @@ -26,7 +26,6 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe import org.jetbrains.kotlin.resolve.descriptorUtil.module import org.jetbrains.kotlin.utils.DFS import org.jetbrains.kotlin.utils.addToStdlib.check -import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult private val BUILTIN_SPECIAL_PROPERTIES_FQ_NAMES = setOf(FqName("kotlin.Collection.size"), FqName("kotlin.Map.size")) private val BUILTIN_SPECIAL_PROPERTIES_SHORT_NAMES = BUILTIN_SPECIAL_PROPERTIES_FQ_NAMES.map { it.shortName() }.toSet() @@ -61,35 +60,26 @@ private fun CallableDescriptor.fqNameOrNull(): FqName? = fqNameUnsafe.check { it val Name.isBuiltinSpecialPropertyName: Boolean get() = this in BUILTIN_SPECIAL_PROPERTIES_SHORT_NAMES -private val CallableDescriptor.builtinSpecialPropertyAccessorName: String? - get() = when(this) { - is PropertyAccessorDescriptor -> correspondingProperty.check { it.hasBuiltinSpecialPropertyFqName() }?.name?.asString() - else -> null - } +public val CallableMemberDescriptor.builtinSpecialPropertyAccessorName: String? + get() = propertyIfAccessor.check { it.hasBuiltinSpecialPropertyFqName() }?.name?.asString() @Suppress("UNCHECKED_CAST") -val T.builtinSpecialOverridden: T? get() { - return when (this) { - is PropertyAccessorDescriptor -> check { correspondingProperty.hasBuiltinSpecialPropertyFqName() } - ?: overriddenDescriptors.firstNotNullResult { it.builtinSpecialOverridden } as T? - is PropertyDescriptor -> check { hasBuiltinSpecialPropertyFqName() } - ?: overriddenDescriptors.firstNotNullResult { it.builtinSpecialOverridden } as T? - else -> null - } +val T.builtinSpecialOverridden: T? get() { + return firstOverridden { it.propertyIfAccessor.hasBuiltinSpecialPropertyFqName() } as T? } -fun CallableDescriptor.overridesBuiltinSpecialDeclaration(): Boolean = builtinSpecialOverridden != null +fun CallableMemberDescriptor.overridesBuiltinSpecialDeclaration(): Boolean = builtinSpecialOverridden != null -public val CallableDescriptor.jvmMethodNameIfSpecial: String? +public val CallableMemberDescriptor.jvmMethodNameIfSpecial: String? get() = builtinOverriddenThatAffectsJvmName?.builtinSpecialPropertyAccessorName -public val CallableDescriptor.builtinOverriddenThatAffectsJvmName: CallableDescriptor? - get() = if (hasBuiltinSpecialPropertyFqName() || isFromJava) builtinSpecialOverridden else null +private val CallableMemberDescriptor.builtinOverriddenThatAffectsJvmName: CallableMemberDescriptor? + get() = if (hasBuiltinSpecialPropertyFqName() || original.isFromJava) builtinSpecialOverridden else null -private val CallableDescriptor.isFromJava: Boolean +private val CallableMemberDescriptor.isFromJava: Boolean get() = propertyIfAccessor is JavaCallableMemberDescriptor -private val CallableDescriptor.propertyIfAccessor: CallableDescriptor +private val CallableMemberDescriptor.propertyIfAccessor: CallableDescriptor get() = if (this is PropertyAccessorDescriptor) correspondingProperty else this val CallableMemberDescriptor.hasErasedValueParametersInJava: Boolean diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/descriptors/JavaPropertyDescriptor.java b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/descriptors/JavaPropertyDescriptor.java index 9e80bb76988..50c6e5f8f18 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/descriptors/JavaPropertyDescriptor.java +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/descriptors/JavaPropertyDescriptor.java @@ -22,6 +22,7 @@ import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.descriptors.annotations.Annotations; import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl; import org.jetbrains.kotlin.descriptors.impl.PropertyGetterDescriptorImpl; +import org.jetbrains.kotlin.descriptors.impl.PropertySetterDescriptorImpl; import org.jetbrains.kotlin.name.Name; import org.jetbrains.kotlin.types.JetType; @@ -79,8 +80,16 @@ public class JavaPropertyDescriptor extends PropertyDescriptorImpl implements Ja newGetter.initialize(enhancedReturnType); } - assert getSetter() == null : "Field must not have a setter: " + this; - enhanced.initialize(newGetter, null); + PropertySetterDescriptorImpl newSetter = null; + PropertySetterDescriptor setter = getSetter(); + if (setter != null) { + newSetter = new PropertySetterDescriptorImpl( + enhanced, setter.getAnnotations(), setter.getModality(), setter.getVisibility(), + setter.hasBody(), setter.isDefault(), getKind(), setter, SourceElement.NO_SOURCE); + newSetter.initialize(setter.getValueParameters().get(0)); + } + + enhanced.initialize(newGetter, newSetter); enhanced.setSetterProjectedOut(isSetterProjectedOut()); if (compileTimeInitializer != null) { enhanced.setCompileTimeInitializer(compileTimeInitializer); diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/JavaDescriptorUtil.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/JavaDescriptorUtil.kt new file mode 100644 index 00000000000..a41d2760e45 --- /dev/null +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/JavaDescriptorUtil.kt @@ -0,0 +1,24 @@ +/* + * Copyright 2010-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.load.java.lazy.descriptors + +import org.jetbrains.kotlin.descriptors.PropertyDescriptor + + +// Currently getter is null iff it's loaded from Java field +public val PropertyDescriptor.isJavaField: Boolean + get() = getter == null \ No newline at end of file diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaClassMemberScope.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaClassMemberScope.kt index 71965982ac2..8b3b5f67d8f 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaClassMemberScope.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaClassMemberScope.kt @@ -16,10 +16,12 @@ package org.jetbrains.kotlin.load.java.lazy.descriptors +import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.descriptors.impl.ConstructorDescriptorImpl import org.jetbrains.kotlin.descriptors.impl.EnumEntrySyntheticClassDescriptor +import org.jetbrains.kotlin.descriptors.impl.PropertySetterDescriptorImpl import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl import org.jetbrains.kotlin.incremental.components.LookupLocation import org.jetbrains.kotlin.incremental.components.NoLookupLocation @@ -34,10 +36,7 @@ import org.jetbrains.kotlin.load.java.lazy.child import org.jetbrains.kotlin.load.java.lazy.resolveAnnotations import org.jetbrains.kotlin.load.java.lazy.types.RawSubstitution import org.jetbrains.kotlin.load.java.lazy.types.toAttributes -import org.jetbrains.kotlin.load.java.structure.JavaArrayType -import org.jetbrains.kotlin.load.java.structure.JavaClass -import org.jetbrains.kotlin.load.java.structure.JavaConstructor -import org.jetbrains.kotlin.load.java.structure.JavaMethod +import org.jetbrains.kotlin.load.java.structure.* import org.jetbrains.kotlin.load.java.typeEnhacement.enhanceSignatures import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.DescriptorFactory @@ -80,28 +79,63 @@ public class LazyJavaClassMemberScope( } override fun JavaMethodDescriptor.isVisibleAsFunction(): Boolean { - if (!canOverrideProperty) return true - return !doesOverrideAnySpecialProperty(getPropertiesFromSupertypes(name)) - } + val nameAsString = name.asString() - private val JavaMethodDescriptor.canOverrideProperty: Boolean - get() = valueParameters.isEmpty() && name.isBuiltinSpecialPropertyName - - private fun JavaMethodDescriptor.doesOverridesSpecialBuiltinProperty(property: PropertyDescriptor): Boolean { - if (valueParameters.isNotEmpty()) return false - - // TODO: is it always false? - if (name != property.name) return false - - return JetTypeChecker.DEFAULT.isSubtypeOf(returnType ?: return false, property.type) - } - - private fun JavaMethodDescriptor.doesOverrideAnySpecialProperty(properties: Collection): Boolean { - return properties.any overridesProperty@{ - property -> - val specialOverridden = property.builtinSpecialOverridden ?: return@overridesProperty false - doesOverridesSpecialBuiltinProperty(specialOverridden) + if (JvmAbi.isGetterName(nameAsString)) { + val propertyName = propertyNameByGetMethodName(name) ?: return true + return !doesClassOverrideAnyProperty(getPropertiesFromSupertypes(propertyName)) } + + if (JvmAbi.isSetterName(nameAsString)) { + return propertyNamesBySetMethodName(name).none { + propertyName -> + getPropertiesFromSupertypes(propertyName).any { + property -> property.isVar && doesClassOverridesProperty(property) + } + } + } + + if (name.isBuiltinSpecialPropertyName) { + return !doesClassOverrideAnyProperty(getPropertiesFromSupertypes(name)) + } + + return true + } + + private fun doesClassOverrideAnyProperty(properties: Collection) + = properties.any { property -> doesClassOverridesProperty(property) } + + private fun PropertyDescriptor.findGetterOverride(): JavaMethodDescriptor? { + val getterName = getter?.builtinSpecialOverridden?.builtinSpecialPropertyAccessorName ?: JvmAbi.getterName(name.asString()) + return memberIndex().findMethodsByName(Name.identifier(getterName)).firstNotNullResult factory@{ + javaMethod -> + val descriptor = resolveMethodToFunctionDescriptor(javaMethod) + if (descriptor.valueParameters.size != 0) return@factory null + + descriptor.check { JetTypeChecker.DEFAULT.isSubtypeOf(descriptor.returnType ?: return@check false, type) } + } + } + + private fun PropertyDescriptor.findSetterOverride(): JavaMethodDescriptor? { + return memberIndex().findMethodsByName(Name.identifier(JvmAbi.setterName(name.asString()))).firstNotNullResult factory@{ + javaMethod -> + val descriptor = resolveMethodToFunctionDescriptor(javaMethod) + if (descriptor.valueParameters.size != 1) return@factory null + + if (!KotlinBuiltIns.isUnit(descriptor.returnType ?: return@factory null)) return@factory null + descriptor.check { JetTypeChecker.DEFAULT.equalTypes(descriptor.valueParameters.single().type, type) } + } + } + + private fun doesClassOverridesProperty(property: PropertyDescriptor): Boolean { + if (property.isJavaField) return false + val getter = property.findGetterOverride() + val setter = property.findSetterOverride() + + if (getter == null) return false + if (!property.isVar) return true + + return setter != null && setter.modality == getter.modality } override fun computeNonDeclaredFunctions(result: MutableCollection, name: Name) { @@ -122,27 +156,22 @@ public class LazyJavaClassMemberScope( } val propertiesFromSupertypes = getPropertiesFromSupertypes(name) - - addPropertyOverrideByMethod(name, propertiesFromSupertypes, result) + addPropertyOverrideByMethod(propertiesFromSupertypes, result) result.addAll(DescriptorResolverUtils.resolveOverrides(name, propertiesFromSupertypes, result, getContainingDeclaration(), c.components.errorReporter)) } private fun addPropertyOverrideByMethod( - name: Name, propertiesFromSupertypes: Set, result: MutableCollection ) { - val javaMethod = memberIndex() - .findMethodsByName(name) - .firstOrNull { it.valueParameters.isEmpty() && it.typeParameters.isEmpty() && it.visibility.isPublicAPI } - ?: return - - val methodDescriptor = resolveMethodToFunctionDescriptor(javaMethod) - - if (methodDescriptor.doesOverrideAnySpecialProperty(propertiesFromSupertypes)) { - result.add(createPropertyDescriptorWithDefaultGetter(javaMethod, methodDescriptor.returnType, methodDescriptor.modality)) + for (property in propertiesFromSupertypes) { + val newProperty = createPropertyDescriptorByMethods(property) + if (newProperty != null) { + result.add(newProperty) + break + } } } @@ -172,6 +201,40 @@ public class LazyJavaClassMemberScope( return propertyDescriptor } + private fun createPropertyDescriptorByMethods( + overriddenProperty: PropertyDescriptor + ): JavaPropertyDescriptor? { + if (!doesClassOverridesProperty(overriddenProperty)) return null + + val getterMethod = overriddenProperty.findGetterOverride()!! + val setterMethod = + if (overriddenProperty.isVar) + overriddenProperty.findSetterOverride()!! + else + null + + val propertyDescriptor = JavaPropertyDescriptor( + getContainingDeclaration(), Annotations.EMPTY, getterMethod.modality, getterMethod.visibility, + /* isVar = */ setterMethod != null, overriddenProperty.name, getterMethod.source, + /* original */ null, + /* isStaticFinal = */ false + ) + + propertyDescriptor.setType(getterMethod.returnType!!, listOf(), getDispatchReceiverParameter(), null as JetType?) + + val getter = DescriptorFactory.createGetter( + propertyDescriptor, getterMethod.annotations, /* isDefault = */false, getterMethod.source + ).apply { + initialize(propertyDescriptor.type) + } + + val setter = setterMethod?.let { setterMethod -> + DescriptorFactory.createSetter(propertyDescriptor, setterMethod.annotations, /* isDefault = */false, setterMethod.visibility) + } + + return propertyDescriptor.apply { initialize(getter, setter) } + } + private fun getPropertiesFromSupertypes(name: Name): Set { return getContainingDeclaration().typeConstructor.supertypes.flatMap { it.memberScope.getProperties(name, NoLookupLocation.WHEN_GET_SUPER_MEMBERS).map { p -> p as PropertyDescriptor } diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/propertiesConventionUtil.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/propertiesConventionUtil.kt new file mode 100644 index 00000000000..f4ac50d1f92 --- /dev/null +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/propertiesConventionUtil.kt @@ -0,0 +1,47 @@ +/* + * Copyright 2010-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.load.java + +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.util.capitalizeDecapitalize.decapitalizeSmart + +fun propertyNameByGetMethodName(methodName: Name): Name? + = propertyNameFromAccessorMethodName(methodName, "get") ?: propertyNameFromAccessorMethodName(methodName, "is", removePrefix = false) + +fun propertyNameBySetMethodName(methodName: Name, withIsPrefix: Boolean): Name? + = propertyNameFromAccessorMethodName(methodName, "set", addPrefix = if (withIsPrefix) "is" else null) + +fun propertyNamesBySetMethodName(methodName: Name) + = listOf(propertyNameBySetMethodName(methodName, false), propertyNameBySetMethodName(methodName, true)).filterNotNull() + +private fun propertyNameFromAccessorMethodName(methodName: Name, prefix: String, removePrefix: Boolean = true, addPrefix: String? = null): Name? { + if (methodName.isSpecial()) return null + val identifier = methodName.getIdentifier() + if (!identifier.startsWith(prefix)) return null + if (identifier.length() == prefix.length()) return null + if (identifier[prefix.length()] in 'a'..'z') return null + + if (addPrefix != null) { + assert(removePrefix) + return Name.identifier(addPrefix + identifier.removePrefix(prefix)) + } + + if (!removePrefix) return methodName + val name = identifier.removePrefix(prefix).decapitalizeSmart(asciiOnly = true) + if (!Name.isValidIdentifier(name)) return null + return Name.identifier(name) +} diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorFactory.java b/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorFactory.java index 43dea53b61a..6fda81be35a 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorFactory.java +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorFactory.java @@ -56,10 +56,20 @@ public class DescriptorFactory { @NotNull PropertyDescriptor propertyDescriptor, @NotNull Annotations annotations, boolean isDefault + ) { + return createSetter(propertyDescriptor, annotations, isDefault, propertyDescriptor.getVisibility()); + } + + @NotNull + public static PropertySetterDescriptorImpl createSetter( + @NotNull PropertyDescriptor propertyDescriptor, + @NotNull Annotations annotations, + boolean isDefault, + @NotNull Visibility visibility ) { PropertySetterDescriptorImpl setterDescriptor = new PropertySetterDescriptorImpl(propertyDescriptor, annotations, propertyDescriptor.getModality(), - propertyDescriptor.getVisibility(), !isDefault, isDefault, + visibility, !isDefault, isDefault, CallableMemberDescriptor.Kind.DECLARATION, null, propertyDescriptor.getSource()); setterDescriptor.initializeDefault(); return setterDescriptor; @@ -78,9 +88,18 @@ public class DescriptorFactory { @NotNull PropertyDescriptor propertyDescriptor, @NotNull Annotations annotations, boolean isDefault) { + return createGetter(propertyDescriptor, annotations, isDefault, propertyDescriptor.getSource()); + } + + @NotNull + public static PropertyGetterDescriptorImpl createGetter( + @NotNull PropertyDescriptor propertyDescriptor, + @NotNull Annotations annotations, + boolean isDefault, + @NotNull SourceElement sourceElement) { return new PropertyGetterDescriptorImpl(propertyDescriptor, annotations, propertyDescriptor.getModality(), propertyDescriptor.getVisibility(), !isDefault, isDefault, - CallableMemberDescriptor.Kind.DECLARATION, null, propertyDescriptor.getSource()); + CallableMemberDescriptor.Kind.DECLARATION, null, sourceElement); } @NotNull diff --git a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KFunctionFromReferenceImpl.kt b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KFunctionFromReferenceImpl.kt index ab201008e76..39569a80615 100644 --- a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KFunctionFromReferenceImpl.kt +++ b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KFunctionFromReferenceImpl.kt @@ -28,12 +28,12 @@ internal class KFunctionFromReferenceImpl( val reference: FunctionReference ): KFunctionImpl( reference.getOwner() as? KDeclarationContainerImpl ?: EmptyContainerForLocal, - reference.getName(), + reference.name, reference.getSignature() ) { override fun getArity() = reference.getArity() - override val name = reference.getName() + override val name = reference.name // The rest of the class is auto-generated. Use the following script: // (0..22).forEach { n -> println("override fun invoke(" + (1..n).joinToString { "p$it: Any?" } + "): Any? = reference(" + (1..n).joinToString { "p$it" } + ")") }