New J2K: Save unused imports

This commit is contained in:
Ilya Kirillov
2019-03-13 14:53:02 +03:00
committed by Ilya Kirillov
parent a7d2238af4
commit 658f763887
3 changed files with 42 additions and 20 deletions
@@ -28,8 +28,10 @@ import com.intellij.psi.impl.source.tree.java.PsiLabeledStatementImpl
import com.intellij.psi.impl.source.tree.java.PsiLiteralExpressionImpl
import com.intellij.psi.impl.source.tree.java.PsiNewExpressionImpl
import com.intellij.psi.javadoc.PsiDocComment
import com.intellij.psi.search.searches.ReferencesSearch
import com.intellij.psi.tree.IElementType
import com.intellij.psi.util.InheritanceUtil
import com.intellij.psi.util.PsiTreeUtil
import com.intellij.psi.util.PsiUtil
import org.jetbrains.kotlin.asJava.classes.KtLightClassForFacade
import org.jetbrains.kotlin.asJava.elements.KtLightField
@@ -53,22 +55,39 @@ import org.jetbrains.kotlin.utils.addToStdlib.safeAs
class JavaToJKTreeBuilder(
var symbolProvider: JKSymbolProvider,
private val converterServices: NewJavaToKotlinServices
converterServices: NewJavaToKotlinServices
) {
private val expressionTreeMapper = ExpressionTreeMapper()
val referenceSearcher: ReferenceSearcher = converterServices.oldServices.referenceSearcher
private val referenceSearcher: ReferenceSearcher = converterServices.oldServices.referenceSearcher
private val declarationMapper = DeclarationMapper(expressionTreeMapper)
private fun PsiJavaFile.toJK(): JKFile =
JKFileImpl(
packageStatement?.toJK() ?: JKPackageDeclarationImpl(JKNameIdentifierImpl("")),
importList?.importStatements?.map { it.toJK() }.orEmpty(),
importList?.toJK().orEmpty(),
with(declarationMapper) { classes.map { it.toJK() } }
)
private fun PsiImportList.toJK(): List<JKImportStatement> =
importStatements.filter { import ->
when {
import.isSingleUnusedImport() -> true
import.isOnDemand -> true
else -> false
}
}.map { it.toJK() }
private fun PsiImportStatement.isSingleUnusedImport(): Boolean {
if (isOnDemand) return false
val target = resolve() ?: return true
val ussages = ReferencesSearch.search(target).toList()
return ussages.size == 1 && PsiTreeUtil.isAncestor(this, ussages.iterator().next().element, true)
}
private fun PsiPackageStatement.toJK(): JKPackageDeclaration =
JKPackageDeclarationImpl(JKNameIdentifierImpl(packageName))
.also {
@@ -12,10 +12,10 @@ package org.jetbrains.kotlin.nj2k.conversions
import com.intellij.psi.CommonClassNames
import org.jetbrains.kotlin.nj2k.tree.*
import org.jetbrains.kotlin.nj2k.tree.impl.JKClassSymbol
import org.jetbrains.kotlin.nj2k.tree.impl.JKImportStatementImpl
import org.jetbrains.kotlin.nj2k.tree.impl.JKNameIdentifierImpl
import org.jetbrains.kotlin.nj2k.tree.impl.JKUniverseClassSymbol
import org.jetbrains.kotlin.nj2k.tree.impl.JKSymbol
import org.jetbrains.kotlin.nj2k.tree.impl.fqNameToImport
import org.jetbrains.kotlin.nj2k.tree.visitors.JKVisitorVoid
@@ -27,7 +27,6 @@ class ImportStatementConversion : RecursiveApplicableConversionBase() {
element.importList += JKImportStatementImpl(JKNameIdentifierImpl(import))
}
}
element.importList = element.importList.filter { it.name.value !in importExceptionList }
return recurse(element)
}
@@ -43,9 +42,6 @@ class ImportStatementConversion : RecursiveApplicableConversionBase() {
"java.util.LinkedHashSet"
)
private fun importIsInPackage(import: String, packageName: String) =
'.' !in import.substringAfter(packageName)
private fun List<JKImportStatement>.containsImport(import: String) =
asSequence()
@@ -86,9 +82,9 @@ class ImportStatementConversion : RecursiveApplicableConversionBase() {
it.substringBeforeLast(".") !in defaultImports && it.contains(".")
}
private fun addClassSymbol(symbol: JKClassSymbol) {
if (symbol !is JKUniverseClassSymbol) {
unfilteredCollectedFqNames += symbol.fqName
private fun addSymbol(symbol: JKSymbol) {
symbol.fqNameToImport()?.also { fqName ->
unfilteredCollectedFqNames += fqName
}
}
@@ -97,32 +93,32 @@ class ImportStatementConversion : RecursiveApplicableConversionBase() {
}
override fun visitClassAccessExpression(classAccessExpression: JKClassAccessExpression) {
addClassSymbol(classAccessExpression.identifier)
addSymbol(classAccessExpression.identifier)
}
override fun visitJavaNewExpression(javaNewExpression: JKJavaNewExpression) {
addClassSymbol(javaNewExpression.classSymbol)
addSymbol(javaNewExpression.classSymbol)
javaNewExpression.acceptChildren(this)
}
override fun visitTypeElement(typeElement: JKTypeElement, data: Nothing?) {
override fun visitTypeElement(typeElement: JKTypeElement) {
val classType = typeElement.type as? JKClassType ?: return
addClassSymbol(classType.classReference)
addSymbol(classType.classReference)
}
override fun visitFieldAccessExpression(fieldAccessExpression: JKFieldAccessExpression) {
unfilteredCollectedFqNames += fieldAccessExpression.identifier.fqName
addSymbol(fieldAccessExpression.identifier)
}
override fun visitMethodCallExpression(methodCallExpression: JKMethodCallExpression) {
unfilteredCollectedFqNames += methodCallExpression.identifier.fqName
addSymbol(methodCallExpression.identifier)
methodCallExpression.acceptChildren(this)
}
override fun visitClassLiteralExpression(classLiteralExpression: JKClassLiteralExpression) {
val type = classLiteralExpression.classType.type
if (type is JKClassType) {
addClassSymbol(type.classReference)
if (type is JKClassType){
addSymbol(type.classReference)
}
classLiteralExpression.acceptChildren(this)
}
@@ -52,6 +52,13 @@ abstract class JKUniverseSymbol<T : JKTreeElement> : JKNamedSymbol {
}
}
fun JKSymbol.fqNameToImport(): String? =
when {
this is JKClassSymbol && this !is JKUniverseClassSymbol -> fqName
else -> null
}
interface JKClassSymbol : JKNamedSymbol