Import is placed in some specific order on adding

This commit is contained in:
Valentin Kipyatkov
2015-02-13 01:07:40 +03:00
parent 371e0baed1
commit 0a363fc371
51 changed files with 126 additions and 74 deletions
@@ -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.*
@@ -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,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,8 +1,8 @@
package a
import b.test
import b.TEST
import b.Test
import b.test
fun bar() {
val t: Test = Test()
@@ -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,8 +1,8 @@
package c
import b.TEST
import b.Test
import b.test
import b.TEST
fun bar() {
val t: Test = Test()
@@ -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,7 +1,7 @@
package target
import library.bar
import library.B
import library.bar
public class A: B() {
fun test() {
@@ -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,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,8 +1,8 @@
package target
import library.JavaClass
import library.KtObject
import library.KtClass
import library.KtObject
class Foo {
val jv1 = JavaClass.foo()
@@ -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);
}
}