New J2K: Add import statement conversion

This commit is contained in:
Ilya Kirillov
2018-12-01 15:50:50 +03:00
committed by Ilya Kirillov
parent a19ae4bcc2
commit 1faaada01f
2 changed files with 93 additions and 0 deletions
@@ -61,6 +61,7 @@ object ConversionsRunner {
+StaticsToCompanionExtractConversion()
+ClassToObjectPromotionConversion(context)
+LabeledStatementConversion()
+ImportStatementConversion()
+SortClassMembersConversion()
}
@@ -0,0 +1,92 @@
/*
* 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.j2k.conversions
import org.jetbrains.kotlin.j2k.tree.*
import org.jetbrains.kotlin.j2k.tree.impl.JKImportStatementImpl
import org.jetbrains.kotlin.j2k.tree.impl.JKNameIdentifierImpl
import org.jetbrains.kotlin.j2k.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 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(".")
}
override fun visitTreeElement(treeElement: JKTreeElement) {
treeElement.acceptChildren(this)
}
override fun visitJavaNewExpression(javaNewExpression: JKJavaNewExpression) {
unfilteredCollectedFqNames += javaNewExpression.classSymbol.fqName!!
javaNewExpression.acceptChildren(this)
}
override fun visitTypeElement(typeElement: JKTypeElement, data: Nothing?) {
val classType = typeElement.type as? JKClassType ?: return
unfilteredCollectedFqNames += classType.classReference.fqName!!
}
override fun visitClassLiteralExpression(classLiteralExpression: JKClassLiteralExpression) {
val type = classLiteralExpression.classType.type
if (type is JKClassType) {
unfilteredCollectedFqNames += type.classReference.fqName!!
}
classLiteralExpression.acceptChildren(this)
}
}
}