From 9fb6cfc26e8252eb57b14f9f7df411ad305db330 Mon Sep 17 00:00:00 2001 From: Ilya Kirillov Date: Tue, 26 Mar 2019 22:36:16 +0300 Subject: [PATCH] New J2K: Collect imports to ImportStorage, not to JKFle --- .../kotlin/nj2k/ConversionsRunner.kt | 3 +- .../jetbrains/kotlin/nj2k/ImportStorage.kt | 16 ++- .../conversions/CollectImportsConversion.kt | 46 ++++++ .../conversions/FilterImportsConversion.kt | 24 ++++ .../conversions/ImportStatementConversion.kt | 131 ------------------ 5 files changed, 87 insertions(+), 133 deletions(-) create mode 100644 nj2k/src/org/jetbrains/kotlin/nj2k/conversions/CollectImportsConversion.kt create mode 100644 nj2k/src/org/jetbrains/kotlin/nj2k/conversions/FilterImportsConversion.kt delete mode 100644 nj2k/src/org/jetbrains/kotlin/nj2k/conversions/ImportStatementConversion.kt diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/ConversionsRunner.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/ConversionsRunner.kt index ff15215d025..f072fa85524 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/ConversionsRunner.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/ConversionsRunner.kt @@ -78,10 +78,11 @@ object ConversionsRunner { //Kotlin --> Kotlin conversions +InnerClassConversion() + +FilterImportsConversion() +StaticsToCompanionExtractConversion() +InterfaceWithFieldConversion() +ClassToObjectPromotionConversion(context) - +ImportStatementConversion() + +CollectImportsConversion(context) +SortClassMembersConversion() } diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/ImportStorage.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/ImportStorage.kt index 7e123894d89..df21ce85ff6 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/ImportStorage.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/ImportStorage.kt @@ -5,14 +5,28 @@ package org.jetbrains.kotlin.nj2k +import org.jetbrains.kotlin.load.java.NULLABILITY_ANNOTATIONS import org.jetbrains.kotlin.name.FqName class ImportStorage { private val imports = mutableSetOf() fun addImport(import: FqName) { - imports += import + if (isImportNeeded(import)) { + imports += import + } } fun getImports(): Set = 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)) + + } } \ No newline at end of file diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/CollectImportsConversion.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/CollectImportsConversion.kt new file mode 100644 index 00000000000..e5a434d1864 --- /dev/null +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/CollectImportsConversion.kt @@ -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()?.also { + addSymbol(it.classReference) + } + } + } + return recurse(element) + } + + private fun addSymbol(symbol: JKSymbol) { + symbol.fqNameToImport()?.also { fqName -> + context.importStorage.addImport(FqName(fqName)) + } + } +} \ No newline at end of file diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/FilterImportsConversion.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/FilterImportsConversion.kt new file mode 100644 index 00000000000..34867594ca0 --- /dev/null +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/FilterImportsConversion.kt @@ -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) + } +} \ No newline at end of file diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/ImportStatementConversion.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/ImportStatementConversion.kt deleted file mode 100644 index a758af9b135..00000000000 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/ImportStatementConversion.kt +++ /dev/null @@ -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.containsImport(import: String) = - asSequence() - .map { it.name.value } - .any { - it == import || - it.endsWith("*") && import.substringBeforeLast(".") == it.substringBeforeLast(".*") - } - - private fun List.collectImports(): List { - val collectImportsVisitor = CollectImportsVisitor() - forEach { - it.accept(collectImportsVisitor) - } - return collectImportsVisitor.collectedFqNames - } - - - private class CollectImportsVisitor : JKVisitorVoid { - private val unfilteredCollectedFqNames = mutableSetOf() - - 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) - } - } -} \ No newline at end of file