Skip to content

Commit ba65300

Browse files
committed
Add experimental extension completion using symbol index
1 parent cbb7bdf commit ba65300

File tree

4 files changed

+44
-21
lines changed

4 files changed

+44
-21
lines changed

gradle.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
projectVersion=0.9.1
22
kotlinVersion=1.4.30-RC-232
3+
exposedVersion=0.29.1
34
javaVersion=11

server/build.gradle

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,9 @@ dependencies {
4444
implementation "org.jetbrains.kotlin:ide-common-ij202:$kotlinVersion"
4545
// implementation("org.jetbrains.kotlin:kotlin-plugin-ij201:$kotlinVersion") { transitive = false }
4646
implementation 'org.jetbrains:fernflower:1.0'
47-
implementation 'org.jetbrains.exposed:exposed-core:0.29.1'
47+
implementation "org.jetbrains.exposed:exposed-core:$exposedVersion"
48+
implementation "org.jetbrains.exposed:exposed-dao:$exposedVersion"
49+
implementation "org.jetbrains.exposed:exposed-jdbc:$exposedVersion"
4850
implementation 'com.h2database:h2:1.4.200'
4951
implementation 'com.github.fwcd:ktfmt:22bd538a1c'
5052
implementation 'com.beust:jcommander:1.78'

server/src/main/kotlin/org/javacs/kt/completion/Completions.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ private fun indexCompletionItems(file: CompiledFile, cursor: Int, receiver: KtEx
9797
val receiverTypeFqName = receiverType?.constructor?.declarationDescriptor?.fqNameSafe
9898

9999
return index
100-
.query(partial, limit = MAX_COMPLETION_ITEMS)
100+
.query(partial, receiverTypeFqName, limit = MAX_COMPLETION_ITEMS)
101101
.asSequence()
102102
.filter { it.kind != Symbol.Kind.MODULE } // Ignore global module/package name completions for now, since they cannot be 'imported'
103103
.filter { it.fqName.shortName() !in importedNames && it.fqName.parent() !in wildcardPackages }
@@ -107,7 +107,6 @@ private fun indexCompletionItems(file: CompiledFile, cursor: Int, receiver: KtEx
107107
|| it.visibility == Symbol.Visibility.PROTECTED
108108
|| it.visibility == Symbol.Visibility.INTERNAL
109109
}
110-
.filter { receiverTypeFqName == it.extensionReceiverType } // if both are null, it's not an extension
111110
.map { CompletionItem().apply {
112111
label = it.fqName.shortName().toString()
113112
kind = when (it.kind) {

server/src/main/kotlin/org/javacs/kt/index/SymbolIndex.kt

Lines changed: 39 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,19 @@ import org.jetbrains.exposed.sql.SqlExpressionBuilder.like
1616
import org.jetbrains.exposed.sql.insert
1717

1818
private object Symbols : Table() {
19-
val fqName = varchar("fqname", length = 255).primaryKey()
20-
val shortName = varchar("shortname", length = 80)
19+
val fqName = varchar("fqname", length = 255) references FqNames.fqName
2120
val kind = integer("kind")
2221
val visibility = integer("visibility")
2322
val extensionReceiverType = varchar("extensionreceivertype", length = 255).nullable()
23+
24+
override val primaryKey = PrimaryKey(fqName)
25+
}
26+
27+
private object FqNames : Table() {
28+
val fqName = varchar("fqname", length = 255)
29+
val shortName = varchar("shortname", length = 80)
30+
31+
override val primaryKey = PrimaryKey(fqName)
2432
}
2533

2634
/**
@@ -33,7 +41,7 @@ class SymbolIndex {
3341

3442
init {
3543
transaction(db) {
36-
SchemaUtils.create(Symbols)
44+
SchemaUtils.create(Symbols, FqNames)
3745
}
3846
}
3947

@@ -50,23 +58,28 @@ class SymbolIndex {
5058
transaction(db) {
5159
Symbols.deleteAll()
5260

53-
// TODO: Workaround, since insertIgnore seems to throw UnsupportedByDialectExceptions
54-
// when used with H2.
55-
val addedFqns = mutableSetOf<FqName>()
56-
5761
for (descriptor in descriptors) {
5862
val fqn = descriptor.fqNameSafe
63+
val extensionReceiverFqn = descriptor.accept(ExtractSymbolExtensionReceiverType, Unit)
5964

60-
if (!addedFqns.contains(fqn)) {
61-
addedFqns.add(fqn)
62-
Symbols.insert {
63-
it[fqName] = fqn.toString()
64-
it[shortName] = fqn.shortName().toString()
65-
it[kind] = descriptor.accept(ExtractSymbolKind, Unit).rawValue
66-
it[visibility] = descriptor.accept(ExtractSymbolVisibility, Unit).rawValue
67-
it[extensionReceiverType] = descriptor.accept(ExtractSymbolExtensionReceiverType, Unit)?.toString()
65+
FqNames.replace {
66+
it[fqName] = fqn.toString()
67+
it[shortName] = fqn.shortName().toString()
68+
}
69+
70+
extensionReceiverFqn?.let { rFqn ->
71+
FqNames.replace {
72+
it[fqName] = rFqn.toString()
73+
it[shortName] = rFqn.shortName().toString()
6874
}
6975
}
76+
77+
Symbols.replace {
78+
it[fqName] = fqn.toString()
79+
it[kind] = descriptor.accept(ExtractSymbolKind, Unit).rawValue
80+
it[visibility] = descriptor.accept(ExtractSymbolVisibility, Unit).rawValue
81+
it[extensionReceiverType] = extensionReceiverFqn?.toString()
82+
}
7083
}
7184

7285
val finished = System.currentTimeMillis()
@@ -82,9 +95,17 @@ class SymbolIndex {
8295
}
8396
}
8497

85-
fun query(prefix: String, limit: Int = 20): List<Symbol> = transaction(db) {
86-
Symbols
87-
.select { Symbols.shortName.like("$prefix%") }
98+
fun query(prefix: String, receiverType: FqName? = null, limit: Int = 20): List<Symbol> = transaction(db) {
99+
(Symbols innerJoin FqNames)
100+
.select {
101+
FqNames.shortName
102+
.like("$prefix%")
103+
.let { q ->
104+
receiverType?.let { t ->
105+
q and (Symbols.extensionReceiverType eq wrapAsExpression(FqNames.slice(FqNames.fqName.count()).select { FqNames.shortName.like("$t%") }))
106+
} ?: q
107+
}
108+
}
88109
.limit(limit)
89110
.map { Symbol(
90111
fqName = FqName(it[Symbols.fqName]),

0 commit comments

Comments
 (0)