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
This commit is contained in:
Ilya Kirillov
2019-06-08 20:53:02 +03:00
parent d0e3ab1beb
commit 5f8b5efd66
26 changed files with 62 additions and 40 deletions
@@ -279,5 +279,6 @@ private val processings: List<GeneralPostProcessing> = listOf(
RemoveForExpressionLoopParameterTypeProcessing()
),
formatCodeProcessing,
optimizeImportsProcessing
optimizeImportsProcessing,
shortenReferencesProcessing
)
@@ -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<KtLightElement<*, *>>()?.kotlinOrigin?.getKotlinFqName()?.asString()
?: target.safeAs<KtLightClass>()?.containingFile?.safeAs<KtFile>()?.packageFqName?.asString()?.let { "$it.*" }
?: target.safeAs<KtLightClassForFacade>()?.fqName?.parent()?.asString()?.let { "$it.*" }
?: target.safeAs<KtLightClassForDecompiledDeclaration>()?.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) {
@@ -1,6 +1,8 @@
// !forceNotNullTypes: false
// !specifyLocalVariableTypeByDefault: true
import java.util.HashSet
internal class Foo {
fun foo(o: HashSet<*>) {
val o2: HashSet<*> = o
@@ -1,3 +1,5 @@
import java.util.HashSet
internal class Foo {
fun foo(o: HashSet<*>) {
var foo = 0
+2
View File
@@ -2,6 +2,8 @@
// ERROR: Type inference failed: Not enough information to infer parameter K in constructor HashMap<K : Any!, V : Any!>(initialCapacity: Int) Please specify it explicitly.
package demo
import java.util.HashMap
internal class Test {
constructor() {}
constructor(s: String?) {}
@@ -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
}
@@ -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
}
+2
View File
@@ -1,3 +1,5 @@
import java.util.ArrayList
internal class A {
private val list1: ArrayList<String> = ArrayList()
private val list2: MutableList<String> = ArrayList()
+2
View File
@@ -1,3 +1,5 @@
import java.util.ArrayList
internal class C {
fun foo1(list: MutableList<String>) {
for (i in list.indices) {
+2
View File
@@ -1,3 +1,5 @@
import java.util.HashMap
internal object Test {
@JvmStatic
fun main(args: Array<String>) {
@@ -77,7 +77,7 @@ internal class Java8Class {
}
fun testGenericFunctions() {
val emptyList: Function0<kotlin.collections.List<String>> = { emptyList() }
val emptyList: Function0<List<String>> = { emptyList() }
val list = emptyList.invoke()
list[0]
}
+3 -3
View File
@@ -122,10 +122,10 @@ internal class Java8Class {
}
fun testGenericFunctions() {
val emptyList: JFunction1<kotlin.collections.List<String>> = JFunction1 { emptyList() }
val emptyList: JFunction1<List<String>> = JFunction1 { emptyList() }
emptyList.foo()
MethodReferenceHelperClass.staticFun1(JFunction1<kotlin.collections.List<String>> { emptyList() })
h.memberFun1(JFunction1<kotlin.collections.List<String>> { emptyList() })
MethodReferenceHelperClass.staticFun1(JFunction1<List<String>> { emptyList() })
h.memberFun1(JFunction1<List<String>> { emptyList() })
}
fun memberFun(): Int {
+2
View File
@@ -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 : String?>(t: T?)
class Java {
internal fun test() {
+1 -3
View File
@@ -1,5 +1,3 @@
import kotlin.collections.Map.Entry
class A {
internal fun foo(o: Entry<Any?, Any?>?) {}
internal fun foo(o: Map.Entry<Any?, Any?>?) {}
}
@@ -1,7 +1,7 @@
import kotlinApi.KotlinClass
import kotlinApi.KotlinClass.Companion.CONST
class C {
internal fun bar() {
println(KotlinClass.CONST)
println(CONST)
}
}
+2
View File
@@ -1,3 +1,5 @@
import java.util.ArrayList
class TestMutableCollection {
val list: MutableList<String> = ArrayList()
@@ -1,3 +1,5 @@
import java.util.ArrayList
internal class User {
fun main() {
val list: List<String> = ArrayList()
@@ -1,5 +1,7 @@
package org.test
import java.util.ArrayList
internal class Member
internal class User {
fun main() {
+2
View File
@@ -1,5 +1,7 @@
package test
import java.util.ArrayList
class Test {
private var myProp: String? = null
private var myIntProp: Int? = null
+1
View File
@@ -1,5 +1,6 @@
import javaApi.JavaClass
import kotlinApi.KotlinClass
import java.util.HashMap
internal class X {
operator fun get(index: Int): Int {
@@ -1,3 +1,5 @@
import java.util.HashMap
internal class Test {
fun test(map: HashMap<String, String>) {
map.forEach { (key: String, value: String) -> foo(key, value) }
+2
View File
@@ -1,3 +1,5 @@
import java.util.ArrayList
internal class C<T> {
fun foo1(src: Collection<T>) {
val t = src.iterator().next()
+2
View File
@@ -1,5 +1,7 @@
package demo
import java.util.HashMap
internal class Test {
fun main() {
val commonMap: HashMap<String, Int> = HashMap()
+2
View File
@@ -1,5 +1,7 @@
package demo
import java.util.ArrayList
internal class Test {
fun main() {
val common: List<String> = ArrayList()
@@ -1,5 +1,7 @@
package demo
import java.util.ArrayList
class TestJava {
fun f(result: Function1<String, Unit?>) {
result.invoke("a")
+2
View File
@@ -1,3 +1,5 @@
import java.util.HashMap
internal class A {
fun foo() {
val map1: Map<String, Int> = getMap1()