Skip to content

Commit 927cd0a

Browse files
committed
Move exclusively to SCIP snapshot tests
Previously, this repo used SemanticDB and LSIF snapshot tests. This commit replaces both of those with SCIP snapshot tests. The LSIF snapshot tests are no longer needed since the SCIP snapshot format captures the relevant details we tried to assert against with the LSIF snapshot tests. The SemanticDB tests are not needed since they look almost identical to SCIP snapshot excluding the extra details SCIP encodes (cross-repo package information and symbol relationships).
1 parent 052f671 commit 927cd0a

File tree

182 files changed

+27619
-22554
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

182 files changed

+27619
-22554
lines changed

scip-java-proto/src/main/protobuf/scip.proto

+17
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,23 @@ message Relationship {
191191
bool is_implementation = 3;
192192
// Similar to `references_symbols` but for "Go to type definition".
193193
bool is_type_definition = 4;
194+
// Allows overriding the behavior of "Go to definition" and "Find references"
195+
// for symbols which do not have a definition of their own or could
196+
// potentially have multiple definitions.
197+
//
198+
// For example, in a language with single inheritance and no field overriding,
199+
// inherited fields can reuse the same symbol as the ancestor which declares
200+
// the field. In such a situation, is_definition is not needed.
201+
//
202+
// On the other hand, in languages with single inheritance and some form
203+
// of mixins, you can use is_definition to relate the symbol to the
204+
// matching symbol in ancestor classes, and is_reference to relate the
205+
// symbol to the matching symbol in mixins.
206+
//
207+
// NOTE: At the moment, due to limitations of the SCIP to LSIF conversion,
208+
// only global symbols in an index are allowed to use is_definition.
209+
// The relationship may not get recorded if either symbol is local.
210+
bool is_definition = 5;
194211
}
195212

