Skip to content

Commit

Permalink
Merge pull request #556 from sourcegraph/olafurpg/scip-snapshots
Browse files Browse the repository at this point in the history
Move to SCIP snapshots
  • Loading branch information
olafurpg authored Apr 20, 2023
2 parents 8c0dde7 + 12c0d14 commit dbb7d6a
Show file tree
Hide file tree
Showing 183 changed files with 27,656 additions and 22,562 deletions.
17 changes: 17 additions & 0 deletions scip-java-proto/src/main/protobuf/scip.proto
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,23 @@ message Relationship {
bool is_implementation = 3;
// Similar to `references_symbols` but for "Go to type definition".
bool is_type_definition = 4;
// Allows overriding the behavior of "Go to definition" and "Find references"
// for symbols which do not have a definition of their own or could
// potentially have multiple definitions.
//
// For example, in a language with single inheritance and no field overriding,
// inherited fields can reuse the same symbol as the ancestor which declares
// the field. In such a situation, is_definition is not needed.
//
// On the other hand, in languages with single inheritance and some form
// of mixins, you can use is_definition to relate the symbol to the
// matching symbol in ancestor classes, and is_reference to relate the
// symbol to the matching symbol in mixins.
//
// NOTE: At the moment, due to limitations of the SCIP to LSIF conversion,
// only global symbols in an index are allowed to use is_definition.
// The relationship may not get recorded if either symbol is local.
bool is_definition = 5;
}

// SymbolRole declares what "role" a symbol has in an occurrence. A role is
Expand Down
202 changes: 202 additions & 0 deletions scip-java/src/main/scala/com/sourcegraph/scip_java/ScipPrinters.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
package com.sourcegraph.scip_java

import scala.collection.mutable
import scala.jdk.CollectionConverters.CollectionHasAsScala
import scala.math.Ordering.Implicits.seqOrdering

import com.sourcegraph.Scip
import com.sourcegraph.Scip.SymbolRole
import com.sourcegraph.scip_java.commands.CommentSyntax
import moped.reporters.Input
import moped.reporters.Position

object ScipPrinters {

def printTextDocument(
doc: Scip.Document,
text: String,
comments: CommentSyntax = CommentSyntax.default
): String = {
val out = new mutable.StringBuilder()
val occurrencesByLine = doc
.getOccurrencesList
.asScala
.groupBy(_.getRange(0))
val symtab =
doc.getSymbolsList.asScala.map(info => info.getSymbol -> info).toMap

val syntheticDefinitions =
doc
.getSymbolsList
.asScala
.flatMap { info =>
info
.getRelationshipsList
.asScala
.collect {
case relationship if relationship.getIsDefinition =>
info -> relationship
}
}
.groupBy { case (_, relationship) =>
relationship.getSymbol
}
.view
.mapValues(
_.map { case (info, _) =>
info
}
)
.toMap
val extension = doc.getRelativePath.split("\\.").lastOption.getOrElse("")
val commentSyntax = comments.extensionSyntax(extension)
val input = Input.filename(doc.getRelativePath, text)
text
.linesWithSeparators
.zipWithIndex
.foreach { case (line, i) =>
out.append(line.replace("\t", ""))
val occurrences = occurrencesByLine
.getOrElse(i, Nil)
.toSeq
.sortBy(o =>
(o.getRangeList.asScala.toList.map(_.toInt), o.getSymbol)
)
occurrences.foreach { occ =>
formatOccurrence(input, out, occ, line, symtab, commentSyntax)
if ((occ.getSymbolRoles & SymbolRole.Definition_VALUE) > 0) {
syntheticDefinitions
.getOrElse(occ.getSymbol, Nil)
.foreach { syntheticDefinition =>
formatOccurrence(
input,
out,
occ,
line,
symtab,
commentSyntax,
syntheticDefinition = Some(syntheticDefinition)
)
}
}
}
}
out.toString()
}

private def mopedPosition(input: Input, occ: Scip.Occurrence): Position = {
if (occ.getRangeCount == 3)
Position.range(
input,
occ.getRange(0),
occ.getRange(1),
occ.getRange(0),
occ.getRange(2)
)
else if (occ.getRangeCount == 4)
Position.range(
input,
occ.getRange(0),
occ.getRange(1),
occ.getRange(2),
occ.getRange(3)
)
else
throw new IllegalArgumentException(s"Invalid range: $occ")
}

private def formatOccurrence(
input: Input,
out: mutable.StringBuilder,
occ: Scip.Occurrence,
line: String,
symtab: Map[String, Scip.SymbolInformation],
comment: String,
syntheticDefinition: Option[Scip.SymbolInformation] = None
): Unit = {
val pos = mopedPosition(input, occ)
val isMultiline = pos.startLine != pos.endLine
val width =
if (isMultiline) {
line.length - pos.startColumn - 1
} else {
math.max(1, pos.endColumn - pos.startColumn)
}

val isDefinition =
(occ.getSymbolRoles & SymbolRole.Definition.getNumber) > 0
val role =
if (syntheticDefinition.isDefined)
"synthetic_definition"
else if (isDefinition)
"definition"
else
"reference"
val indent =
if (pos.startColumn > comment.length)
" " * (pos.startColumn - comment.length)
else
""
val caretCharacter =
if (syntheticDefinition.isDefined)
"_"
else
"^"
val carets =
if (pos.startColumn == 1)
caretCharacter * (width - 1)
else
caretCharacter * width

val symbol = syntheticDefinition.fold(occ.getSymbol)(_.getSymbol)
out
.append(comment)
.append(indent)
.append(carets)
.append(" ")
.append(role)
.append(" ")
.append(symbol)
if (isMultiline) {
out.append(s" ${pos.endLine - pos.startLine}:${pos.endColumn}")
}
out.append("\n")

syntheticDefinition.orElse(symtab.get(occ.getSymbol)) match {
case Some(info) if isDefinition =>
val prefix =
comment + (" " * indent.length) + (" " * carets.length) + " "
0.until(info.getDocumentationCount)
.foreach { n =>
val documentation = info.getDocumentation(n)
out
.append(prefix)
.append("documentation ")
.append(documentation.replace("\n", "\\n").replace("\t", "\\t"))
.append("\n")
}
info
.getRelationshipsList
.asScala
.toList
.sortBy(_.getSymbol) // sort for deterministic order
.foreach { relationship =>
out.append(prefix).append("relationship")
if (relationship.getIsReference) {
out.append(" is_reference")
}
if (relationship.getIsDefinition) {
out.append(" is_definition")
}
if (relationship.getIsImplementation) {
out.append(" is_implementation")
}
if (relationship.getIsTypeDefinition) {
out.append(" is_type_definition")
}
out.append(" ").append(relationship.getSymbol).append("\n")
}
case _ =>
}
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -387,7 +387,8 @@ class ScipBuildTool(index: IndexCommand) extends BuildTool("SCIP", index) {
.getOrElse {
throw new IllegalArgumentException(
s"failed to infer the Scala version from the dependencies: " +
pprint.PPrinter.BlackWhite.tokenize(deps.classpath).mkString
pprint.PPrinter.BlackWhite.tokenize(deps.classpath).mkString +
s"\n\nTo fix this, consider adding 'org.scala-lang:scala-library:${BuildInfo.scalaVersion}' to the list of dependencies."
)
}
val mtags = Dependencies.resolveDependencies(
Expand Down
Loading

0 comments on commit dbb7d6a

Please sign in to comment.