Import is placed in some specific order on adding
This commit is contained in:
@@ -40,9 +40,7 @@ import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.scopes.getDescriptorsFiltered
|
||||
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor
|
||||
import org.jetbrains.kotlin.idea.imports.importableFqName
|
||||
import java.util.LinkedHashSet
|
||||
import org.jetbrains.kotlin.idea.imports.importableFqNameSafe
|
||||
import java.util.ArrayList
|
||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||
import org.jetbrains.kotlin.resolve.scopes.JetScope
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
@@ -55,6 +53,7 @@ import org.jetbrains.kotlin.idea.util.ImportInsertHelper
|
||||
import org.jetbrains.kotlin.idea.util.ImportInsertHelper.ImportDescriptorResult
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.idea.refactoring.fqName.isImported
|
||||
import java.util.*
|
||||
|
||||
public class ImportInsertHelperImpl(private val project: Project) : ImportInsertHelper() {
|
||||
|
||||
@@ -68,7 +67,7 @@ public class ImportInsertHelperImpl(private val project: Project) : ImportInsert
|
||||
}
|
||||
}
|
||||
|
||||
private fun writeImportToFile(importPath: ImportPath, file: JetFile): JetImportDirective {
|
||||
private fun addImport(file: JetFile, importPath: ImportPath): JetImportDirective {
|
||||
val psiFactory = JetPsiFactory(project)
|
||||
if (file is JetCodeFragment) {
|
||||
val newDirective = psiFactory.createImportDirective(importPath)
|
||||
@@ -79,21 +78,53 @@ public class ImportInsertHelperImpl(private val project: Project) : ImportInsert
|
||||
val importList = file.getImportList()
|
||||
if (importList != null) {
|
||||
val newDirective = psiFactory.createImportDirective(importPath)
|
||||
importList.add(psiFactory.createNewLine())
|
||||
return importList.add(newDirective) as JetImportDirective
|
||||
val imports = importList.getImports()
|
||||
if (imports.isEmpty()) { //TODO: strange hack
|
||||
importList.add(psiFactory.createNewLine())
|
||||
return importList.add(newDirective) as JetImportDirective
|
||||
}
|
||||
else {
|
||||
val insertAfter = imports
|
||||
.reverse()
|
||||
.firstOrNull {
|
||||
val directivePath = it.getImportPath()
|
||||
directivePath != null && ImportPathComparator.compare(directivePath, importPath) <= 0
|
||||
}
|
||||
return importList.addAfter(newDirective, insertAfter) as JetImportDirective
|
||||
}
|
||||
}
|
||||
else {
|
||||
val newImportList = psiFactory.createImportDirectiveWithImportList(importPath)
|
||||
val packageDirective = file.getPackageDirective()
|
||||
if (packageDirective == null) {
|
||||
throw IllegalStateException("Scripts are not supported: " + file.getName())
|
||||
}
|
||||
|
||||
?: throw IllegalStateException("Scripts are not supported: " + file.getName())
|
||||
val addedImportList = packageDirective.getParent().addAfter(newImportList, packageDirective) as JetImportList
|
||||
return addedImportList.getImports().single()
|
||||
}
|
||||
}
|
||||
|
||||
private object ImportPathComparator : Comparator<ImportPath> {
|
||||
override fun compare(import1: ImportPath, import2: ImportPath): Int {
|
||||
// alias imports placed last
|
||||
if (import1.hasAlias() != import2.hasAlias()) {
|
||||
return if (import1.hasAlias()) +1 else -1
|
||||
}
|
||||
|
||||
// standard library imports last
|
||||
val stdlib1 = isJavaOrKotlinStdlibImport(import1)
|
||||
val stdlib2 = isJavaOrKotlinStdlibImport(import2)
|
||||
if (stdlib1 != stdlib2) {
|
||||
return if (stdlib1) +1 else -1
|
||||
}
|
||||
|
||||
return import1.toString().compareTo(import2.toString())
|
||||
}
|
||||
|
||||
private fun isJavaOrKotlinStdlibImport(path: ImportPath): Boolean {
|
||||
val s = path.getPathStr()
|
||||
return s.startsWith("java.") || s.startsWith("javax.")|| s.startsWith("kotlin.")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that import is useless.
|
||||
*/
|
||||
@@ -383,7 +414,7 @@ public class ImportInsertHelperImpl(private val project: Project) : ImportInsert
|
||||
}
|
||||
|
||||
private fun addImport(fqName: FqName, allUnder: Boolean): JetImportDirective {
|
||||
return writeImportToFile(ImportPath(fqName, allUnder), file)
|
||||
return addImport(file, ImportPath(fqName, allUnder))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
package p
|
||||
|
||||
import java.sql.*
|
||||
import java.util.*
|
||||
import java.sql.Date
|
||||
import java.util.*
|
||||
|
||||
val d = Date()
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
package p
|
||||
|
||||
import java.sql.*
|
||||
import java.util.*
|
||||
import java.sql.Date
|
||||
import java.util.*
|
||||
|
||||
val d: Date? = null
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
package p
|
||||
|
||||
import dependency.*
|
||||
import java.util.*
|
||||
import dependency.Date
|
||||
import java.util.*
|
||||
|
||||
val d = Date(1, 2)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
package p
|
||||
|
||||
import dependency.*
|
||||
import java.util.*
|
||||
import dependency.Date
|
||||
import java.util.*
|
||||
|
||||
val d = Date.VALUE
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
package p
|
||||
|
||||
import dependency.AClass.*
|
||||
import java.util.*
|
||||
import dependency.AClass.Date
|
||||
import java.util.*
|
||||
|
||||
val d = Date()
|
||||
|
||||
@@ -3,7 +3,7 @@ package p
|
||||
|
||||
import java.sql.*
|
||||
import dependency.Date // import of function does not affect class name conflict
|
||||
import java.util.*
|
||||
import java.sql.Date
|
||||
import java.util.*
|
||||
|
||||
val d = Date(1)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// IMPORT: java.sql.Date
|
||||
package p
|
||||
|
||||
import java.util.*
|
||||
import java.sql.Date
|
||||
import java.util.*
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// IMPORT: dependency.Date
|
||||
package p
|
||||
|
||||
import dependency.Date
|
||||
import java.util.*
|
||||
import java.sql.*
|
||||
import dependency.Date
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
package p
|
||||
|
||||
import java.sql.*
|
||||
import java.util.HashSet as JavaHashSet // alias import should not be dropped
|
||||
import java.util.concurrent // import of package should not be dropped because packages are not imported by *
|
||||
import java.util.*
|
||||
import java.util.Date
|
||||
import java.util.HashSet as JavaHashSet // alias import should not be dropped
|
||||
import java.util.concurrent // import of package should not be dropped because packages are not imported by *
|
||||
|
||||
fun foo() {
|
||||
val v1 = JavaHashSet()
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// IMPORT: dependency.X
|
||||
package p
|
||||
|
||||
import java.util.*
|
||||
import dependency.*
|
||||
import java.util.*
|
||||
|
||||
val d = Date(1, 2)
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
package xxx
|
||||
|
||||
trait Dependency
|
||||
@@ -0,0 +1,6 @@
|
||||
// IMPORT: xxx.Dependency
|
||||
|
||||
import a.*
|
||||
import kotlin.math.*
|
||||
import java.util.*
|
||||
import javax.*
|
||||
@@ -0,0 +1,7 @@
|
||||
// IMPORT: xxx.Dependency
|
||||
|
||||
import a.*
|
||||
import xxx.*
|
||||
import kotlin.math.*
|
||||
import java.util.*
|
||||
import javax.*
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
package foo
|
||||
|
||||
import java.util.ArrayList
|
||||
import bar.Other
|
||||
import bar.Bar
|
||||
import bar.Other
|
||||
import java.util.ArrayList
|
||||
|
||||
class Impl: Foo() {
|
||||
override fun foo(list: ArrayList<Int>?, other: Other?): Bar? {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package some
|
||||
|
||||
import java.util.SortedSet
|
||||
import jettesting.data.somefun
|
||||
import java.util.SortedSet
|
||||
|
||||
fun other() {
|
||||
somefun(<caret>)
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package to
|
||||
|
||||
import a.T
|
||||
import a.A
|
||||
import a.B
|
||||
import a.T
|
||||
|
||||
fun g(t: T): Int {
|
||||
g(A)
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package to
|
||||
|
||||
import a.A
|
||||
import a.get
|
||||
import a.set
|
||||
import a.A
|
||||
|
||||
class B {
|
||||
var v by A()
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
package to
|
||||
|
||||
import d.ext
|
||||
import d.A
|
||||
import d.T
|
||||
import d.Outer
|
||||
import d.c
|
||||
import d.g
|
||||
import d.ClassObject
|
||||
import d.E
|
||||
import d.O1
|
||||
import d.O2
|
||||
import d.E
|
||||
import d.ClassObject
|
||||
import d.Outer
|
||||
import d.T
|
||||
import d.c
|
||||
import d.ext
|
||||
import d.g
|
||||
|
||||
fun f(a: A, t: T) {
|
||||
g(A(c).ext())
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package to
|
||||
|
||||
import a.f
|
||||
import a.p
|
||||
import a.g
|
||||
import a.p
|
||||
|
||||
fun foo() {
|
||||
3.f()
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package to
|
||||
|
||||
import a.plus
|
||||
import a.infix
|
||||
import a.A
|
||||
import a.infix
|
||||
import a.plus
|
||||
|
||||
fun f(a: A) {
|
||||
a + a
|
||||
|
||||
@@ -2,10 +2,10 @@ package to
|
||||
|
||||
import a.A
|
||||
import a.ext
|
||||
import a.plus
|
||||
import a.infix
|
||||
import a.minus
|
||||
import a.p
|
||||
import a.plus
|
||||
|
||||
fun A.ext() {
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package to
|
||||
|
||||
import a.A
|
||||
import a.hasNext
|
||||
import a.iterator
|
||||
import a.next
|
||||
import a.hasNext
|
||||
import a.A
|
||||
|
||||
fun f() {
|
||||
for (i in A()) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package to
|
||||
|
||||
import a.get
|
||||
import a.A
|
||||
import a.get
|
||||
|
||||
fun f() {
|
||||
A()[""]
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
package to
|
||||
|
||||
import d.ext
|
||||
import d.A
|
||||
import d.T
|
||||
import d.Outer
|
||||
import d.c
|
||||
import d.g
|
||||
import d.ClassObject
|
||||
import d.E
|
||||
import d.O1
|
||||
import d.O2
|
||||
import d.E
|
||||
import d.ClassObject
|
||||
import d.Outer
|
||||
import d.T
|
||||
import d.c
|
||||
import d.ext
|
||||
import d.g
|
||||
|
||||
fun f(a: A, t: T) {
|
||||
g(A(c).ext())
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package to
|
||||
|
||||
import a.invoke
|
||||
import a.A
|
||||
import a.invoke
|
||||
|
||||
fun f(a: A) {
|
||||
a()
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package to
|
||||
|
||||
import a.JavaM
|
||||
import a.JavaF
|
||||
import a.JavaM
|
||||
|
||||
fun f() {
|
||||
JavaM.staticMethod()
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package to
|
||||
|
||||
import a.A
|
||||
import a.component1
|
||||
import a.component2
|
||||
import a.A
|
||||
|
||||
fun f() {
|
||||
val (a, b) = A()
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package to
|
||||
|
||||
import a.next
|
||||
import a.hasNext
|
||||
import a.A
|
||||
import a.B
|
||||
import a.hasNext
|
||||
import a.next
|
||||
|
||||
fun A.iterator() = B()
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package to
|
||||
|
||||
import a.d
|
||||
import a.b
|
||||
import a.d
|
||||
|
||||
fun f(c: IntRange) = d + b
|
||||
@@ -1,8 +1,8 @@
|
||||
package to
|
||||
|
||||
import a.T
|
||||
import a.A
|
||||
import a.B
|
||||
import a.T
|
||||
|
||||
fun g(t: T) {
|
||||
g(A)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package to
|
||||
|
||||
import a.c
|
||||
import a.b
|
||||
import a.c
|
||||
|
||||
fun f() = c + b
|
||||
@@ -1,7 +1,7 @@
|
||||
// "Change function signature to 'fun f(a: A)'" "true"
|
||||
// ERROR: 'f' overrides nothing
|
||||
import a.B
|
||||
import a.A
|
||||
import a.B
|
||||
|
||||
class BB : B() {
|
||||
<caret>override fun f(a: A) {}
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
// "Change function signature to 'fun f(a: A)'" "true"
|
||||
// ERROR: 'f' overrides nothing
|
||||
import a.B
|
||||
import a.A
|
||||
|
||||
import a.B
|
||||
class A {}
|
||||
class BB : B() {
|
||||
override fun f(a: A) {}
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
// "Change type from 'String' to '(ModuleBuilder) -> Module'" "true"
|
||||
|
||||
import kotlin.modules.ModuleBuilder
|
||||
import kotlin.modules.Module
|
||||
import kotlin.modules.ModuleBuilder
|
||||
|
||||
fun foo(f: ((kotlin.modules.ModuleBuilder) -> kotlin.modules.Module) -> String) {
|
||||
foo {
|
||||
|
||||
+1
-1
@@ -1,8 +1,8 @@
|
||||
package a
|
||||
|
||||
import b.test
|
||||
import b.TEST
|
||||
import b.Test
|
||||
import b.test
|
||||
|
||||
fun bar() {
|
||||
val t: Test = Test()
|
||||
|
||||
+1
-1
@@ -1,8 +1,8 @@
|
||||
package a
|
||||
|
||||
import b.test
|
||||
import b.TEST
|
||||
import b.Test
|
||||
import b.test
|
||||
|
||||
fun bar() {
|
||||
val t: Test = Test()
|
||||
|
||||
+1
-1
@@ -1,8 +1,8 @@
|
||||
package c
|
||||
|
||||
import b.TEST
|
||||
import b.Test
|
||||
import b.test
|
||||
import b.TEST
|
||||
|
||||
fun bar() {
|
||||
val t: Test = Test()
|
||||
|
||||
+1
-1
@@ -1,9 +1,9 @@
|
||||
package c
|
||||
|
||||
import a.*
|
||||
import b.test
|
||||
import b.TEST
|
||||
import b.Test
|
||||
import b.test
|
||||
|
||||
fun bar() {
|
||||
val t: Test = Test()
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
package target
|
||||
|
||||
import library.bar
|
||||
import library.B
|
||||
import library.bar
|
||||
|
||||
public class A: B() {
|
||||
fun test() {
|
||||
|
||||
+1
-1
@@ -1,9 +1,9 @@
|
||||
package first
|
||||
|
||||
import fourth.X
|
||||
import second.A
|
||||
import third.B
|
||||
import third.D
|
||||
import fourth.X
|
||||
|
||||
class Test {
|
||||
val a = A()
|
||||
|
||||
+1
-1
@@ -1,9 +1,9 @@
|
||||
package first
|
||||
|
||||
import fourth.X
|
||||
import second.A
|
||||
import third.B
|
||||
import third.D
|
||||
import fourth.X
|
||||
|
||||
fun test() {
|
||||
val a = A()
|
||||
|
||||
+1
-1
@@ -1,8 +1,8 @@
|
||||
package target
|
||||
|
||||
import library.JavaClass
|
||||
import library.KtObject
|
||||
import library.KtClass
|
||||
import library.KtObject
|
||||
|
||||
class Foo {
|
||||
val jv1 = JavaClass.foo()
|
||||
|
||||
+1
-1
@@ -1,8 +1,8 @@
|
||||
package target
|
||||
|
||||
import library.JavaEnum
|
||||
import library.KtEnum
|
||||
import library.KtData
|
||||
import library.KtEnum
|
||||
|
||||
class Foo {
|
||||
val javaEnum = JavaEnum.values()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import java.util.Date
|
||||
import java.sql
|
||||
import java.util.Date
|
||||
|
||||
val x = sql.Date(1)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import p.globalVal
|
||||
import p.globalFun
|
||||
import p.globalVal
|
||||
|
||||
fun foo() {
|
||||
globalFun(globalVal)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import java.awt.Container
|
||||
import java.io.File
|
||||
import java.util.ArrayList
|
||||
import java.awt.Container
|
||||
|
||||
class A {
|
||||
var x: ((File, ArrayList<String>) -> Container)? = null
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import java.util.Date
|
||||
import java.sql
|
||||
import java.util.Date
|
||||
|
||||
class A : sql.Date
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import java.util.*
|
||||
import java.sql.Date
|
||||
import java.util.*
|
||||
|
||||
val v: ArrayList<Date>
|
||||
@@ -1,6 +1,6 @@
|
||||
import java.sql
|
||||
import java.util.Date
|
||||
import java.util.HashMap
|
||||
import java.sql
|
||||
|
||||
class A {
|
||||
val x: HashMap<Date, sql.Date>
|
||||
|
||||
@@ -221,4 +221,10 @@ public class AddImportTestGenerated extends AbstractAddImportTest {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/addImport/PropertyAlreadyImported2.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("StdlibImportsLast.kt")
|
||||
public void testStdlibImportsLast() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/addImport/StdlibImportsLast.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user