196213
// SymbolRole declares what "role" a symbol has in an occurrence. A role is
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
package com.sourcegraph.scip_java
2+
3+
import scala.collection.mutable
4+
import scala.jdk.CollectionConverters.CollectionHasAsScala
5+
import scala.math.Ordering.Implicits.seqOrdering
6+
7+
import com.sourcegraph.Scip
8+
import com.sourcegraph.Scip.SymbolRole
9+
import com.sourcegraph.scip_java.commands.CommentSyntax
10+
import moped.reporters.Input
11+
import moped.reporters.Position
12+
13+
object ScipPrinters {
14+
15+
def printTextDocument(
16+
doc: Scip.Document,
17+
text: String,
18+
comments: CommentSyntax = CommentSyntax.default
19+
): String = {
20+
val out = new mutable.StringBuilder()
21+
val occurrencesByLine = doc
22+
.getOccurrencesList
23+
.asScala
24+
.groupBy(_.getRange(0))
25+
val symtab =
26+
doc.getSymbolsList.asScala.map(info => info.getSymbol -> info).toMap
27+
28+
val syntheticDefinitions =
29+
doc
30+
.getSymbolsList
31+
.asScala
32+
.flatMap { info =>
33+
info
34+
.getRelationshipsList
35+
.asScala
36+
.collect {
37+
case relationship if relationship.getIsDefinition =>
38+
info -> relationship
39+
}
40+
}
41+
.groupBy { case (_, relationship) =>
42+
relationship.getSymbol
43+
}
44+
.view
45+
.mapValues(
46+
_.map { case (info, _) =>
47+
info
48+
}
49+
)
50+
.toMap
51+
val extension = doc.getRelativePath.split("\\.").lastOption.getOrElse("")
52+
val commentSyntax = comments.extensionSyntax(extension)
53+
val input = Input.filename(doc.getRelativePath, text)
54+
text
55+
.linesWithSeparators
56+
.zipWithIndex
57+
.foreach { case (line, i) =>
58+
out.append(line.replace("\t", ""))
59+
val occurrences = occurrencesByLine
60+
.getOrElse(i, Nil)
61+
.toSeq
62+
.sortBy(o => o.getRangeList.asScala.toList.map(_.toInt))
63+
occurrences.foreach { occ =>
64+
formatOccurrence(input, out, occ, line, symtab, commentSyntax)
65+
if ((occ.getSymbolRoles & SymbolRole.Definition_VALUE) > 0) {
66+
syntheticDefinitions
67+
.getOrElse(occ.getSymbol, Nil)
68+
.foreach { syntheticDefinition =>
69+
formatOccurrence(
70+
input,
71+
out,
72+
occ,
73+
line,
74+
symtab,
75+
commentSyntax,
76+
syntheticDefinition = Some(syntheticDefinition)
77+
)
78+
}
79+
}
80+
}
81+
}
82+
out.toString()
83+
}
84+
85+
private def mopedPosition(input: Input, occ: Scip.Occurrence): Position = {
86+
if (occ.getRangeCount == 3)
87+
Position.range(
88+
input,
89+
occ.getRange(0),
90+
occ.getRange(1),
91+
occ.getRange(0),
92+
occ.getRange(2)
93+
)
94+
else if (occ.getRangeCount == 4)
95+
Position.range(
96+
input,
97+
occ.getRange(0),
98+
occ.getRange(1),
99+
occ.getRange(2),
100+
occ.getRange(3)
101+
)
102+
else
103+
throw new IllegalArgumentException(s"Invalid range: $occ")
104+
}
105+
106+
private def formatOccurrence(
107+
input: Input,
108+
out: mutable.StringBuilder,
109+
occ: Scip.Occurrence,
110+
line: String,
111+
symtab: Map[String, Scip.SymbolInformation],
112+
comment: String,
113+
syntheticDefinition: Option[Scip.SymbolInformation] = None
114+
): Unit = {
115+
val pos = mopedPosition(input, occ)
116+
val isMultiline = pos.startLine != pos.endLine
117+
val width =
118+
if (isMultiline) {
119+
line.length - pos.startColumn - 1
120+
} else {
121+
math.max(1, pos.endColumn - pos.startColumn)
122+
}
123+
124+
val isDefinition =
125+
(occ.getSymbolRoles & SymbolRole.Definition.getNumber) > 0
126+
val role =
127+
if (syntheticDefinition.isDefined)
128+
"synthetic_definition"
129+
else if (isDefinition)
130+
"definition"
131+
else
132+
"reference"
133+
val indent =
134+
if (pos.startColumn > comment.length)
135+
" " * (pos.startColumn - comment.length)
136+
else
137+
""
138+
val caretCharacter =
139+
if (syntheticDefinition.isDefined)
140+
"_"
141+
else
142+
"^"
143+
val carets =
144+
if (pos.startColumn == 1)
145+
caretCharacter * (width - 1)
146+
else
147+
caretCharacter * width
148+
149+
val symbol = syntheticDefinition.fold(occ.getSymbol)(_.getSymbol)
150+
out
151+
.append(comment)
152+
.append(indent)
153+
.append(carets)
154+
.append(" ")
155+
.append(role)
156+
.append(" ")
157+
.append(symbol)
158+
if (isMultiline) {
159+
out.append(s" ${pos.endLine - pos.startLine}:${pos.endColumn}")
160+
}
161+
out.append("\n")
162+
163+
syntheticDefinition.orElse(symtab.get(occ.getSymbol)) match {
164+
case Some(info) if isDefinition =>
165+
val prefix =
166+
comment + (" " * indent.length) + (" " * carets.length) + " "
167+
0.until(info.getDocumentationCount)
168+
.foreach { n =>
169+
val documentation = info.getDocumentation(n)
170+
out
171+
.append(prefix)
172+
.append("documentation ")
173+
.append(documentation.replace("\n", "\\n").replace("\t", "\\t"))
174+
.append("\n")
175+
}
176+
0.until(info.getRelationshipsCount)
177+
.foreach { n =>
178+
val relationship = info.getRelationships(n)
179+
out.append(prefix).append("relationship")
180+
if (relationship.getIsReference) {
181+
out.append(" is_reference")
182+
}
183+
if (relationship.getIsDefinition) {
184+
out.append(" is_definition")
185+
}
186+
if (relationship.getIsImplementation) {
187+
out.append(" is_implementation")
188+
}
189+
if (relationship.getIsTypeDefinition) {
190+
out.append(" is_type_definition")
191+
}
192+
out.append(" ").append(relationship.getSymbol).append("\n")
193+
}
194+
case _ =>
195+
}
196+
}
197+
}

scip-java/src/main/scala/com/sourcegraph/scip_java/SemanticdbPrinters.scala

-119
This file was deleted.

scip-java/src/main/scala/com/sourcegraph/scip_java/buildtools/ScipBuildTool.scala

+2-1
Original file line numberDiff line numberDiff line change
@@ -387,7 +387,8 @@ class ScipBuildTool(index: IndexCommand) extends BuildTool("SCIP", index) {
387387
.getOrElse {
388388
throw new IllegalArgumentException(
389389
s"failed to infer the Scala version from the dependencies: " +
390-
pprint.PPrinter.BlackWhite.tokenize(deps.classpath).mkString
390+
pprint.PPrinter.BlackWhite.tokenize(deps.classpath).mkString +
391+
s"\n\nTo fix this, consider adding 'org.scala-lang:scala-library:${BuildInfo.scalaVersion}' to the list of dependencies."
391392
)
392393
}
393394
val mtags = Dependencies.resolveDependencies(

0 commit comments

Comments
 (0)