Skip to content

Commit f7563f5

Browse files
committed
Implement backticking of built-in symbols in package names when auto importing
1 parent 0a56af3 commit f7563f5

File tree

3 files changed

+79
-1
lines changed

3 files changed

+79
-1
lines changed

server/src/main/kotlin/org/javacs/kt/imports/Imports.kt

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ package org.javacs.kt.imports
33
import org.eclipse.lsp4j.Position
44
import org.eclipse.lsp4j.Range
55
import org.eclipse.lsp4j.TextEdit
6+
import org.jetbrains.kotlin.lexer.KtKeywordToken
7+
import org.jetbrains.kotlin.lexer.KtTokens
68
import org.jetbrains.kotlin.name.FqName
79
import org.jetbrains.kotlin.psi.*
810
import org.javacs.kt.position.location
@@ -15,7 +17,7 @@ fun getImportTextEditEntry(parsedFile: KtFile, fqName: FqName): TextEdit {
1517

1618
val pos = findImportInsertionPosition(parsedFile, fqName)
1719
val prefix = if (importedNames.isEmpty()) "\n\n" else "\n"
18-
return TextEdit(Range(pos, pos), "${prefix}import ${fqName}")
20+
return TextEdit(Range(pos, pos), "${prefix}import ${backtickBultins(fqName)}")
1921
}
2022

2123
/** Finds a good insertion position for a new import of the given fully-qualified name. */
@@ -36,3 +38,25 @@ private fun matchingPrefixLength(left: FqName, right: FqName): Int =
3638
left.pathSegments().asSequence().zip(right.pathSegments().asSequence())
3739
.takeWhile { it.first == it.second }
3840
.count()
41+
42+
private fun backtickBultins(fqName: FqName): String {
43+
val builtInKeywords = (KtTokens.SOFT_KEYWORDS.getTypes() + KtTokens.KEYWORDS.getTypes())
44+
.asSequence()
45+
.mapNotNull { (it as? KtKeywordToken)?.value }
46+
var result = fqName.asString()
47+
for (builtin in builtInKeywords) {
48+
if (result.contains(builtin)) {
49+
// need to go through each part to handle words
50+
// that are part of other words (e.g, as and class)
51+
result = result.split('.').map {
52+
if (builtin == it) {
53+
"`$builtin`"
54+
} else {
55+
it
56+
}
57+
}.joinToString(".")
58+
}
59+
}
60+
61+
return result
62+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package org.javacs.kt
2+
3+
import org.javacs.kt.imports.getImportTextEditEntry
4+
import org.jetbrains.kotlin.name.FqName
5+
import org.hamcrest.Matchers.*
6+
import org.junit.Assert.assertThat
7+
import org.junit.Test
8+
9+
class ImportTextEditTest : SingleFileTestFixture("imports", "Simple.kt") {
10+
11+
@Test
12+
fun `should return normal import name`() {
13+
val ktFile = languageServer.sourcePath.parsedFile(workspaceRoot.resolve(file).toUri())
14+
val importName = FqName("org.jetbrains.kotlin.name.FqName")
15+
val result = getImportTextEditEntry(ktFile, importName)
16+
17+
assertThat(result.range, equalTo(range(1, 23, 1, 23)))
18+
assertThat(result.newText, equalTo("\n\nimport org.jetbrains.kotlin.name.FqName"))
19+
}
20+
21+
@Test
22+
fun `should wrap -class- in backticks`() {
23+
val ktFile = languageServer.sourcePath.parsedFile(workspaceRoot.resolve(file).toUri())
24+
val importName = FqName("com.class.myMethod")
25+
val result = getImportTextEditEntry(ktFile, importName)
26+
27+
assertThat(result.range, equalTo(range(1, 23, 1, 23)))
28+
assertThat(result.newText, equalTo("\n\nimport com.`class`.myMethod"))
29+
}
30+
31+
@Test
32+
fun `should wrap -fun- in backticks`() {
33+
val ktFile = languageServer.sourcePath.parsedFile(workspaceRoot.resolve(file).toUri())
34+
val importName = FqName("com.fun.myMethod")
35+
val result = getImportTextEditEntry(ktFile, importName)
36+
37+
assertThat(result.range, equalTo(range(1, 23, 1, 23)))
38+
assertThat(result.newText, equalTo("\n\nimport com.`fun`.myMethod"))
39+
}
40+
41+
@Test
42+
fun `should wrap multiple built in keywords in backticks`() {
43+
val ktFile = languageServer.sourcePath.parsedFile(workspaceRoot.resolve(file).toUri())
44+
val importName = FqName("fun.class.someother.package.method.var.val")
45+
val result = getImportTextEditEntry(ktFile, importName)
46+
47+
assertThat(result.range, equalTo(range(1, 23, 1, 23)))
48+
assertThat(result.newText, equalTo("\n\nimport `fun`.`class`.someother.`package`.method.`var`.`val`"))
49+
}
50+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
package test.mypackage
2+
3+
4+
val something = 1

0 commit comments

Comments
 (0)