From be04912f6fc748c0f88230f80b5abb1c5967c8e7 Mon Sep 17 00:00:00 2001 From: Toshiaki Kameyama Date: Thu, 28 Nov 2019 00:55:50 +0900 Subject: [PATCH] KT-19574 Code with inferred default parameters and parameter vs property name clashes (#2671) New J2K: add 'this' receiver to default parameter value if needed #KT-19574 Fixed --- .../conversions/DefaultArgumentsConversion.kt | 25 ++++++++-- .../overloads/ConflictParameterName.java | 49 +++++++++++++++++++ .../newJ2k/overloads/ConflictParameterName.kt | 36 ++++++++++++++ ...otlinConverterSingleFileTestGenerated.java | 5 ++ 4 files changed, 112 insertions(+), 3 deletions(-) create mode 100644 nj2k/testData/newJ2k/overloads/ConflictParameterName.java create mode 100644 nj2k/testData/newJ2k/overloads/ConflictParameterName.kt diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/DefaultArgumentsConversion.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/DefaultArgumentsConversion.kt index 95ee7261bb1..fad7825a48f 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/DefaultArgumentsConversion.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/DefaultArgumentsConversion.kt @@ -5,12 +5,15 @@ package org.jetbrains.kotlin.nj2k.conversions + import com.intellij.psi.PsiMethod +import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.nj2k.* +import org.jetbrains.kotlin.nj2k.symbols.JKSymbol import org.jetbrains.kotlin.nj2k.symbols.JKUniverseMethodSymbol import org.jetbrains.kotlin.nj2k.tree.* - - +import org.jetbrains.kotlin.nj2k.types.JKNoType +import org.jetbrains.kotlin.synthetic.SyntheticJavaPropertyDescriptor import org.jetbrains.kotlin.utils.addToStdlib.safeAs class DefaultArgumentsConversion(context: NewJ2kConverterContext) : RecursiveApplicableConversionBase(context) { @@ -91,9 +94,20 @@ class DefaultArgumentsConversion(context: NewJ2kConverterContext) : RecursiveApp .zip(calledMethod.parameters) .drop(method.parameters.size) + fun JKSymbol.isNeedThisReceiver(): Boolean { + val parameters = defaults.map { it.second } + val declarations = element.declarations + val propertyNameByGetMethodName = + SyntheticJavaPropertyDescriptor.propertyNameByGetMethodName(Name.identifier(this.name))?.asString() + return parameters.any { it.name.value == this.name || it.name.value == propertyNameByGetMethodName } + && declarations.any { it == this.target } + } for ((defaultValue, parameter) in defaults) { fun remapParameterSymbol(on: JKTreeElement): JKTreeElement { + if (on is JKQualifiedExpression && on.receiver is JKThisExpression) { + return on + } if (on is JKFieldAccessExpression) { val target = on.identifier.target if (target is JKParameter) { @@ -101,8 +115,13 @@ class DefaultArgumentsConversion(context: NewJ2kConverterContext) : RecursiveApp symbolProvider.provideUniverseSymbol(calledMethod.parameters[method.parameters.indexOf(target)]) return JKFieldAccessExpression(newSymbol) } + if (on.identifier.isNeedThisReceiver()) { + return JKQualifiedExpression(JKThisExpression(JKLabelEmpty(), JKNoType), JKFieldAccessExpression(on.identifier)) + } + } + if (on is JKCallExpression && on.identifier.isNeedThisReceiver()) { + return JKQualifiedExpression(JKThisExpression(JKLabelEmpty(), JKNoType), applyRecursive(on, ::remapParameterSymbol)) } - return applyRecursive(on, ::remapParameterSymbol) } parameter.initializer = remapParameterSymbol(defaultValue) as JKExpression diff --git a/nj2k/testData/newJ2k/overloads/ConflictParameterName.java b/nj2k/testData/newJ2k/overloads/ConflictParameterName.java new file mode 100644 index 00000000000..5aa047cfca7 --- /dev/null +++ b/nj2k/testData/newJ2k/overloads/ConflictParameterName.java @@ -0,0 +1,49 @@ +public class Test { + + private int x = 1; + + private final boolean a = true; + + private final boolean b = true; + + private final boolean c() { + return true; + } + + private final boolean isD() { + return true; + } + + private final E e = new E(); + + public static class E { + public boolean ee = true; + } + + public static class F { + public boolean f = true; + } + + private final int getG() { return 1; } + + public void foo() { + foo(a, this.b, c(), isD(), e.ee, new F().f, getG()); + } + + public void foo(boolean a, boolean b, boolean c, boolean isD, boolean e, boolean f, int g) { + } + + public void bar() { + bar(a, a, b); + } + + public void bar(boolean a, boolean e, boolean f) { + } + + public void baz() { + baz(!a, ++x, x++, x + x + 1); + } + + public void baz(boolean a, int x, int y, int z) { + } +} \ No newline at end of file diff --git a/nj2k/testData/newJ2k/overloads/ConflictParameterName.kt b/nj2k/testData/newJ2k/overloads/ConflictParameterName.kt new file mode 100644 index 00000000000..7b6bf72823c --- /dev/null +++ b/nj2k/testData/newJ2k/overloads/ConflictParameterName.kt @@ -0,0 +1,36 @@ +class Test { + private var x = 1 + private val a = true + private val b = true + private fun c(): Boolean { + return true + } + + private val isD: Boolean + private get() = true + + private val e = E() + + class E { + var ee = true + } + + class F { + var f = true + } + + private val g: Int + private get() = 1 + + @JvmOverloads + fun foo(a: Boolean = this.a, b: Boolean = this.b, c: Boolean = c(), isD: Boolean = this.isD, e: Boolean = this.e.ee, f: Boolean = F().f, g: Int = this.g) { + } + + @JvmOverloads + fun bar(a: Boolean = this.a, e: Boolean = this.a, f: Boolean = b) { + } + + @JvmOverloads + fun baz(a: Boolean = !this.a, x: Int = ++this.x, y: Int = this.x++, z: Int = this.x + this.x + 1) { + } +} \ No newline at end of file diff --git a/nj2k/tests/org/jetbrains/kotlin/nj2k/NewJavaToKotlinConverterSingleFileTestGenerated.java b/nj2k/tests/org/jetbrains/kotlin/nj2k/NewJavaToKotlinConverterSingleFileTestGenerated.java index 592d318f4b6..76fd574a210 100644 --- a/nj2k/tests/org/jetbrains/kotlin/nj2k/NewJavaToKotlinConverterSingleFileTestGenerated.java +++ b/nj2k/tests/org/jetbrains/kotlin/nj2k/NewJavaToKotlinConverterSingleFileTestGenerated.java @@ -4044,6 +4044,11 @@ public class NewJavaToKotlinConverterSingleFileTestGenerated extends AbstractNew runTest("nj2k/testData/newJ2k/overloads/Annotations.java"); } + @TestMetadata("ConflictParameterName.java") + public void testConflictParameterName() throws Exception { + runTest("nj2k/testData/newJ2k/overloads/ConflictParameterName.java"); + } + @TestMetadata("Override.java") public void testOverride() throws Exception { runTest("nj2k/testData/newJ2k/overloads/Override.java");