New J2K: convert Java method reference to Kotlin one on copy-pasting Java code

#KT-34965 fixed
This commit is contained in:
Ilya Kirillov
2020-03-30 14:30:49 +03:00
parent d6d843aaed
commit bc52281208
13 changed files with 66 additions and 5 deletions
@@ -470,6 +470,7 @@ class JavaToJKTreeBuilder constructor(
is JKClassSymbol -> JKClassAccessExpression(symbol) is JKClassSymbol -> JKClassAccessExpression(symbol)
is JKFieldSymbol -> JKFieldAccessExpression(symbol) is JKFieldSymbol -> JKFieldAccessExpression(symbol)
is JKPackageSymbol -> JKPackageAccessExpression(symbol) is JKPackageSymbol -> JKPackageAccessExpression(symbol)
is JKMethodSymbol -> JKMethodAccessExpression(symbol)
else -> throwCanNotConvertError("unexpected symbol ${symbol::class}") else -> throwCanNotConvertError("unexpected symbol ${symbol::class}")
}.qualified(qualifierExpression?.toJK()).also { }.qualified(qualifierExpression?.toJK()).also {
it.withFormattingFrom(this) it.withFormattingFrom(this)
@@ -68,6 +68,14 @@ class BuiltinMembersConversion(context: NewJ2kConverterContext) : RecursiveAppli
true true
} }
is JKMethodAccessExpression ->
conversions[identifier.deepestFqName()]?.firstOrNull { conversion ->
if (conversion.from !is Method) return@firstOrNull false
if (conversion.to !is Method) return@firstOrNull false
if (conversion.filter?.invoke(this) == false) return@firstOrNull false
true
}
is JKNewExpression -> is JKNewExpression ->
conversions[classSymbol.deepestFqName()]?.firstOrNull { conversion -> conversions[classSymbol.deepestFqName()]?.firstOrNull { conversion ->
if (conversion.from !is NewExpression) return@firstOrNull false if (conversion.from !is NewExpression) return@firstOrNull false
@@ -93,21 +101,23 @@ class BuiltinMembersConversion(context: NewJ2kConverterContext) : RecursiveAppli
symbolProvider.provideMethodSymbol(fqName), symbolProvider.provideMethodSymbol(fqName),
argumentsProvider(from::arguments.detached()), argumentsProvider(from::arguments.detached()),
from::typeArgumentList.detached() from::typeArgumentList.detached()
).withFormattingFrom(from) )
is JKFieldAccessExpression -> is JKFieldAccessExpression ->
JKCallExpressionImpl( JKCallExpressionImpl(
symbolProvider.provideMethodSymbol(fqName), symbolProvider.provideMethodSymbol(fqName),
JKArgumentList(), JKArgumentList(),
JKTypeArgumentList() JKTypeArgumentList()
).withFormattingFrom(from) )
is JKMethodAccessExpression ->
JKMethodAccessExpression(symbolProvider.provideMethodSymbol(fqName))
is JKNewExpression -> is JKNewExpression ->
JKCallExpressionImpl( JKCallExpressionImpl(
symbolProvider.provideMethodSymbol(fqName), symbolProvider.provideMethodSymbol(fqName),
argumentsProvider(from::arguments.detached()), argumentsProvider(from::arguments.detached()),
JKTypeArgumentList() JKTypeArgumentList()
).withFormattingFrom(from) )
else -> error("Bad conversion") else -> error("Bad conversion")
} }.withFormattingFrom(from)
} }
private inner class FieldBuilder( private inner class FieldBuilder(
@@ -142,6 +142,10 @@ internal class JKCodeBuilder(context: NewJ2kConverterContext) {
printer.renderSymbol(classAccessExpression.identifier, classAccessExpression) printer.renderSymbol(classAccessExpression.identifier, classAccessExpression)
} }
override fun visitMethodAccessExpression(methodAccessExpression: JKMethodAccessExpression) {
printer.renderSymbol(methodAccessExpression.identifier, methodAccessExpression)
}
override fun visitFileRaw(file: JKFile) { override fun visitFileRaw(file: JKFile) {
if (file.packageDeclaration.name.value.isNotEmpty()) { if (file.packageDeclaration.name.value.isNotEmpty()) {
file.packageDeclaration.accept(this) file.packageDeclaration.accept(this)
@@ -196,6 +196,11 @@ class JKClassAccessExpression(var identifier: JKClassSymbol) : JKExpression() {
override fun accept(visitor: JKVisitor) = visitor.visitClassAccessExpression(this) override fun accept(visitor: JKVisitor) = visitor.visitClassAccessExpression(this)
} }
class JKMethodAccessExpression(val identifier: JKMethodSymbol) : JKExpression() {
override fun calculateType(typeFactory: JKTypeFactory): JKType? = null
override fun accept(visitor: JKVisitor) = visitor.visitMethodAccessExpression(this)
}
class JKMethodReferenceExpression( class JKMethodReferenceExpression(
qualifier: JKExpression, qualifier: JKExpression,
val identifier: JKSymbol, val identifier: JKSymbol,
@@ -83,6 +83,7 @@ abstract class JKVisitor {
open fun visitFieldAccessExpression(fieldAccessExpression: JKFieldAccessExpression) = visitExpression(fieldAccessExpression) open fun visitFieldAccessExpression(fieldAccessExpression: JKFieldAccessExpression) = visitExpression(fieldAccessExpression)
open fun visitPackageAccessExpression(packageAccessExpression: JKPackageAccessExpression) = visitExpression(packageAccessExpression) open fun visitPackageAccessExpression(packageAccessExpression: JKPackageAccessExpression) = visitExpression(packageAccessExpression)
open fun visitClassAccessExpression(classAccessExpression: JKClassAccessExpression) = visitExpression(classAccessExpression) open fun visitClassAccessExpression(classAccessExpression: JKClassAccessExpression) = visitExpression(classAccessExpression)
open fun visitMethodAccessExpression(methodAccessExpression: JKMethodAccessExpression) = visitExpression(methodAccessExpression)
open fun visitMethodReferenceExpression(methodReferenceExpression: JKMethodReferenceExpression) = open fun visitMethodReferenceExpression(methodReferenceExpression: JKMethodReferenceExpression) =
visitExpression(methodReferenceExpression) visitExpression(methodReferenceExpression)
@@ -579,6 +579,14 @@ abstract class JKVisitorWithCommentsPrinting : JKVisitor() {
open fun visitPackageAccessExpressionRaw(packageAccessExpression: JKPackageAccessExpression) = open fun visitPackageAccessExpressionRaw(packageAccessExpression: JKPackageAccessExpression) =
visitExpressionRaw(packageAccessExpression) visitExpressionRaw(packageAccessExpression)
override fun visitMethodAccessExpression(methodAccessExpression: JKMethodAccessExpression) {
printLeftNonCodeElements(methodAccessExpression)
visitMethodAccessExpressionRaw(methodAccessExpression)
printRightNonCodeElements(methodAccessExpression)
}
open fun visitMethodAccessExpressionRaw(methodAccessExpression: JKMethodAccessExpression) = visitExpressionRaw(methodAccessExpression)
override fun visitClassAccessExpression(classAccessExpression: JKClassAccessExpression) { override fun visitClassAccessExpression(classAccessExpression: JKClassAccessExpression) {
printLeftNonCodeElements(classAccessExpression) printLeftNonCodeElements(classAccessExpression)
visitClassAccessExpressionRaw(classAccessExpression) visitClassAccessExpressionRaw(classAccessExpression)
@@ -0,0 +1,3 @@
fun foo() {
println
}
+5
View File
@@ -0,0 +1,5 @@
class A {
public static void main(String[] args) {
<selection>System.out.println</selection>("nya")
}
}
@@ -0,0 +1,3 @@
fun foo() {
<caret>
}
@@ -0,0 +1,3 @@
fun foo() {
System.out.printf
}
@@ -0,0 +1,5 @@
class A {
public static void main(String[] args) {
<selection>System.out.printf</selection>("nya")
}
}
@@ -0,0 +1,3 @@
fun foo() {
<caret>
}
@@ -83,6 +83,11 @@ public class NewJavaToKotlinCopyPasteConversionTestGenerated extends AbstractNew
runTest("nj2k/testData/copyPaste/ConversionInCorrectContext.java"); runTest("nj2k/testData/copyPaste/ConversionInCorrectContext.java");
} }
@TestMetadata("ConvertedMethodReference.java")
public void testConvertedMethodReference() throws Exception {
runTest("nj2k/testData/copyPaste/ConvertedMethodReference.java");
}
@TestMetadata("CopyAnnotation.java") @TestMetadata("CopyAnnotation.java")
public void testCopyAnnotation() throws Exception { public void testCopyAnnotation() throws Exception {
runTest("nj2k/testData/copyPaste/CopyAnnotation.java"); runTest("nj2k/testData/copyPaste/CopyAnnotation.java");
@@ -222,4 +227,9 @@ public class NewJavaToKotlinCopyPasteConversionTestGenerated extends AbstractNew
public void testSingleWordFromIdentifier() throws Exception { public void testSingleWordFromIdentifier() throws Exception {
runTest("nj2k/testData/copyPaste/SingleWordFromIdentifier.java"); runTest("nj2k/testData/copyPaste/SingleWordFromIdentifier.java");
} }
@TestMetadata("UnconvertedMethodReference.java")
public void testUnconvertedMethodReference() throws Exception {
runTest("nj2k/testData/copyPaste/UnconvertedMethodReference.java");
}
} }