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
This commit is contained in:
Toshiaki Kameyama
2019-11-28 00:55:50 +09:00
committed by Ilya Kirillov
parent 1bbd17c4d6
commit be04912f6f
4 changed files with 112 additions and 3 deletions
@@ -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
@@ -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) {
}
}
+36
View File
@@ -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) {
}
}
@@ -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");