New J2K: Collect imports to ImportStorage, not to JKFle
This commit is contained in:
committed by
Ilya Kirillov
parent
9d9c9f40db
commit
9fb6cfc26e
@@ -78,10 +78,11 @@ object ConversionsRunner {
|
|||||||
|
|
||||||
//Kotlin --> Kotlin conversions
|
//Kotlin --> Kotlin conversions
|
||||||
+InnerClassConversion()
|
+InnerClassConversion()
|
||||||
|
+FilterImportsConversion()
|
||||||
+StaticsToCompanionExtractConversion()
|
+StaticsToCompanionExtractConversion()
|
||||||
+InterfaceWithFieldConversion()
|
+InterfaceWithFieldConversion()
|
||||||
+ClassToObjectPromotionConversion(context)
|
+ClassToObjectPromotionConversion(context)
|
||||||
+ImportStatementConversion()
|
+CollectImportsConversion(context)
|
||||||
+SortClassMembersConversion()
|
+SortClassMembersConversion()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,14 +5,28 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.nj2k
|
package org.jetbrains.kotlin.nj2k
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.load.java.NULLABILITY_ANNOTATIONS
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
|
||||||
class ImportStorage {
|
class ImportStorage {
|
||||||
private val imports = mutableSetOf<FqName>()
|
private val imports = mutableSetOf<FqName>()
|
||||||
|
|
||||||
fun addImport(import: FqName) {
|
fun addImport(import: FqName) {
|
||||||
imports += import
|
if (isImportNeeded(import)) {
|
||||||
|
imports += import
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getImports(): Set<FqName> = imports
|
fun getImports(): Set<FqName> = imports
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun isImportNeeded(fqName: FqName): Boolean {
|
||||||
|
if (fqName in NULLABILITY_ANNOTATIONS) return false
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun isImportNeeded(fqName: String): Boolean =
|
||||||
|
isImportNeeded(FqName(fqName))
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||||
|
* that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||||
|
* that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.nj2k.conversions
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
import org.jetbrains.kotlin.nj2k.ConversionContext
|
||||||
|
import org.jetbrains.kotlin.nj2k.tree.*
|
||||||
|
import org.jetbrains.kotlin.nj2k.tree.impl.JKSymbol
|
||||||
|
import org.jetbrains.kotlin.nj2k.tree.impl.fqNameToImport
|
||||||
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
|
|
||||||
|
|
||||||
|
class CollectImportsConversion(private val context: ConversionContext) : RecursiveApplicableConversionBase() {
|
||||||
|
override fun applyToElement(element: JKTreeElement): JKTreeElement {
|
||||||
|
when (element) {
|
||||||
|
is JKClassAccessExpression -> addSymbol(element.identifier)
|
||||||
|
is JKFieldAccessExpression -> addSymbol(element.identifier)
|
||||||
|
is JKMethodCallExpression -> addSymbol(element.identifier)
|
||||||
|
is JKAnnotation -> addSymbol(element.classSymbol)
|
||||||
|
is JKJavaNewExpression -> addSymbol(element.classSymbol)
|
||||||
|
is JKInheritanceInfo -> {
|
||||||
|
element.implements
|
||||||
|
}
|
||||||
|
is JKTypeElement -> {
|
||||||
|
element.type.safeAs<JKClassType>()?.also {
|
||||||
|
addSymbol(it.classReference)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return recurse(element)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun addSymbol(symbol: JKSymbol) {
|
||||||
|
symbol.fqNameToImport()?.also { fqName ->
|
||||||
|
context.importStorage.addImport(FqName(fqName))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||||
|
* that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.nj2k.conversions
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.nj2k.ImportStorage
|
||||||
|
import org.jetbrains.kotlin.nj2k.tree.JKFile
|
||||||
|
import org.jetbrains.kotlin.nj2k.tree.JKTreeElement
|
||||||
|
|
||||||
|
|
||||||
|
class FilterImportsConversion : RecursiveApplicableConversionBase() {
|
||||||
|
override fun applyToElement(element: JKTreeElement): JKTreeElement {
|
||||||
|
if (element is JKFile) {
|
||||||
|
for (import in element.importList) {
|
||||||
|
if (!ImportStorage.isImportNeeded(import.name.value)) {
|
||||||
|
element.importList -= import
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return recurse(element)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,131 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
|
||||||
* that can be found in the license/LICENSE.txt file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
|
||||||
* that can be found in the license/LICENSE.txt file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.kotlin.nj2k.conversions
|
|
||||||
|
|
||||||
import com.intellij.psi.CommonClassNames
|
|
||||||
import org.jetbrains.kotlin.nj2k.tree.*
|
|
||||||
import org.jetbrains.kotlin.nj2k.tree.impl.JKImportStatementImpl
|
|
||||||
import org.jetbrains.kotlin.nj2k.tree.impl.JKNameIdentifierImpl
|
|
||||||
import org.jetbrains.kotlin.nj2k.tree.impl.JKSymbol
|
|
||||||
import org.jetbrains.kotlin.nj2k.tree.impl.fqNameToImport
|
|
||||||
import org.jetbrains.kotlin.nj2k.tree.visitors.JKVisitorVoid
|
|
||||||
|
|
||||||
|
|
||||||
class ImportStatementConversion : RecursiveApplicableConversionBase() {
|
|
||||||
override fun applyToElement(element: JKTreeElement): JKTreeElement {
|
|
||||||
if (element !is JKFile) return recurse(element)
|
|
||||||
for (import in element.declarationList.collectImports()) {
|
|
||||||
if (!element.importList.containsImport(import)) {
|
|
||||||
element.importList += JKImportStatementImpl(JKNameIdentifierImpl(import))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return recurse(element)
|
|
||||||
}
|
|
||||||
|
|
||||||
private val importExceptionList =
|
|
||||||
listOf(
|
|
||||||
CommonClassNames.JAVA_UTIL_ARRAY_LIST,
|
|
||||||
CommonClassNames.JAVA_UTIL_LIST,
|
|
||||||
CommonClassNames.JAVA_UTIL_HASH_SET,
|
|
||||||
CommonClassNames.JAVA_UTIL_HASH_MAP,
|
|
||||||
CommonClassNames.JAVA_UTIL_COLLECTION,
|
|
||||||
CommonClassNames.JAVA_UTIL_ITERATOR,
|
|
||||||
"java.util.LinkedHashMap",
|
|
||||||
"java.util.LinkedHashSet"
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
private fun List<JKImportStatement>.containsImport(import: String) =
|
|
||||||
asSequence()
|
|
||||||
.map { it.name.value }
|
|
||||||
.any {
|
|
||||||
it == import ||
|
|
||||||
it.endsWith("*") && import.substringBeforeLast(".") == it.substringBeforeLast(".*")
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun List<JKDeclaration>.collectImports(): List<String> {
|
|
||||||
val collectImportsVisitor = CollectImportsVisitor()
|
|
||||||
forEach {
|
|
||||||
it.accept(collectImportsVisitor)
|
|
||||||
}
|
|
||||||
return collectImportsVisitor.collectedFqNames
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private class CollectImportsVisitor : JKVisitorVoid {
|
|
||||||
private val unfilteredCollectedFqNames = mutableSetOf<String>()
|
|
||||||
|
|
||||||
private val defaultImports =
|
|
||||||
listOf(
|
|
||||||
"kotlin",
|
|
||||||
"kotlin.annotation",
|
|
||||||
"kotlin.collections",
|
|
||||||
"kotlin.comparisons",
|
|
||||||
"kotlin.io",
|
|
||||||
"kotlin.ranges",
|
|
||||||
"kotlin.sequences",
|
|
||||||
"kotlin.text",
|
|
||||||
"java.lang",
|
|
||||||
"kotlin.jvm"
|
|
||||||
)
|
|
||||||
|
|
||||||
val collectedFqNames
|
|
||||||
get() = unfilteredCollectedFqNames.filter {
|
|
||||||
it.substringBeforeLast(".") !in defaultImports && it.contains(".")
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun addSymbol(symbol: JKSymbol) {
|
|
||||||
symbol.fqNameToImport()?.also { fqName ->
|
|
||||||
unfilteredCollectedFqNames += fqName
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitTreeElement(treeElement: JKTreeElement) {
|
|
||||||
treeElement.acceptChildren(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitClassAccessExpression(classAccessExpression: JKClassAccessExpression) {
|
|
||||||
addSymbol(classAccessExpression.identifier)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitJavaNewExpression(javaNewExpression: JKJavaNewExpression) {
|
|
||||||
addSymbol(javaNewExpression.classSymbol)
|
|
||||||
javaNewExpression.acceptChildren(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitTypeElement(typeElement: JKTypeElement) {
|
|
||||||
val classType = typeElement.type as? JKClassType ?: return
|
|
||||||
addSymbol(classType.classReference)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitFieldAccessExpression(fieldAccessExpression: JKFieldAccessExpression) {
|
|
||||||
addSymbol(fieldAccessExpression.identifier)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitMethodCallExpression(methodCallExpression: JKMethodCallExpression) {
|
|
||||||
addSymbol(methodCallExpression.identifier)
|
|
||||||
methodCallExpression.acceptChildren(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitAnnotation(annotation: JKAnnotation) {
|
|
||||||
addSymbol(annotation.classSymbol)
|
|
||||||
annotation.acceptChildren(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitClassLiteralExpression(classLiteralExpression: JKClassLiteralExpression) {
|
|
||||||
val type = classLiteralExpression.classType.type
|
|
||||||
if (type is JKClassType) {
|
|
||||||
addSymbol(type.classReference)
|
|
||||||
}
|
|
||||||
classLiteralExpression.acceptChildren(this)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user