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