J2K ImportPath: kotlinify
This commit is contained in:
@@ -28,8 +28,8 @@ object JvmPlatform : TargetPlatform("JVM") {
|
||||
override fun getDefaultImports(languageVersionSettings: LanguageVersionSettings): List<ImportPath> = ArrayList<ImportPath>().apply {
|
||||
addAll(Default.getDefaultImports(languageVersionSettings))
|
||||
|
||||
add(ImportPath("java.lang.*"))
|
||||
add(ImportPath("kotlin.jvm.*"))
|
||||
add(ImportPath.fromString("java.lang.*"))
|
||||
add(ImportPath.fromString("kotlin.jvm.*"))
|
||||
|
||||
fun addAllClassifiersFromScope(scope: MemberScope) {
|
||||
for (descriptor in scope.getContributedDescriptors(DescriptorKindFilter.CLASSIFIERS, MemberScope.ALL_NAME_FILTER)) {
|
||||
|
||||
@@ -384,7 +384,7 @@ class KtPsiFactory(private val project: Project) {
|
||||
}
|
||||
|
||||
fun createImportDirective(importPath: ImportPath): KtImportDirective {
|
||||
if (importPath.fqnPart().isRoot) {
|
||||
if (importPath.fqName.isRoot) {
|
||||
throw IllegalArgumentException("import path must not be empty")
|
||||
}
|
||||
|
||||
|
||||
@@ -20,29 +20,7 @@ import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.renderer.*
|
||||
|
||||
class ImportPath {
|
||||
private val fqName: FqName
|
||||
val alias: Name?
|
||||
val isAllUnder: Boolean
|
||||
|
||||
@JvmOverloads constructor(fqName: FqName, isAllUnder: Boolean, alias: Name? = null) {
|
||||
this.fqName = fqName
|
||||
this.isAllUnder = isAllUnder
|
||||
this.alias = alias
|
||||
}
|
||||
|
||||
constructor(pathStr: String) {
|
||||
if (pathStr.endsWith(".*")) {
|
||||
this.isAllUnder = true
|
||||
this.fqName = FqName(pathStr.substring(0, pathStr.length - 2))
|
||||
}
|
||||
else {
|
||||
this.isAllUnder = false
|
||||
this.fqName = FqName(pathStr)
|
||||
}
|
||||
|
||||
alias = null
|
||||
}
|
||||
data class ImportPath @JvmOverloads constructor(val fqName: FqName, val isAllUnder: Boolean, val alias: Name? = null) {
|
||||
|
||||
val pathStr: String
|
||||
get() = fqName.toUnsafe().render() + if (isAllUnder) ".*" else ""
|
||||
@@ -51,10 +29,6 @@ class ImportPath {
|
||||
return pathStr + if (alias != null) " as " + alias.asString() else ""
|
||||
}
|
||||
|
||||
fun fqnPart(): FqName {
|
||||
return fqName
|
||||
}
|
||||
|
||||
fun hasAlias(): Boolean {
|
||||
return alias != null
|
||||
}
|
||||
@@ -68,23 +42,15 @@ class ImportPath {
|
||||
return null
|
||||
}
|
||||
|
||||
override fun equals(o: Any?): Boolean {
|
||||
if (this === o) return true
|
||||
if (o == null || javaClass != o.javaClass) return false
|
||||
companion object {
|
||||
@JvmStatic fun fromString(pathStr: String): ImportPath {
|
||||
if (pathStr.endsWith(".*")) {
|
||||
return ImportPath(FqName(pathStr.substring(0, pathStr.length - 2)), isAllUnder = true)
|
||||
}
|
||||
else {
|
||||
return ImportPath(FqName(pathStr), isAllUnder = false)
|
||||
|
||||
val path = o as ImportPath?
|
||||
|
||||
if (isAllUnder != path!!.isAllUnder) return false
|
||||
if (if (alias != null) alias != path.alias else path.alias != null) return false
|
||||
if (fqName != path.fqName) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = fqName.hashCode()
|
||||
result = 31 * result + (alias?.hashCode() ?: 0)
|
||||
result = 31 * result + if (isAllUnder) 1 else 0
|
||||
return result
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,16 +43,18 @@ abstract class TargetPlatform(val platformName: String) {
|
||||
|
||||
object Default : TargetPlatform("Default") {
|
||||
override fun getDefaultImports(languageVersionSettings: LanguageVersionSettings): List<ImportPath> = ArrayList<ImportPath>().apply {
|
||||
add(ImportPath("kotlin.*"))
|
||||
add(ImportPath("kotlin.annotation.*"))
|
||||
add(ImportPath("kotlin.collections.*"))
|
||||
add(ImportPath("kotlin.ranges.*"))
|
||||
add(ImportPath("kotlin.sequences.*"))
|
||||
add(ImportPath("kotlin.text.*"))
|
||||
add(ImportPath("kotlin.io.*"))
|
||||
listOf(
|
||||
"kotlin.*",
|
||||
"kotlin.annotation.*",
|
||||
"kotlin.collections.*",
|
||||
"kotlin.ranges.*",
|
||||
"kotlin.sequences.*",
|
||||
"kotlin.text.*",
|
||||
"kotlin.io.*"
|
||||
).forEach { add(ImportPath.fromString(it)) }
|
||||
|
||||
if (languageVersionSettings.supportsFeature(LanguageFeature.DefaultImportOfPackageKotlinComparisons)) {
|
||||
add(ImportPath("kotlin.comparisons.*"))
|
||||
add(ImportPath.fromString("kotlin.comparisons.*"))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ class DefaultImportProvider(
|
||||
defaultImports
|
||||
.filter { it.isAllUnder }
|
||||
.mapNotNull {
|
||||
it.fqnPart().takeIf { !it.isSubpackageOf(KotlinBuiltIns.BUILT_INS_PACKAGE_FQ_NAME) }
|
||||
it.fqName.takeIf { !it.isSubpackageOf(KotlinBuiltIns.BUILT_INS_PACKAGE_FQ_NAME) }
|
||||
}
|
||||
val nonKotlinAliasedTypeFqNames =
|
||||
builtinTypeAliases
|
||||
|
||||
@@ -71,7 +71,7 @@ class FileScopeFactory(
|
||||
|
||||
val extraImports = file.originalFile.virtualFile?.let { vFile ->
|
||||
val scriptExternalDependencies = getScriptExternalDependencies(vFile, file.project)
|
||||
ktImportsFactory.createImportDirectives(scriptExternalDependencies?.imports?.map(::ImportPath).orEmpty())
|
||||
ktImportsFactory.createImportDirectives(scriptExternalDependencies?.imports?.map { ImportPath.fromString(it) }.orEmpty())
|
||||
}
|
||||
|
||||
val allImplicitImports = defaultImports concat extraImports
|
||||
|
||||
@@ -91,7 +91,7 @@ class OptimizedImportsBuilder(
|
||||
.mapNotNull { it.importPath }
|
||||
.filter {
|
||||
val aliasName = it.alias
|
||||
aliasName != null && aliasName != it.fqnPart().shortName()
|
||||
aliasName != null && aliasName != it.fqName.shortName()
|
||||
}
|
||||
.mapTo(importRules) { ImportRule.Add(it) }
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ private fun KtFile.buildAliasImportMap(): Multimap<String, String> {
|
||||
val importList = importList ?: return map
|
||||
for (import in importList.imports) {
|
||||
val aliasName = import.aliasName ?: continue
|
||||
val name = import.importPath?.fqnPart()?.shortName()?.asString() ?: continue
|
||||
val name = import.importPath?.fqName?.shortName()?.asString() ?: continue
|
||||
map.put(aliasName, name)
|
||||
}
|
||||
return map
|
||||
|
||||
@@ -45,17 +45,17 @@ fun PsiElement.getKotlinFqName(): FqName? {
|
||||
fun FqName.isImported(importPath: ImportPath, skipAliasedImports: Boolean = true): Boolean {
|
||||
return when {
|
||||
skipAliasedImports && importPath.hasAlias() -> false
|
||||
importPath.isAllUnder && !isRoot -> importPath.fqnPart() == this.parent()
|
||||
else -> importPath.fqnPart() == this
|
||||
importPath.isAllUnder && !isRoot -> importPath.fqName == this.parent()
|
||||
else -> importPath.fqName == this
|
||||
}
|
||||
}
|
||||
|
||||
fun ImportPath.isImported(alreadyImported: ImportPath): Boolean {
|
||||
return if (isAllUnder || hasAlias()) this == alreadyImported else fqnPart().isImported(alreadyImported)
|
||||
return if (isAllUnder || hasAlias()) this == alreadyImported else fqName.isImported(alreadyImported)
|
||||
}
|
||||
|
||||
private fun ImportPath.isImported(imports: Iterable<ImportPath>): Boolean = imports.any { isImported(it) }
|
||||
|
||||
fun ImportPath.isImported(imports: Iterable<ImportPath>, excludedFqNames: Iterable<FqName>): Boolean {
|
||||
return isImported(imports) && (isAllUnder || this.fqnPart() !in excludedFqNames)
|
||||
return isImported(imports) && (isAllUnder || this.fqName !in excludedFqNames)
|
||||
}
|
||||
|
||||
@@ -391,7 +391,7 @@ fun LookupElement.decorateAsStaticMember(
|
||||
val psiDocumentManager = PsiDocumentManager.getInstance(context.project)
|
||||
val file = context.file as KtFile
|
||||
|
||||
val addMemberImport = file.importDirectives.any { !it.isAllUnder && it.importPath?.fqnPart()?.parent() == containerFqName }
|
||||
val addMemberImport = file.importDirectives.any { !it.isAllUnder && it.importPath?.fqName?.parent() == containerFqName }
|
||||
|
||||
if (addMemberImport) {
|
||||
psiDocumentManager.commitAllDocuments()
|
||||
|
||||
@@ -34,7 +34,7 @@ class ImportableFqNameClassifier(private val file: KtFile) {
|
||||
init {
|
||||
for (import in file.importDirectives) {
|
||||
val importPath = import.importPath ?: continue
|
||||
val fqName = importPath.fqnPart()
|
||||
val fqName = importPath.fqName
|
||||
if (importPath.isAllUnder) {
|
||||
allUnderImports.add(fqName)
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ class KotlinUnusedImportInspection : AbstractKotlinInspection() {
|
||||
.asSequence()
|
||||
.mapNotNull { it.importPath }
|
||||
.filter { !it.isAllUnder && !it.hasAlias() }
|
||||
.map { it.fqnPart() }
|
||||
.map { it.fqName }
|
||||
.toSet()
|
||||
|
||||
val fqNames = HashSet<FqName>()
|
||||
@@ -95,10 +95,10 @@ class KotlinUnusedImportInspection : AbstractKotlinInspection() {
|
||||
false
|
||||
}
|
||||
else if (importPath.isAllUnder) {
|
||||
importPath.fqnPart() in parentFqNames
|
||||
importPath.fqName in parentFqNames
|
||||
}
|
||||
else {
|
||||
importPath.fqnPart() in fqNames
|
||||
importPath.fqName in fqNames
|
||||
}
|
||||
|
||||
if (!isUsed) {
|
||||
|
||||
+2
-2
@@ -134,8 +134,8 @@ object ReplaceWithAnnotationAnalyzer {
|
||||
// this solution doesn't support aliased default imports with a different alias
|
||||
// TODO: Create import directives from ImportPath, create ImportResolver, create LazyResolverScope, see FileScopeProviderImpl
|
||||
|
||||
return listOf(buildExplicitImportsScope(aliasImports.map { it.fqnPart() }, resolutionFacade, module)) +
|
||||
allUnderImports.map { module.getPackage(it.fqnPart()).memberScope.memberScopeAsImportingScope() }.asReversed()
|
||||
return listOf(buildExplicitImportsScope(aliasImports.map { it.fqName }, resolutionFacade, module)) +
|
||||
allUnderImports.map { module.getPackage(it.fqName).memberScope.memberScopeAsImportingScope() }.asReversed()
|
||||
}
|
||||
|
||||
private fun buildExplicitImportsScope(annotation: ReplaceWith, resolutionFacade: ResolutionFacade, module: ModuleDescriptor): ExplicitImportsScope {
|
||||
|
||||
@@ -121,7 +121,7 @@ class ImportInsertHelperImpl(private val project: Project) : ImportInsertHelper(
|
||||
|
||||
val imports = file.importDirectives
|
||||
|
||||
if (imports.any { !it.isAllUnder && it.importPath?.fqnPart() == targetFqName }) {
|
||||
if (imports.any { !it.isAllUnder && it.importPath?.fqName == targetFqName }) {
|
||||
return ImportDescriptorResult.FAIL
|
||||
}
|
||||
|
||||
@@ -132,7 +132,7 @@ class ImportInsertHelperImpl(private val project: Project) : ImportInsertHelper(
|
||||
else -> null
|
||||
}
|
||||
if (conflict != null
|
||||
&& imports.any { !it.isAllUnder && it.importPath?.fqnPart() == conflict.importableFqName && it.importPath?.importedName == name }
|
||||
&& imports.any { !it.isAllUnder && it.importPath?.fqName == conflict.importableFqName && it.importPath?.importedName == name }
|
||||
) {
|
||||
return ImportDescriptorResult.FAIL
|
||||
}
|
||||
@@ -187,7 +187,7 @@ class ImportInsertHelperImpl(private val project: Project) : ImportInsertHelper(
|
||||
|
||||
val importsFromPackage = imports.count {
|
||||
val path = it.importPath
|
||||
path != null && !path.isAllUnder && !path.hasAlias() && path.fqnPart().parent() == containerFqName
|
||||
path != null && !path.isAllUnder && !path.hasAlias() && path.fqName.parent() == containerFqName
|
||||
}
|
||||
val nameCountToUseStar = if (target.containingDeclaration is ClassDescriptor)
|
||||
codeStyleSettings.NAME_COUNT_TO_USE_STAR_IMPORT_FOR_MEMBERS
|
||||
@@ -217,7 +217,7 @@ class ImportInsertHelperImpl(private val project: Project) : ImportInsertHelper(
|
||||
.mapNotNull {
|
||||
val importPath = it.importPath
|
||||
if (importPath != null) {
|
||||
val fqName = importPath.fqnPart()
|
||||
val fqName = importPath.fqName
|
||||
getMemberScope(fqName, moduleDescriptor)
|
||||
}
|
||||
else {
|
||||
@@ -300,7 +300,7 @@ class ImportInsertHelperImpl(private val project: Project) : ImportInsertHelper(
|
||||
|
||||
private fun dropRedundantExplicitImports(packageFqName: FqName) {
|
||||
val dropCandidates = file.importDirectives.filter {
|
||||
!it.isAllUnder && it.aliasName == null && it.importPath?.fqnPart()?.parent() == packageFqName
|
||||
!it.isAllUnder && it.aliasName == null && it.importPath?.fqName?.parent() == packageFqName
|
||||
}
|
||||
|
||||
val importsToCheck = ArrayList<FqName>()
|
||||
|
||||
@@ -163,7 +163,7 @@ private fun renderImportName(fqName: FqName, isOnDemand: Boolean)
|
||||
// TODO: use the correct LanguageVersionSettings instance here
|
||||
private val DEFAULT_IMPORTS_SET: Set<FqName> = JvmPlatform.getDefaultImports(LanguageVersionSettingsImpl.DEFAULT)
|
||||
.filter { it.isAllUnder }
|
||||
.map { it.fqnPart() }
|
||||
.map { it.fqName }
|
||||
.toSet()
|
||||
|
||||
private fun isImportedByDefault(c: KtLightClass) = c.qualifiedName?.let { FqName(it).parent() } in DEFAULT_IMPORTS_SET
|
||||
|
||||
@@ -27,7 +27,7 @@ import org.jetbrains.kotlin.resolve.TargetPlatform
|
||||
|
||||
object JsPlatform : TargetPlatform("JS") {
|
||||
override fun getDefaultImports(languageVersionSettings: LanguageVersionSettings): List<ImportPath> =
|
||||
Default.getDefaultImports(languageVersionSettings) + ImportPath("kotlin.js.*")
|
||||
Default.getDefaultImports(languageVersionSettings) + ImportPath.fromString("kotlin.js.*")
|
||||
|
||||
override val platformConfigurator: PlatformConfigurator = JsPlatformConfigurator
|
||||
|
||||
|
||||
Reference in New Issue
Block a user