From 5f8b5efd66935d265d904654155bcd0ad93eb44c Mon Sep 17 00:00:00 2001 From: Ilya Kirillov Date: Sat, 8 Jun 2019 20:53:02 +0300 Subject: [PATCH] New J2K: do not find import usages in AST building phase It is a rather heavy operation and it increases conversion time Related to #KT-31848 --- .../nj2k/postProcessing/J2kPostProcessor.kt | 3 +- .../kotlin/nj2k/JavaToJKTreeBuilder.kt | 40 ++++++------------- .../nullability-settings.kt | 2 + .../assignmentExpression/nullability.kt | 2 + nj2k/testData/newJ2k/class/kt-639.kt | 2 + .../nestedClassNameInParameterDefaults2.kt | 4 +- .../nestedClassNameInParameterDefaults3.kt | 4 +- .../newJ2k/detectProperties/PropertyType.kt | 2 + .../newJ2k/for/forThroughListIndices.kt | 2 + nj2k/testData/newJ2k/for/overMapEntries.kt | 2 + .../function/java8MRKFunctionExpectedType.kt | 2 +- .../newJ2k/function/java8MRSamConstructor.kt | 6 +-- nj2k/testData/newJ2k/issues/kt-1048.kt | 2 + nj2k/testData/newJ2k/issues/kt-6790.kt | 4 +- .../StaticImportFromCompanionObject.kt | 4 +- .../newJ2k/mutableCollections/Iterator2.kt | 2 + .../genericClassInvocation.kt | 2 + .../newClassExpression/newListAndNewMember.kt | 2 + .../newJ2k/nullability/nullableField.kt | 2 + .../newJ2k/postProcessing/GetOperator.kt | 1 + .../java8MapForEachWithFullJdk.kt | 2 + .../newJ2k/projections/projections.kt | 2 + .../testData/newJ2k/rawGenerics/kt-540-map.kt | 2 + nj2k/testData/newJ2k/rawGenerics/kt-540.kt | 2 + .../toKotlinClasses/LibraryFunctions.kt | 2 + .../newJ2k/typeParameters/needTypeArgs.kt | 2 + 26 files changed, 62 insertions(+), 40 deletions(-) diff --git a/nj2k/nj2k-services/src/org/jetbrains/kotlin/nj2k/postProcessing/J2kPostProcessor.kt b/nj2k/nj2k-services/src/org/jetbrains/kotlin/nj2k/postProcessing/J2kPostProcessor.kt index 92d1f9d4877..2d6edcc4a09 100644 --- a/nj2k/nj2k-services/src/org/jetbrains/kotlin/nj2k/postProcessing/J2kPostProcessor.kt +++ b/nj2k/nj2k-services/src/org/jetbrains/kotlin/nj2k/postProcessing/J2kPostProcessor.kt @@ -279,5 +279,6 @@ private val processings: List = listOf( RemoveForExpressionLoopParameterTypeProcessing() ), formatCodeProcessing, - optimizeImportsProcessing + optimizeImportsProcessing, + shortenReferencesProcessing ) \ No newline at end of file diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/JavaToJKTreeBuilder.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/JavaToJKTreeBuilder.kt index 1ac02b8bec9..329b6b58fec 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/JavaToJKTreeBuilder.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/JavaToJKTreeBuilder.kt @@ -30,10 +30,10 @@ import com.intellij.psi.impl.source.tree.java.PsiLiteralExpressionImpl import com.intellij.psi.impl.source.tree.java.PsiNewExpressionImpl import com.intellij.psi.infos.MethodCandidateInfo import com.intellij.psi.javadoc.PsiDocComment -import com.intellij.psi.search.searches.ReferencesSearch import com.intellij.psi.tree.IElementType -import com.intellij.psi.util.PsiTreeUtil +import org.jetbrains.kotlin.asJava.classes.KtLightClass import org.jetbrains.kotlin.asJava.classes.KtLightClassForFacade +import org.jetbrains.kotlin.asJava.elements.KtLightElement import org.jetbrains.kotlin.asJava.elements.KtLightField import org.jetbrains.kotlin.asJava.elements.KtLightMethod import org.jetbrains.kotlin.idea.caches.lightClasses.KtLightClassForDecompiledDeclaration @@ -68,32 +68,12 @@ class JavaToJKTreeBuilder constructor( private fun PsiJavaFile.toJK(): JKFile = JKFileImpl( packageStatement?.toJK() ?: JKPackageDeclarationImpl(JKNameIdentifierImpl("")), - importList.toJK(filterOutUsedImports = true), + importList.toJK(), with(declarationMapper) { classes.map { it.toJK() } } ) - private fun PsiImportList?.toJK(filterOutUsedImports: Boolean): JKImportList = - JKImportListImpl( - this?.allImportStatements?.let { imports -> - if (filterOutUsedImports) { - imports.filter { import -> - when { - import.isSingleUnusedImport() -> true - import.isOnDemand -> true - else -> false - } - } - } else imports.toList() - }?.mapNotNull { it.toJK() }.orEmpty() - ) - - - private fun PsiImportStatementBase.isSingleUnusedImport(): Boolean { - if (isOnDemand) return false - val target = resolve() ?: return true - val usages = ReferencesSearch.search(target).toList() - return usages.size == 1 && PsiTreeUtil.isAncestor(this, usages.iterator().next().element, true) - } + private fun PsiImportList?.toJK(): JKImportList = + JKImportListImpl(this?.allImportStatements?.mapNotNull { it.toJK() }.orEmpty()) private fun PsiPackageStatement.toJK(): JKPackageDeclaration = JKPackageDeclarationImpl(JKNameIdentifierImpl(packageName)) @@ -106,8 +86,12 @@ class JavaToJKTreeBuilder constructor( val target = resolve() val rawName = (importReference?.canonicalText ?: return null) + if (isOnDemand) ".*" else "" val name = - if (target is KtLightClassForFacade) target.fqName.parent().asString() + ".*" - else rawName + target.safeAs>()?.kotlinOrigin?.getKotlinFqName()?.asString() + ?: target.safeAs()?.containingFile?.safeAs()?.packageFqName?.asString()?.let { "$it.*" } + ?: target.safeAs()?.fqName?.parent()?.asString()?.let { "$it.*" } + ?: target.safeAs()?.fqName?.parent()?.asString()?.let { "$it.*" } + ?: rawName + return JKImportStatementImpl(JKNameIdentifierImpl(name)) .also { it.assignNonCodeElements(this) @@ -929,7 +913,7 @@ class JavaToJKTreeBuilder constructor( is PsiField -> with(declarationMapper) { psi.toJK() } is PsiMethod -> with(declarationMapper) { psi.toJK() } is PsiAnnotation -> with(declarationMapper) { psi.toJK() } - is PsiImportList -> psi.toJK(filterOutUsedImports = false) + is PsiImportList -> psi.toJK() is PsiImportStatement -> psi.toJK() is PsiJavaCodeReferenceElement -> if (psi.parent is PsiReferenceList) { diff --git a/nj2k/testData/newJ2k/assignmentExpression/nullability-settings.kt b/nj2k/testData/newJ2k/assignmentExpression/nullability-settings.kt index b481deca041..ae0203d7b13 100644 --- a/nj2k/testData/newJ2k/assignmentExpression/nullability-settings.kt +++ b/nj2k/testData/newJ2k/assignmentExpression/nullability-settings.kt @@ -1,6 +1,8 @@ // !forceNotNullTypes: false // !specifyLocalVariableTypeByDefault: true +import java.util.HashSet + internal class Foo { fun foo(o: HashSet<*>) { val o2: HashSet<*> = o diff --git a/nj2k/testData/newJ2k/assignmentExpression/nullability.kt b/nj2k/testData/newJ2k/assignmentExpression/nullability.kt index 8dd3c9ff495..94224d39719 100644 --- a/nj2k/testData/newJ2k/assignmentExpression/nullability.kt +++ b/nj2k/testData/newJ2k/assignmentExpression/nullability.kt @@ -1,3 +1,5 @@ +import java.util.HashSet + internal class Foo { fun foo(o: HashSet<*>) { var foo = 0 diff --git a/nj2k/testData/newJ2k/class/kt-639.kt b/nj2k/testData/newJ2k/class/kt-639.kt index beb7a868d79..43ad72a5bfa 100644 --- a/nj2k/testData/newJ2k/class/kt-639.kt +++ b/nj2k/testData/newJ2k/class/kt-639.kt @@ -2,6 +2,8 @@ // ERROR: Type inference failed: Not enough information to infer parameter K in constructor HashMap(initialCapacity: Int) Please specify it explicitly. package demo +import java.util.HashMap + internal class Test { constructor() {} constructor(s: String?) {} diff --git a/nj2k/testData/newJ2k/constructors/nestedClassNameInParameterDefaults2.kt b/nj2k/testData/newJ2k/constructors/nestedClassNameInParameterDefaults2.kt index 781f010b40d..5d9d368d9ec 100644 --- a/nj2k/testData/newJ2k/constructors/nestedClassNameInParameterDefaults2.kt +++ b/nj2k/testData/newJ2k/constructors/nestedClassNameInParameterDefaults2.kt @@ -1,3 +1,5 @@ +import A.Nested + internal class A @JvmOverloads constructor(nested: Nested = Nested(Nested.FIELD)) { internal class Nested(p: Int) { companion object { @@ -7,5 +9,5 @@ internal class A @JvmOverloads constructor(nested: Nested = Nested(Nested.FIELD) } internal class B { - var nested: A.Nested? = null + var nested: Nested? = null } \ No newline at end of file diff --git a/nj2k/testData/newJ2k/constructors/nestedClassNameInParameterDefaults3.kt b/nj2k/testData/newJ2k/constructors/nestedClassNameInParameterDefaults3.kt index 7b5ec9c0695..d6f8f39dfbb 100644 --- a/nj2k/testData/newJ2k/constructors/nestedClassNameInParameterDefaults3.kt +++ b/nj2k/testData/newJ2k/constructors/nestedClassNameInParameterDefaults3.kt @@ -1,5 +1,7 @@ package pack +import pack.A.Nested + internal class A @JvmOverloads constructor(nested: Nested = Nested(Nested.FIELD)) { internal class Nested(p: Int) { companion object { @@ -9,5 +11,5 @@ internal class A @JvmOverloads constructor(nested: Nested = Nested(Nested.FIELD) } internal class B { - var nested: A.Nested? = null + var nested: Nested? = null } \ No newline at end of file diff --git a/nj2k/testData/newJ2k/detectProperties/PropertyType.kt b/nj2k/testData/newJ2k/detectProperties/PropertyType.kt index c409787857d..1de4e56507e 100644 --- a/nj2k/testData/newJ2k/detectProperties/PropertyType.kt +++ b/nj2k/testData/newJ2k/detectProperties/PropertyType.kt @@ -1,3 +1,5 @@ +import java.util.ArrayList + internal class A { private val list1: ArrayList = ArrayList() private val list2: MutableList = ArrayList() diff --git a/nj2k/testData/newJ2k/for/forThroughListIndices.kt b/nj2k/testData/newJ2k/for/forThroughListIndices.kt index de15d19be85..45bd0422a63 100644 --- a/nj2k/testData/newJ2k/for/forThroughListIndices.kt +++ b/nj2k/testData/newJ2k/for/forThroughListIndices.kt @@ -1,3 +1,5 @@ +import java.util.ArrayList + internal class C { fun foo1(list: MutableList) { for (i in list.indices) { diff --git a/nj2k/testData/newJ2k/for/overMapEntries.kt b/nj2k/testData/newJ2k/for/overMapEntries.kt index 3c140200d16..f39d9bfd409 100644 --- a/nj2k/testData/newJ2k/for/overMapEntries.kt +++ b/nj2k/testData/newJ2k/for/overMapEntries.kt @@ -1,3 +1,5 @@ +import java.util.HashMap + internal object Test { @JvmStatic fun main(args: Array) { diff --git a/nj2k/testData/newJ2k/function/java8MRKFunctionExpectedType.kt b/nj2k/testData/newJ2k/function/java8MRKFunctionExpectedType.kt index 423f25cab90..4f6def97e7e 100644 --- a/nj2k/testData/newJ2k/function/java8MRKFunctionExpectedType.kt +++ b/nj2k/testData/newJ2k/function/java8MRKFunctionExpectedType.kt @@ -77,7 +77,7 @@ internal class Java8Class { } fun testGenericFunctions() { - val emptyList: Function0> = { emptyList() } + val emptyList: Function0> = { emptyList() } val list = emptyList.invoke() list[0] } diff --git a/nj2k/testData/newJ2k/function/java8MRSamConstructor.kt b/nj2k/testData/newJ2k/function/java8MRSamConstructor.kt index 8e50536c1c4..68abd6dbe44 100644 --- a/nj2k/testData/newJ2k/function/java8MRSamConstructor.kt +++ b/nj2k/testData/newJ2k/function/java8MRSamConstructor.kt @@ -122,10 +122,10 @@ internal class Java8Class { } fun testGenericFunctions() { - val emptyList: JFunction1> = JFunction1 { emptyList() } + val emptyList: JFunction1> = JFunction1 { emptyList() } emptyList.foo() - MethodReferenceHelperClass.staticFun1(JFunction1> { emptyList() }) - h.memberFun1(JFunction1> { emptyList() }) + MethodReferenceHelperClass.staticFun1(JFunction1> { emptyList() }) + h.memberFun1(JFunction1> { emptyList() }) } fun memberFun(): Int { diff --git a/nj2k/testData/newJ2k/issues/kt-1048.kt b/nj2k/testData/newJ2k/issues/kt-1048.kt index e78244b8b17..7c75ba22201 100644 --- a/nj2k/testData/newJ2k/issues/kt-1048.kt +++ b/nj2k/testData/newJ2k/issues/kt-1048.kt @@ -1,6 +1,8 @@ // ERROR: The integer literal does not conform to the expected type CapturedType(*) // ERROR: The integer literal does not conform to the expected type CapturedType(*) // ERROR: Type argument is not within its bounds: should be subtype of 'String?' +import java.util.HashMap + internal class G(t: T?) class Java { internal fun test() { diff --git a/nj2k/testData/newJ2k/issues/kt-6790.kt b/nj2k/testData/newJ2k/issues/kt-6790.kt index 92d8ff75457..a7ad30c3b76 100644 --- a/nj2k/testData/newJ2k/issues/kt-6790.kt +++ b/nj2k/testData/newJ2k/issues/kt-6790.kt @@ -1,5 +1,3 @@ -import kotlin.collections.Map.Entry - class A { - internal fun foo(o: Entry?) {} + internal fun foo(o: Map.Entry?) {} } \ No newline at end of file diff --git a/nj2k/testData/newJ2k/kotlinApiAccess/StaticImportFromCompanionObject.kt b/nj2k/testData/newJ2k/kotlinApiAccess/StaticImportFromCompanionObject.kt index 21323b6a3a9..4993f26b1d6 100644 --- a/nj2k/testData/newJ2k/kotlinApiAccess/StaticImportFromCompanionObject.kt +++ b/nj2k/testData/newJ2k/kotlinApiAccess/StaticImportFromCompanionObject.kt @@ -1,7 +1,7 @@ -import kotlinApi.KotlinClass +import kotlinApi.KotlinClass.Companion.CONST class C { internal fun bar() { - println(KotlinClass.CONST) + println(CONST) } } \ No newline at end of file diff --git a/nj2k/testData/newJ2k/mutableCollections/Iterator2.kt b/nj2k/testData/newJ2k/mutableCollections/Iterator2.kt index 03674157a08..fb47dc25361 100644 --- a/nj2k/testData/newJ2k/mutableCollections/Iterator2.kt +++ b/nj2k/testData/newJ2k/mutableCollections/Iterator2.kt @@ -1,3 +1,5 @@ +import java.util.ArrayList + class TestMutableCollection { val list: MutableList = ArrayList() diff --git a/nj2k/testData/newJ2k/newClassExpression/genericClassInvocation.kt b/nj2k/testData/newJ2k/newClassExpression/genericClassInvocation.kt index a500cadb3da..fe40a351b51 100644 --- a/nj2k/testData/newJ2k/newClassExpression/genericClassInvocation.kt +++ b/nj2k/testData/newJ2k/newClassExpression/genericClassInvocation.kt @@ -1,3 +1,5 @@ +import java.util.ArrayList + internal class User { fun main() { val list: List = ArrayList() diff --git a/nj2k/testData/newJ2k/newClassExpression/newListAndNewMember.kt b/nj2k/testData/newJ2k/newClassExpression/newListAndNewMember.kt index 6d66872aca5..02be4a150de 100644 --- a/nj2k/testData/newJ2k/newClassExpression/newListAndNewMember.kt +++ b/nj2k/testData/newJ2k/newClassExpression/newListAndNewMember.kt @@ -1,5 +1,7 @@ package org.test +import java.util.ArrayList + internal class Member internal class User { fun main() { diff --git a/nj2k/testData/newJ2k/nullability/nullableField.kt b/nj2k/testData/newJ2k/nullability/nullableField.kt index 97a314d14b6..1f38580e8ec 100644 --- a/nj2k/testData/newJ2k/nullability/nullableField.kt +++ b/nj2k/testData/newJ2k/nullability/nullableField.kt @@ -1,5 +1,7 @@ package test +import java.util.ArrayList + class Test { private var myProp: String? = null private var myIntProp: Int? = null diff --git a/nj2k/testData/newJ2k/postProcessing/GetOperator.kt b/nj2k/testData/newJ2k/postProcessing/GetOperator.kt index 54a7305db4b..2130fcffdb3 100644 --- a/nj2k/testData/newJ2k/postProcessing/GetOperator.kt +++ b/nj2k/testData/newJ2k/postProcessing/GetOperator.kt @@ -1,5 +1,6 @@ import javaApi.JavaClass import kotlinApi.KotlinClass +import java.util.HashMap internal class X { operator fun get(index: Int): Int { diff --git a/nj2k/testData/newJ2k/postProcessing/java8MapForEachWithFullJdk.kt b/nj2k/testData/newJ2k/postProcessing/java8MapForEachWithFullJdk.kt index f5aec5bc428..ccf81d1ae6e 100644 --- a/nj2k/testData/newJ2k/postProcessing/java8MapForEachWithFullJdk.kt +++ b/nj2k/testData/newJ2k/postProcessing/java8MapForEachWithFullJdk.kt @@ -1,3 +1,5 @@ +import java.util.HashMap + internal class Test { fun test(map: HashMap) { map.forEach { (key: String, value: String) -> foo(key, value) } diff --git a/nj2k/testData/newJ2k/projections/projections.kt b/nj2k/testData/newJ2k/projections/projections.kt index 4e67b422fdb..415b7fe880e 100644 --- a/nj2k/testData/newJ2k/projections/projections.kt +++ b/nj2k/testData/newJ2k/projections/projections.kt @@ -1,3 +1,5 @@ +import java.util.ArrayList + internal class C { fun foo1(src: Collection) { val t = src.iterator().next() diff --git a/nj2k/testData/newJ2k/rawGenerics/kt-540-map.kt b/nj2k/testData/newJ2k/rawGenerics/kt-540-map.kt index 4867a12bb33..5a56eda21e6 100644 --- a/nj2k/testData/newJ2k/rawGenerics/kt-540-map.kt +++ b/nj2k/testData/newJ2k/rawGenerics/kt-540-map.kt @@ -1,5 +1,7 @@ package demo +import java.util.HashMap + internal class Test { fun main() { val commonMap: HashMap = HashMap() diff --git a/nj2k/testData/newJ2k/rawGenerics/kt-540.kt b/nj2k/testData/newJ2k/rawGenerics/kt-540.kt index 0fb5a935603..fc32320fbc0 100644 --- a/nj2k/testData/newJ2k/rawGenerics/kt-540.kt +++ b/nj2k/testData/newJ2k/rawGenerics/kt-540.kt @@ -1,5 +1,7 @@ package demo +import java.util.ArrayList + internal class Test { fun main() { val common: List = ArrayList() diff --git a/nj2k/testData/newJ2k/toKotlinClasses/LibraryFunctions.kt b/nj2k/testData/newJ2k/toKotlinClasses/LibraryFunctions.kt index 6334d777fe3..1d7e0207db9 100644 --- a/nj2k/testData/newJ2k/toKotlinClasses/LibraryFunctions.kt +++ b/nj2k/testData/newJ2k/toKotlinClasses/LibraryFunctions.kt @@ -1,5 +1,7 @@ package demo +import java.util.ArrayList + class TestJava { fun f(result: Function1) { result.invoke("a") diff --git a/nj2k/testData/newJ2k/typeParameters/needTypeArgs.kt b/nj2k/testData/newJ2k/typeParameters/needTypeArgs.kt index bbfaa0555e6..3ba80b88166 100644 --- a/nj2k/testData/newJ2k/typeParameters/needTypeArgs.kt +++ b/nj2k/testData/newJ2k/typeParameters/needTypeArgs.kt @@ -1,3 +1,5 @@ +import java.util.HashMap + internal class A { fun foo() { val map1: Map = getMap1()