Skip to content

Commit f140db0

Browse files
committed
Apply ScipOccurrences/ScipRole refactor to Kotlin plugin
1 parent d87b926 commit f140db0

4 files changed

Lines changed: 40 additions & 50 deletions

File tree

semanticdb-kotlinc/src/main/kotlin/com/sourcegraph/semanticdb_kotlinc/ScipOccurrences.kt

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,17 @@ package com.sourcegraph.semanticdb_kotlinc
33
import org.scip_code.scip.Occurrence
44

55
/**
6-
* Deduplicates SCIP [Occurrence] entries by `(symbol, range, roles)`. Variants differing only in
7-
* whether `enclosing_range` is set are collapsed, preferring the one that carries it. Mirrors the
8-
* Java `ScipOccurrences` helper.
6+
* Accumulator that deduplicates SCIP [Occurrence] entries by their `(symbol, range, roles)` key.
7+
* Variants that differ only in whether `enclosing_range` is set are collapsed, preferring the one
8+
* that carries the enclosing range. Mirrors the Java `ScipOccurrences` accumulator used by the
9+
* javac plug-in.
910
*/
10-
internal object ScipOccurrences {
11+
internal class ScipOccurrences {
1112

12-
fun deduplicate(occurrences: List<Occurrence>): List<Occurrence> {
13-
val out = LinkedHashMap<Key, Occurrence>()
14-
for (occ in occurrences) put(out, occ)
15-
return out.values.toList()
16-
}
13+
private val out = LinkedHashMap<Key, Occurrence>()
1714

18-
fun put(out: LinkedHashMap<Key, Occurrence>, occ: Occurrence) {
15+
/** Adds [occ], collapsing it into any existing entry with the same [Key]. */
16+
fun add(occ: Occurrence) {
1917
val key = Key.of(occ)
2018
val existing = out[key]
2119
if (existing == null) {
@@ -27,7 +25,15 @@ internal object ScipOccurrences {
2725
}
2826
}
2927

30-
data class Key(val symbol: String, val range: List<Int>, val roles: Int) {
28+
/** Adds every occurrence in [occs]. */
29+
fun addAll(occs: Iterable<Occurrence>) {
30+
for (occ in occs) add(occ)
31+
}
32+
33+
/** Returns the deduplicated occurrences in insertion order. */
34+
fun values(): Collection<Occurrence> = out.values
35+
36+
private data class Key(val symbol: String, val range: List<Int>, val roles: Int) {
3137
companion object {
3238
fun of(occ: Occurrence): Key =
3339
Key(occ.symbol, occ.rangeList.toList(), occ.symbolRoles)

semanticdb-kotlinc/src/main/kotlin/com/sourcegraph/semanticdb_kotlinc/ScipRole.kt

Lines changed: 0 additions & 11 deletions
This file was deleted.

semanticdb-kotlinc/src/main/kotlin/com/sourcegraph/semanticdb_kotlinc/ScipTextDocumentBuilder.kt

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ class ScipTextDocumentBuilder(
4040
private val cache: SymbolsCache,
4141
private val relativePath: String,
4242
) {
43-
private val occurrences = mutableListOf<Occurrence>()
43+
private val occurrences = ScipOccurrences()
4444
// Keyed by symbol string so re-encounters of the same definition (multi-round compilation,
4545
// synthetic accessors) do not produce duplicate entries.
4646
private val symbols = LinkedHashMap<String, SymbolInformation>()
@@ -50,7 +50,7 @@ class ScipTextDocumentBuilder(
5050
.newBuilder()
5151
.setRelativePath(relativePath)
5252
.setLanguage(LANGUAGE_KOTLIN)
53-
.addAllOccurrences(ScipOccurrences.deduplicate(occurrences))
53+
.addAllOccurrences(occurrences.values())
5454
.addAllSymbols(symbols.values)
5555
.build()
5656

@@ -60,30 +60,30 @@ class ScipTextDocumentBuilder(
6060
firBasedSymbol: FirBasedSymbol<*>?,
6161
symbol: Symbol,
6262
element: KtSourceElement,
63-
role: ScipRole,
63+
roles: Int,
6464
context: CheckerContext,
6565
enclosingSource: KtSourceElement? = null,
6666
) {
6767
if (symbol == Symbol.NONE) return
6868

69-
emitOccurrence(symbol, element, role, enclosingSource)
70-
if (role == ScipRole.DEFINITION) {
69+
emitOccurrence(symbol, element, roles, enclosingSource)
70+
if (roles == SymbolRole.Definition_VALUE) {
7171
emitSymbolInformation(firBasedSymbol, symbol, element, context)
7272
}
7373
}
7474

7575
private fun emitOccurrence(
7676
symbol: Symbol,
7777
element: KtSourceElement,
78-
role: ScipRole,
78+
roles: Int,
7979
enclosingSource: KtSourceElement?,
8080
) {
8181
val builder =
8282
Occurrence
8383
.newBuilder()
8484
.addAllRange(scipRange(element))
8585
.setSymbol(ScipSymbols.fromSemanticdbSymbol(symbol))
86-
.setSymbolRoles(scipRole(role))
86+
.setSymbolRoles(roles)
8787
if (enclosingSource != null) {
8888
builder.addAllEnclosingRange(scipEnclosingRange(enclosingSource))
8989
}
@@ -261,12 +261,6 @@ class ScipTextDocumentBuilder(
261261
else -> firBasedSymbol.toString()
262262
}
263263

264-
private fun scipRole(role: ScipRole): Int =
265-
when (role) {
266-
ScipRole.DEFINITION -> SymbolRole.Definition_VALUE
267-
else -> 0
268-
}
269-
270264
private fun scipKind(firBasedSymbol: FirBasedSymbol<*>?): SymbolInformation.Kind =
271265
when (firBasedSymbol) {
272266
null -> SymbolInformation.Kind.UnspecifiedKind

semanticdb-kotlinc/src/main/kotlin/com/sourcegraph/semanticdb_kotlinc/SemanticdbVisitor.kt

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.sourcegraph.semanticdb_kotlinc
22

33
import org.scip_code.scip.Index
4+
import org.scip_code.scip.SymbolRole
45
import java.nio.file.Path
56
import java.nio.file.Paths
67
import kotlin.contracts.ExperimentalContracts
@@ -42,12 +43,12 @@ class SemanticdbVisitor(
4243

4344
private fun Sequence<SymbolDescriptorPair>?.emitAll(
4445
element: KtSourceElement,
45-
role: ScipRole,
46+
roles: Int,
4647
context: CheckerContext,
4748
enclosingSource: KtSourceElement? = null,
4849
): List<Symbol>? =
4950
this?.onEach { (firBasedSymbol, symbol) ->
50-
scipBuilder.emitScipData(firBasedSymbol, symbol, element, role, context, enclosingSource)
51+
scipBuilder.emitScipData(firBasedSymbol, symbol, element, roles, context, enclosingSource)
5152
}
5253
?.map { it.symbol }
5354
?.toList()
@@ -56,55 +57,55 @@ class SemanticdbVisitor(
5657
this.map { SymbolDescriptorPair(firBasedSymbol, it) }
5758

5859
fun visitPackage(pkg: FqName, element: KtSourceElement, context: CheckerContext) {
59-
cache[pkg].with(null).emitAll(element, ScipRole.REFERENCE, context)
60+
cache[pkg].with(null).emitAll(element, 0, context)
6061
}
6162

6263
fun visitClassReference(firClassSymbol: FirClassLikeSymbol<*>, element: KtSourceElement, context: CheckerContext) {
63-
cache[firClassSymbol].with(firClassSymbol).emitAll(element, ScipRole.REFERENCE, context)
64+
cache[firClassSymbol].with(firClassSymbol).emitAll(element, 0, context)
6465
}
6566

6667
fun visitCallableReference(firClassSymbol: FirCallableSymbol<*>, element: KtSourceElement, context: CheckerContext) {
67-
cache[firClassSymbol].with(firClassSymbol).emitAll(element, ScipRole.REFERENCE, context)
68+
cache[firClassSymbol].with(firClassSymbol).emitAll(element, 0, context)
6869
}
6970

7071
fun visitClassOrObject(firClass: FirClassLikeDeclaration, element: KtSourceElement, context: CheckerContext, enclosingSource: KtSourceElement? = null) {
71-
cache[firClass.symbol].with(firClass.symbol).emitAll(element, ScipRole.DEFINITION, context, enclosingSource)
72+
cache[firClass.symbol].with(firClass.symbol).emitAll(element, SymbolRole.Definition_VALUE, context, enclosingSource)
7273
}
7374

7475
fun visitPrimaryConstructor(firConstructor: FirConstructor, source: KtSourceElement, context: CheckerContext, enclosingSource: KtSourceElement? = null) {
75-
cache[firConstructor.symbol].with(firConstructor.symbol).emitAll(source, ScipRole.DEFINITION, context, enclosingSource)
76+
cache[firConstructor.symbol].with(firConstructor.symbol).emitAll(source, SymbolRole.Definition_VALUE, context, enclosingSource)
7677
}
7778

7879
fun visitSecondaryConstructor(firConstructor: FirConstructor, source: KtSourceElement, context: CheckerContext, enclosingSource: KtSourceElement? = null) {
79-
cache[firConstructor.symbol].with(firConstructor.symbol).emitAll(source, ScipRole.DEFINITION, context, enclosingSource)
80+
cache[firConstructor.symbol].with(firConstructor.symbol).emitAll(source, SymbolRole.Definition_VALUE, context, enclosingSource)
8081
}
8182

8283
fun visitNamedFunction(firFunction: FirFunction, source: KtSourceElement, context: CheckerContext, enclosingSource: KtSourceElement? = null) {
83-
cache[firFunction.symbol].with(firFunction.symbol).emitAll(source, ScipRole.DEFINITION, context, enclosingSource)
84+
cache[firFunction.symbol].with(firFunction.symbol).emitAll(source, SymbolRole.Definition_VALUE, context, enclosingSource)
8485
}
8586

8687
fun visitProperty(firProperty: FirProperty, source: KtSourceElement, context: CheckerContext, enclosingSource: KtSourceElement? = null) {
87-
cache[firProperty.symbol].with(firProperty.symbol).emitAll(source, ScipRole.DEFINITION, context, enclosingSource)
88+
cache[firProperty.symbol].with(firProperty.symbol).emitAll(source, SymbolRole.Definition_VALUE, context, enclosingSource)
8889
}
8990

9091
fun visitParameter(firParameter: FirValueParameter, source: KtSourceElement, context: CheckerContext, enclosingSource: KtSourceElement? = null) {
91-
cache[firParameter.symbol].with(firParameter.symbol).emitAll(source, ScipRole.DEFINITION, context, enclosingSource)
92+
cache[firParameter.symbol].with(firParameter.symbol).emitAll(source, SymbolRole.Definition_VALUE, context, enclosingSource)
9293
}
9394

9495
fun visitTypeParameter(firTypeParameter: FirTypeParameter, source: KtSourceElement, context: CheckerContext, enclosingSource: KtSourceElement? = null) {
9596
cache[firTypeParameter.symbol]
9697
.with(firTypeParameter.symbol)
97-
.emitAll(source, ScipRole.DEFINITION, context, enclosingSource)
98+
.emitAll(source, SymbolRole.Definition_VALUE, context, enclosingSource)
9899
}
99100

100101
fun visitTypeAlias(firTypeAlias: FirTypeAlias, source: KtSourceElement, context: CheckerContext, enclosingSource: KtSourceElement? = null) {
101-
cache[firTypeAlias.symbol].with(firTypeAlias.symbol).emitAll(source, ScipRole.DEFINITION, context, enclosingSource)
102+
cache[firTypeAlias.symbol].with(firTypeAlias.symbol).emitAll(source, SymbolRole.Definition_VALUE, context, enclosingSource)
102103
}
103104

104105
fun visitPropertyAccessor(firPropertyAccessor: FirPropertyAccessor, source: KtSourceElement, context: CheckerContext, enclosingSource: KtSourceElement? = null) {
105106
cache[firPropertyAccessor.symbol]
106107
.with(firPropertyAccessor.symbol)
107-
.emitAll(source, ScipRole.DEFINITION, context, enclosingSource)
108+
.emitAll(source, SymbolRole.Definition_VALUE, context, enclosingSource)
108109
}
109110

110111
fun visitSimpleNameExpression(
@@ -113,7 +114,7 @@ class SemanticdbVisitor(
113114
) {
114115
cache[firResolvedNamedReference.resolvedSymbol]
115116
.with(firResolvedNamedReference.resolvedSymbol)
116-
.emitAll(source, ScipRole.REFERENCE, context)
117+
.emitAll(source, 0, context)
117118
}
118119
}
119120

0 commit comments

Comments
 (0)