Skip to content

Commit dbb7d6a

Browse files
authored
Merge pull request #556 from sourcegraph/olafurpg/scip-snapshots
Move to SCIP snapshots
2 parents 8c0dde7 + 12c0d14 commit dbb7d6a

File tree

183 files changed

+27656
-22562
lines changed

Some content is hidden

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

183 files changed

+27656
-22562
lines changed

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

Lines changed: 17 additions & 0 deletions
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
Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
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 =>
63+
(o.getRangeList.asScala.toList.map(_.toInt), o.getSymbol)
64+
)
65+
occurrences.foreach { occ =>
66+
formatOccurrence(input, out, occ, line, symtab, commentSyntax)
67+
if ((occ.getSymbolRoles & SymbolRole.Definition_VALUE) > 0) {
68+
syntheticDefinitions
69+
.getOrElse(occ.getSymbol, Nil)
70+
.foreach { syntheticDefinition =>
71+
formatOccurrence(
72+
input,
73+
out,
74+
occ,
75+
line,
76+
symtab,
77+
commentSyntax,
78+
syntheticDefinition = Some(syntheticDefinition)
79+
)
80+
}
81+
}
82+
}
83+
}
84+
out.toString()
85+
}
86+
87+
private def mopedPosition(input: Input, occ: Scip.Occurrence): Position = {
88+
if (occ.getRangeCount == 3)
89+
Position.range(
90+
input,
91+
occ.getRange(0),
92+
occ.getRange(1),
93+
occ.getRange(0),
94+
occ.getRange(2)
95+
)
96+
else if (occ.getRangeCount == 4)
97+
Position.range(
98+
input,
99+
occ.getRange(0),
100+
occ.getRange(1),
101+
occ.getRange(2),
102+
occ.getRange(3)
103+
)
104+
else
105+
throw new IllegalArgumentException(s"Invalid range: $occ")
106+
}
107+
108+
private def formatOccurrence(
109+
input: Input,
110+
out: mutable.StringBuilder,
111+
occ: Scip.Occurrence,
112+
line: String,
113+
symtab: Map[String, Scip.SymbolInformation],
114+
comment: String,
115+
syntheticDefinition: Option[Scip.SymbolInformation] = None
116+
): Unit = {
117+
val pos = mopedPosition(input, occ)
118+
val isMultiline = pos.startLine != pos.endLine
119+
val width =
120+
if (isMultiline) {
121+
line.length - pos.startColumn - 1
122+
} else {
123+
math.max(1, pos.endColumn - pos.startColumn)
124+
}
125+
126+
val isDefinition =
127+
(occ.getSymbolRoles & SymbolRole.Definition.getNumber) > 0
128+
val role =
129+
if (syntheticDefinition.isDefined)
130+
"synthetic_definition"
131+
else if (isDefinition)
132+
"definition"
133+
else
134+
"reference"
135+
val indent =
136+
if (pos.startColumn > comment.length)
137+
" " * (pos.startColumn - comment.length)
138+
else
139+
""
140+
val caretCharacter =
141+
if (syntheticDefinition.isDefined)
142+
"_"
143+
else
144+
"^"
145+
val carets =
146+
if (pos.startColumn == 1)
147+
caretCharacter * (width - 1)
148+
else
149+
caretCharacter * width
150+
151+
val symbol = syntheticDefinition.fold(occ.getSymbol)(_.getSymbol)
152+
out
153+
.append(comment)
154+
.append(indent)
155+
.append(carets)
156+
.append(" ")
157+
.append(role)
158+
.append(" ")
159+
.append(symbol)
160+
if (isMultiline) {
161+
out.append(s" ${pos.endLine - pos.startLine}:${pos.endColumn}")
162+
}
163+
out.append("\n")
164+
165+
syntheticDefinition.orElse(symtab.get(occ.getSymbol)) match {
166+
case Some(info) if isDefinition =>
167+
val prefix =
168+
comment + (" " * indent.length) + (" " * carets.length) + " "
169+
0.until(info.getDocumentationCount)
170+
.foreach { n =>
171+
val documentation = info.getDocumentation(n)
172+
out
173+
.append(prefix)
174+
.append("documentation ")
175+
.append(documentation.replace("\n", "\\n").replace("\t", "\\t"))
176+
.append("\n")
177+
}
178+
info
179+
.getRelationshipsList
180+
.asScala
181+
.toList
182+
.sortBy(_.getSymbol) // sort for deterministic order
183+
.foreach { relationship =>
184+
out.append(prefix).append("relationship")
185+
if (relationship.getIsReference) {
186+
out.append(" is_reference")
187+
}
188+
if (relationship.getIsDefinition) {
189+
out.append(" is_definition")
190+
}
191+
if (relationship.getIsImplementation) {
192+
out.append(" is_implementation")
193+
}
194+
if (relationship.getIsTypeDefinition) {
195+
out.append(" is_type_definition")
196+
}
197+
out.append(" ").append(relationship.getSymbol).append("\n")
198+
}
199+
case _ =>
200+
}
201+
}
202+
}

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

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

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

Lines changed: 2 additions & 1 deletion
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)