From 1a391dc30438f66bc73cf3cc87144cf7e5e44f1b Mon Sep 17 00:00:00 2001 From: jupblb Date: Wed, 3 Jun 2026 14:06:38 +0200 Subject: [PATCH 1/5] Extract SemanticdbSymbols to shared module Move the proto-free symbol-encoding helper to a new semanticdb-shared module so semanticdb-java and semanticdb-kotlinc can both depend on it. The Kotlin Symbol value class and SemanticdbSymbolDescriptor data class now delegate descriptor encoding to the shared Java implementation instead of duplicating it. --- build.sbt | 13 +++++ .../sourcegraph/scip_java/ScipSymbol.scala | 2 +- scip-semanticdb/BUILD | 1 + .../scip_semanticdb/ScipSemanticdb.java | 2 +- .../scip_semanticdb/SignatureFormatter.java | 2 +- .../scip_semanticdb/SymbolDescriptor.java | 6 +- semanticdb-javac/BUILD | 1 + .../semanticdb_javac/GlobalSymbolsCache.java | 2 + .../semanticdb_javac/LocalSymbolsCache.java | 2 + .../semanticdb_javac/SemanticdbVisitor.java | 2 + .../semanticdb_kotlinc/SemanticdbSymbols.kt | 58 +++++++++---------- semanticdb-shared/BUILD | 10 ++++ .../semanticdb}/SemanticdbSymbols.java | 2 +- .../scala/tests/SymbolDescriptorSuite.scala | 2 +- 14 files changed, 68 insertions(+), 37 deletions(-) create mode 100644 semanticdb-shared/BUILD rename {semanticdb-java/src/main/java/com/sourcegraph/semanticdb_javac => semanticdb-shared/src/main/java/com/sourcegraph/semanticdb}/SemanticdbSymbols.java (99%) diff --git a/build.sbt b/build.sbt index e1eeca85d..b5dc58769 100644 --- a/build.sbt +++ b/build.sbt @@ -72,6 +72,17 @@ commands += "scalafixAll --check" :: "publishLocal" :: s } +// Shared, proto-free utility code consumed by both the Java and Kotlin +// SemanticDB compiler plugins. Kept intentionally small so each plugin's +// fat-jar pays only for the encoding helpers, not for the full Java proto +// schema. +lazy val semanticdbShared = project + .in(file("semanticdb-shared")) + .settings( + moduleName := "semanticdb-shared", + javaOnlySettings + ) + lazy val semanticdb = project .in(file("semanticdb-java")) .settings( @@ -80,6 +91,7 @@ lazy val semanticdb = project (Compile / PB.targets) := Seq(PB.gens.java(V.protobuf) -> (Compile / sourceManaged).value) ) + .dependsOn(semanticdbShared) lazy val agent = project .in(file("semanticdb-agent")) @@ -431,6 +443,7 @@ lazy val semanticdbKotlinc = project Attributed.blank(dir) } ) + .dependsOn(semanticdbShared) // `semanticdbKotlincMinimized` mirrors the (still-present) Gradle build at // semanticdb-kotlinc/minimized/build.gradle.kts. It compiles a small set of diff --git a/scip-java/src/main/scala/com/sourcegraph/scip_java/ScipSymbol.scala b/scip-java/src/main/scala/com/sourcegraph/scip_java/ScipSymbol.scala index 2ab5e2b1f..d2cf98c79 100644 --- a/scip-java/src/main/scala/com/sourcegraph/scip_java/ScipSymbol.scala +++ b/scip-java/src/main/scala/com/sourcegraph/scip_java/ScipSymbol.scala @@ -1,7 +1,7 @@ package com.sourcegraph.scip_java import com.sourcegraph.scip_semanticdb.SymbolDescriptor -import com.sourcegraph.semanticdb_javac.SemanticdbSymbols +import com.sourcegraph.semanticdb.SemanticdbSymbols sealed abstract class ScipSymbol {} final case class LocalScipSymbol(identifier: String) extends ScipSymbol diff --git a/scip-semanticdb/BUILD b/scip-semanticdb/BUILD index 5a1388038..b7de2764b 100644 --- a/scip-semanticdb/BUILD +++ b/scip-semanticdb/BUILD @@ -21,6 +21,7 @@ java_library( ":all_java_proto", "//semanticdb-java", "//semanticdb-java/src/main/protobuf:semanticdb_java_proto", + "//semanticdb-shared", "@maven//:com_google_code_findbugs_jsr305", "@maven//:com_google_protobuf_protobuf_java", "@maven//:com_google_protobuf_protobuf_java_util", diff --git a/scip-semanticdb/src/main/java/com/sourcegraph/scip_semanticdb/ScipSemanticdb.java b/scip-semanticdb/src/main/java/com/sourcegraph/scip_semanticdb/ScipSemanticdb.java index 065ba314b..29d429ced 100644 --- a/scip-semanticdb/src/main/java/com/sourcegraph/scip_semanticdb/ScipSemanticdb.java +++ b/scip-semanticdb/src/main/java/com/sourcegraph/scip_semanticdb/ScipSemanticdb.java @@ -4,7 +4,7 @@ import com.sourcegraph.semanticdb_javac.Semanticdb; import com.sourcegraph.semanticdb_javac.Semanticdb.SymbolOccurrence; import com.sourcegraph.semanticdb_javac.Semanticdb.SymbolOccurrence.Role; -import com.sourcegraph.semanticdb_javac.SemanticdbSymbols; +import com.sourcegraph.semanticdb.SemanticdbSymbols; import org.scip_code.scip.Document; import org.scip_code.scip.Index; import org.scip_code.scip.Metadata; diff --git a/scip-semanticdb/src/main/java/com/sourcegraph/scip_semanticdb/SignatureFormatter.java b/scip-semanticdb/src/main/java/com/sourcegraph/scip_semanticdb/SignatureFormatter.java index fc306ad25..308e509d3 100644 --- a/scip-semanticdb/src/main/java/com/sourcegraph/scip_semanticdb/SignatureFormatter.java +++ b/scip-semanticdb/src/main/java/com/sourcegraph/scip_semanticdb/SignatureFormatter.java @@ -3,7 +3,7 @@ import com.sourcegraph.semanticdb_javac.Semanticdb.SymbolInformation.Property; import com.sourcegraph.semanticdb_javac.Semanticdb.*; -import com.sourcegraph.semanticdb_javac.SemanticdbSymbols; +import com.sourcegraph.semanticdb.SemanticdbSymbols; import java.util.*; import java.util.concurrent.atomic.AtomicInteger; diff --git a/scip-semanticdb/src/main/java/com/sourcegraph/scip_semanticdb/SymbolDescriptor.java b/scip-semanticdb/src/main/java/com/sourcegraph/scip_semanticdb/SymbolDescriptor.java index 77bfb32a5..146ecdf79 100644 --- a/scip-semanticdb/src/main/java/com/sourcegraph/scip_semanticdb/SymbolDescriptor.java +++ b/scip-semanticdb/src/main/java/com/sourcegraph/scip_semanticdb/SymbolDescriptor.java @@ -1,8 +1,8 @@ package com.sourcegraph.scip_semanticdb; -import com.sourcegraph.semanticdb_javac.SemanticdbSymbols; -import com.sourcegraph.semanticdb_javac.SemanticdbSymbols.Descriptor; -import com.sourcegraph.semanticdb_javac.SemanticdbSymbols.Descriptor.Kind; +import com.sourcegraph.semanticdb.SemanticdbSymbols; +import com.sourcegraph.semanticdb.SemanticdbSymbols.Descriptor; +import com.sourcegraph.semanticdb.SemanticdbSymbols.Descriptor.Kind; import java.util.Optional; public class SymbolDescriptor { diff --git a/semanticdb-javac/BUILD b/semanticdb-javac/BUILD index d0d8894f5..af5538d4a 100644 --- a/semanticdb-javac/BUILD +++ b/semanticdb-javac/BUILD @@ -33,5 +33,6 @@ java_library( deps = [ "//semanticdb-java", "//semanticdb-java/src/main/protobuf:semanticdb_java_proto", + "//semanticdb-shared", ], ) diff --git a/semanticdb-javac/src/main/java/com/sourcegraph/semanticdb_javac/GlobalSymbolsCache.java b/semanticdb-javac/src/main/java/com/sourcegraph/semanticdb_javac/GlobalSymbolsCache.java index 72c9b887d..f819b3ddc 100644 --- a/semanticdb-javac/src/main/java/com/sourcegraph/semanticdb_javac/GlobalSymbolsCache.java +++ b/semanticdb-javac/src/main/java/com/sourcegraph/semanticdb_javac/GlobalSymbolsCache.java @@ -1,5 +1,7 @@ package com.sourcegraph.semanticdb_javac; +import com.sourcegraph.semanticdb.SemanticdbSymbols; + import javax.lang.model.element.Element; import javax.lang.model.element.ExecutableElement; import javax.lang.model.element.TypeElement; diff --git a/semanticdb-javac/src/main/java/com/sourcegraph/semanticdb_javac/LocalSymbolsCache.java b/semanticdb-javac/src/main/java/com/sourcegraph/semanticdb_javac/LocalSymbolsCache.java index db22699c5..f28dd4189 100644 --- a/semanticdb-javac/src/main/java/com/sourcegraph/semanticdb_javac/LocalSymbolsCache.java +++ b/semanticdb-javac/src/main/java/com/sourcegraph/semanticdb_javac/LocalSymbolsCache.java @@ -1,5 +1,7 @@ package com.sourcegraph.semanticdb_javac; +import com.sourcegraph.semanticdb.SemanticdbSymbols; + import javax.lang.model.element.Element; import java.util.IdentityHashMap; diff --git a/semanticdb-javac/src/main/java/com/sourcegraph/semanticdb_javac/SemanticdbVisitor.java b/semanticdb-javac/src/main/java/com/sourcegraph/semanticdb_javac/SemanticdbVisitor.java index 3a24aa885..c99907116 100644 --- a/semanticdb-javac/src/main/java/com/sourcegraph/semanticdb_javac/SemanticdbVisitor.java +++ b/semanticdb-javac/src/main/java/com/sourcegraph/semanticdb_javac/SemanticdbVisitor.java @@ -1,5 +1,7 @@ package com.sourcegraph.semanticdb_javac; +import com.sourcegraph.semanticdb.SemanticdbSymbols; + import com.sun.source.util.SourcePositions; import com.sun.source.util.Trees; import com.sun.source.util.TreePathScanner; diff --git a/semanticdb-kotlinc/src/main/kotlin/com/sourcegraph/semanticdb_kotlinc/SemanticdbSymbols.kt b/semanticdb-kotlinc/src/main/kotlin/com/sourcegraph/semanticdb_kotlinc/SemanticdbSymbols.kt index 3e60befcf..74d7fc51f 100644 --- a/semanticdb-kotlinc/src/main/kotlin/com/sourcegraph/semanticdb_kotlinc/SemanticdbSymbols.kt +++ b/semanticdb-kotlinc/src/main/kotlin/com/sourcegraph/semanticdb_kotlinc/SemanticdbSymbols.kt @@ -1,11 +1,17 @@ package com.sourcegraph.semanticdb_kotlinc +import com.sourcegraph.semanticdb.SemanticdbSymbols as SharedSymbols + @JvmInline value class Symbol(private val symbol: String) { companion object { - val NONE = Symbol("") - val ROOT_PACKAGE = Symbol("_root_/") + val NONE = Symbol(SharedSymbols.NONE) + val ROOT_PACKAGE = Symbol(SharedSymbols.ROOT_PACKAGE) + // Note: this intentionally diverges from `SharedSymbols.global` when + // `desc == NONE` — Java returns `NONE`, Kotlin returns the owner. + // SymbolsCache relies on this behavior; do not delegate without first + // updating those call sites. fun createGlobal(owner: Symbol, desc: SemanticdbSymbolDescriptor): Symbol = when { desc == SemanticdbSymbolDescriptor.NONE -> owner @@ -13,12 +19,12 @@ value class Symbol(private val symbol: String) { else -> desc.encode() } - fun createLocal(i: Int) = Symbol("local$i") + fun createLocal(i: Int) = Symbol(SharedSymbols.local(i)) } - fun isGlobal() = !isLocal() + fun isGlobal() = SharedSymbols.isGlobal(symbol) - fun isLocal() = symbol.startsWith("local") + fun isLocal() = SharedSymbols.isLocal(symbol) override fun toString(): String = symbol } @@ -28,22 +34,13 @@ fun String.symbol(): Symbol = Symbol(this) data class SemanticdbSymbolDescriptor( val kind: Kind, val name: String, + // Default differs from `SharedSymbols.Descriptor` (which is "") because + // Kotlin call sites — getters/setters in particular — rely on the no-arg + // overload producing `name().` rather than `name.` for METHOD kinds. val disambiguator: String = "()" ) { companion object { val NONE = SemanticdbSymbolDescriptor(Kind.NONE, "") - - private fun encodeName(name: String): String { - if (name.isEmpty()) return "``" - val isStartOk = Character.isJavaIdentifierStart(name[0]) - var isPartsOk = true - var i = 1 - while (isPartsOk && i < name.length) { - isPartsOk = Character.isJavaIdentifierPart(name[i]) - i++ - } - return if (isStartOk && isPartsOk) name else "`$name`" - } } enum class Kind { @@ -53,18 +50,21 @@ data class SemanticdbSymbolDescriptor( TYPE, PACKAGE, PARAMETER, - TYPE_PARAMETER + TYPE_PARAMETER; + + internal fun toSharedKind(): SharedSymbols.Descriptor.Kind = + when (this) { + NONE -> SharedSymbols.Descriptor.Kind.None + TERM -> SharedSymbols.Descriptor.Kind.Term + METHOD -> SharedSymbols.Descriptor.Kind.Method + TYPE -> SharedSymbols.Descriptor.Kind.Type + PACKAGE -> SharedSymbols.Descriptor.Kind.Package + PARAMETER -> SharedSymbols.Descriptor.Kind.Parameter + TYPE_PARAMETER -> SharedSymbols.Descriptor.Kind.TypeParameter + } } - fun encode() = - Symbol( - when (kind) { - Kind.NONE -> "" - Kind.TERM -> "${encodeName(name)}." - Kind.METHOD -> "${encodeName(name)}${disambiguator}." - Kind.TYPE -> "${encodeName(name)}#" - Kind.PACKAGE -> "${encodeName(name)}/" - Kind.PARAMETER -> "(${encodeName(name)})" - Kind.TYPE_PARAMETER -> "[${encodeName(name)}]" - }) + fun encode(): Symbol = + if (kind == Kind.NONE) Symbol(SharedSymbols.NONE) + else Symbol(SharedSymbols.Descriptor(kind.toSharedKind(), name, disambiguator).encode()) } diff --git a/semanticdb-shared/BUILD b/semanticdb-shared/BUILD new file mode 100644 index 000000000..2efbc3ea3 --- /dev/null +++ b/semanticdb-shared/BUILD @@ -0,0 +1,10 @@ +load("@rules_java//java:defs.bzl", "java_library") + +package( + default_visibility = ["//visibility:public"], +) + +java_library( + name = "semanticdb-shared", + srcs = glob(["src/main/java/**/*.java"]), +) diff --git a/semanticdb-java/src/main/java/com/sourcegraph/semanticdb_javac/SemanticdbSymbols.java b/semanticdb-shared/src/main/java/com/sourcegraph/semanticdb/SemanticdbSymbols.java similarity index 99% rename from semanticdb-java/src/main/java/com/sourcegraph/semanticdb_javac/SemanticdbSymbols.java rename to semanticdb-shared/src/main/java/com/sourcegraph/semanticdb/SemanticdbSymbols.java index 94ca1695e..8f1ec4f3f 100644 --- a/semanticdb-java/src/main/java/com/sourcegraph/semanticdb_javac/SemanticdbSymbols.java +++ b/semanticdb-shared/src/main/java/com/sourcegraph/semanticdb/SemanticdbSymbols.java @@ -1,4 +1,4 @@ -package com.sourcegraph.semanticdb_javac; +package com.sourcegraph.semanticdb; import java.util.Objects; diff --git a/tests/unit/src/test/scala/tests/SymbolDescriptorSuite.scala b/tests/unit/src/test/scala/tests/SymbolDescriptorSuite.scala index 9e07f8d99..9888e1625 100644 --- a/tests/unit/src/test/scala/tests/SymbolDescriptorSuite.scala +++ b/tests/unit/src/test/scala/tests/SymbolDescriptorSuite.scala @@ -3,7 +3,7 @@ package tests import scala.meta.internal.semanticdb.Scala._ import com.sourcegraph.scip_semanticdb.SymbolDescriptor -import com.sourcegraph.semanticdb_javac.SemanticdbSymbols.Descriptor.Kind +import com.sourcegraph.semanticdb.SemanticdbSymbols.Descriptor.Kind import munit.FunSuite import munit.TestOptions From f8aad728897824f11b417f7d72f41a6a26be3997 Mon Sep 17 00:00:00 2001 From: jupblb Date: Wed, 3 Jun 2026 16:00:52 +0200 Subject: [PATCH 2/5] Unify SemanticDB proto schema in shared module Collapse the Java and Kotlin proto definitions into a single canonical schema at semanticdb-shared/src/main/protobuf/semanticdb.proto, generated to com.sourcegraph.semanticdb. The Java schema (a strict superset of the Kotlin one) wins. The standalone semanticdb-java SBT/Bazel module is removed; semanticdb-javac, scip-semanticdb, and semanticdb-kotlinc now all depend on semanticdb-shared. Snapshot regeneration produces byte-identical output, confirming no behavioral change to .semanticdb files. --- build.sbt | 32 +-- scip-semanticdb/BUILD | 2 - .../scip_semanticdb/RangeComparator.java | 2 +- .../scip_semanticdb/ScipSemanticdb.java | 6 +- .../scip_semanticdb/ScipTextDocument.java | 2 +- .../SemanticdbTreeVisitor.java | 2 +- .../scip_semanticdb/SignatureFormatter.java | 6 +- .../SignatureFormatterException.java | 2 +- .../scip_semanticdb/SymbolOccurrences.java | 2 +- .../sourcegraph/scip_semanticdb/Symtab.java | 2 +- semanticdb-java/BUILD | 13 -- semanticdb-java/src/main/protobuf/BUILD | 16 -- semanticdb-javac/BUILD | 2 - .../SemanticdbSignatures.java | 6 +- .../SemanticdbTaskListener.java | 2 + .../semanticdb_javac/SemanticdbTrees.java | 4 +- .../SemanticdbTypeVisitor.java | 4 +- .../semanticdb_javac/SemanticdbVisitor.java | 10 +- .../semanticdb_kotlinc/SemanticdbBuilders.kt | 2 + .../semanticdb_kotlinc/AnalyzerRegistrar.kt | 2 + .../PostAnalysisExtension.kt | 2 + .../SemanticdbTextDocumentBuilder.kt | 4 +- .../semanticdb_kotlinc/SemanticdbVisitor.kt | 4 +- .../semanticdb.proto | 192 ------------------ .../semanticdb_kotlinc/test/AnalyzerTest.kt | 8 +- .../test/SemanticdbSymbolsTest.kt | 8 +- .../semanticdb_kotlinc/test/Utils.kt | 2 + semanticdb-shared/BUILD | 14 ++ .../semanticdb}/SemanticdbBuilders.java | 2 +- .../src/main/protobuf/semanticdb.proto | 7 +- .../src/main/scala/tests/SemanticdbFile.scala | 4 +- .../src/main/scala/tests/CompileResult.scala | 2 +- .../src/main/scala/tests/TestCompiler.scala | 2 +- .../tests/GeneratedConstructorSuite.scala | 2 +- .../src/test/scala/tests/TargetedSuite.scala | 4 +- 35 files changed, 93 insertions(+), 283 deletions(-) delete mode 100644 semanticdb-java/BUILD delete mode 100644 semanticdb-java/src/main/protobuf/BUILD delete mode 100644 semanticdb-kotlinc/src/main/proto/com.sourcegraph.semanticdb_kotlin/semanticdb.proto rename {semanticdb-java/src/main/java/com/sourcegraph/semanticdb_javac => semanticdb-shared/src/main/java/com/sourcegraph/semanticdb}/SemanticdbBuilders.java (99%) rename {semanticdb-java => semanticdb-shared}/src/main/protobuf/semanticdb.proto (97%) diff --git a/build.sbt b/build.sbt index b5dc58769..d4c56a8f0 100644 --- a/build.sbt +++ b/build.sbt @@ -72,26 +72,20 @@ commands += "scalafixAll --check" :: "publishLocal" :: s } -// Shared, proto-free utility code consumed by both the Java and Kotlin -// SemanticDB compiler plugins. Kept intentionally small so each plugin's -// fat-jar pays only for the encoding helpers, not for the full Java proto -// schema. +// Shared module that owns the canonical SemanticDB proto schema and the +// associated symbol/builder utilities. Both the Java compiler plugin +// (semanticdb-javac) and the Kotlin compiler plugin (semanticdb-kotlinc) +// depend on it instead of carrying their own divergent copies of the proto. lazy val semanticdbShared = project .in(file("semanticdb-shared")) .settings( moduleName := "semanticdb-shared", - javaOnlySettings - ) - -lazy val semanticdb = project - .in(file("semanticdb-java")) - .settings( - moduleName := "semanticdb-java", javaOnlySettings, (Compile / PB.targets) := - Seq(PB.gens.java(V.protobuf) -> (Compile / sourceManaged).value) + Seq(PB.gens.java(V.protobuf) -> (Compile / sourceManaged).value), + libraryDependencies += + "com.google.protobuf" % "protobuf-java" % V.protobuf ) - .dependsOn(semanticdbShared) lazy val agent = project .in(file("semanticdb-agent")) @@ -182,7 +176,7 @@ lazy val javacPlugin = project .inAll ) ) - .dependsOn(semanticdb) + .dependsOn(semanticdbShared) lazy val scip = project .in(file("scip-semanticdb")) @@ -196,7 +190,7 @@ lazy val scip = project Seq(PB.gens.java(V.protobuf) -> (Compile / sourceManaged).value), Compile / PB.protocOptions := Seq("--experimental_allow_proto3_optional") ) - .dependsOn(semanticdb) + .dependsOn(semanticdbShared) lazy val mavenPlugin = project .in(file("maven-plugin")) @@ -365,12 +359,8 @@ lazy val semanticdbKotlinc = project // classpath via Provided so the assembled fat-jar does not bundle it. libraryDependencies += "org.jetbrains.kotlin" % "kotlin-stdlib" % V.kotlinVersion % Provided, - // protobuf java codegen — proto file lives at src/main/proto/... - Compile / PB.protoSources := - Seq((Compile / sourceDirectory).value / "proto"), - Compile / PB.targets := - Seq(PB.gens.java(V.protobuf) -> (Compile / sourceManaged).value), - libraryDependencies += "com.google.protobuf" % "protobuf-java" % V.protobuf, + // The SemanticDB proto schema and the generated Java classes live in + // semanticdbShared; we get them transitively via .dependsOn below. // kotlin-compiler-embeddable is supplied by kotlinc at runtime libraryDependencies += "org.jetbrains.kotlin" % "kotlin-compiler-embeddable" % V.kotlinVersion % diff --git a/scip-semanticdb/BUILD b/scip-semanticdb/BUILD index b7de2764b..9cee3def4 100644 --- a/scip-semanticdb/BUILD +++ b/scip-semanticdb/BUILD @@ -19,8 +19,6 @@ java_library( srcs = glob(["src/main/java/**/*.java"]), deps = [ ":all_java_proto", - "//semanticdb-java", - "//semanticdb-java/src/main/protobuf:semanticdb_java_proto", "//semanticdb-shared", "@maven//:com_google_code_findbugs_jsr305", "@maven//:com_google_protobuf_protobuf_java", diff --git a/scip-semanticdb/src/main/java/com/sourcegraph/scip_semanticdb/RangeComparator.java b/scip-semanticdb/src/main/java/com/sourcegraph/scip_semanticdb/RangeComparator.java index aa16a5af2..951028c22 100644 --- a/scip-semanticdb/src/main/java/com/sourcegraph/scip_semanticdb/RangeComparator.java +++ b/scip-semanticdb/src/main/java/com/sourcegraph/scip_semanticdb/RangeComparator.java @@ -1,6 +1,6 @@ package com.sourcegraph.scip_semanticdb; -import com.sourcegraph.semanticdb_javac.Semanticdb.Range; +import com.sourcegraph.semanticdb.Semanticdb.Range; /** * Comparator that sorts SemanticDB ranges by appearance in the document. diff --git a/scip-semanticdb/src/main/java/com/sourcegraph/scip_semanticdb/ScipSemanticdb.java b/scip-semanticdb/src/main/java/com/sourcegraph/scip_semanticdb/ScipSemanticdb.java index 29d429ced..540dd83d6 100644 --- a/scip-semanticdb/src/main/java/com/sourcegraph/scip_semanticdb/ScipSemanticdb.java +++ b/scip-semanticdb/src/main/java/com/sourcegraph/scip_semanticdb/ScipSemanticdb.java @@ -1,9 +1,9 @@ package com.sourcegraph.scip_semanticdb; import com.google.protobuf.CodedInputStream; -import com.sourcegraph.semanticdb_javac.Semanticdb; -import com.sourcegraph.semanticdb_javac.Semanticdb.SymbolOccurrence; -import com.sourcegraph.semanticdb_javac.Semanticdb.SymbolOccurrence.Role; +import com.sourcegraph.semanticdb.Semanticdb; +import com.sourcegraph.semanticdb.Semanticdb.SymbolOccurrence; +import com.sourcegraph.semanticdb.Semanticdb.SymbolOccurrence.Role; import com.sourcegraph.semanticdb.SemanticdbSymbols; import org.scip_code.scip.Document; import org.scip_code.scip.Index; diff --git a/scip-semanticdb/src/main/java/com/sourcegraph/scip_semanticdb/ScipTextDocument.java b/scip-semanticdb/src/main/java/com/sourcegraph/scip_semanticdb/ScipTextDocument.java index 4b6307a88..13c5dddae 100644 --- a/scip-semanticdb/src/main/java/com/sourcegraph/scip_semanticdb/ScipTextDocument.java +++ b/scip-semanticdb/src/main/java/com/sourcegraph/scip_semanticdb/ScipTextDocument.java @@ -1,6 +1,6 @@ package com.sourcegraph.scip_semanticdb; -import com.sourcegraph.semanticdb_javac.Semanticdb; +import com.sourcegraph.semanticdb.Semanticdb; import java.nio.file.Path; import java.util.ArrayList; diff --git a/scip-semanticdb/src/main/java/com/sourcegraph/scip_semanticdb/SemanticdbTreeVisitor.java b/scip-semanticdb/src/main/java/com/sourcegraph/scip_semanticdb/SemanticdbTreeVisitor.java index 3ecd82a48..ca9b296cd 100644 --- a/scip-semanticdb/src/main/java/com/sourcegraph/scip_semanticdb/SemanticdbTreeVisitor.java +++ b/scip-semanticdb/src/main/java/com/sourcegraph/scip_semanticdb/SemanticdbTreeVisitor.java @@ -1,6 +1,6 @@ package com.sourcegraph.scip_semanticdb; -import com.sourcegraph.semanticdb_javac.Semanticdb.*; +import com.sourcegraph.semanticdb.Semanticdb.*; public abstract class SemanticdbTreeVisitor { public void visitTree(Tree tree) { diff --git a/scip-semanticdb/src/main/java/com/sourcegraph/scip_semanticdb/SignatureFormatter.java b/scip-semanticdb/src/main/java/com/sourcegraph/scip_semanticdb/SignatureFormatter.java index 308e509d3..216c2adb3 100644 --- a/scip-semanticdb/src/main/java/com/sourcegraph/scip_semanticdb/SignatureFormatter.java +++ b/scip-semanticdb/src/main/java/com/sourcegraph/scip_semanticdb/SignatureFormatter.java @@ -1,7 +1,7 @@ package com.sourcegraph.scip_semanticdb; -import com.sourcegraph.semanticdb_javac.Semanticdb.SymbolInformation.Property; -import com.sourcegraph.semanticdb_javac.Semanticdb.*; +import com.sourcegraph.semanticdb.Semanticdb.SymbolInformation.Property; +import com.sourcegraph.semanticdb.Semanticdb.*; import com.sourcegraph.semanticdb.SemanticdbSymbols; @@ -9,7 +9,7 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Collectors; -import static com.sourcegraph.semanticdb_javac.SemanticdbBuilders.typeRef; +import static com.sourcegraph.semanticdb.SemanticdbBuilders.typeRef; public class SignatureFormatter { private static final Type OBJECT_TYPE_REF = typeRef("java/lang/Object#"); diff --git a/scip-semanticdb/src/main/java/com/sourcegraph/scip_semanticdb/SignatureFormatterException.java b/scip-semanticdb/src/main/java/com/sourcegraph/scip_semanticdb/SignatureFormatterException.java index 5c094aebc..32799afb2 100644 --- a/scip-semanticdb/src/main/java/com/sourcegraph/scip_semanticdb/SignatureFormatterException.java +++ b/scip-semanticdb/src/main/java/com/sourcegraph/scip_semanticdb/SignatureFormatterException.java @@ -1,6 +1,6 @@ package com.sourcegraph.scip_semanticdb; -import com.sourcegraph.semanticdb_javac.Semanticdb; +import com.sourcegraph.semanticdb.Semanticdb; public class SignatureFormatterException extends RuntimeException { public SignatureFormatterException( diff --git a/scip-semanticdb/src/main/java/com/sourcegraph/scip_semanticdb/SymbolOccurrences.java b/scip-semanticdb/src/main/java/com/sourcegraph/scip_semanticdb/SymbolOccurrences.java index b4d309491..5ffe51001 100644 --- a/scip-semanticdb/src/main/java/com/sourcegraph/scip_semanticdb/SymbolOccurrences.java +++ b/scip-semanticdb/src/main/java/com/sourcegraph/scip_semanticdb/SymbolOccurrences.java @@ -1,6 +1,6 @@ package com.sourcegraph.scip_semanticdb; -import com.sourcegraph.semanticdb_javac.Semanticdb; +import com.sourcegraph.semanticdb.Semanticdb; import java.util.ArrayList; import java.util.List; diff --git a/scip-semanticdb/src/main/java/com/sourcegraph/scip_semanticdb/Symtab.java b/scip-semanticdb/src/main/java/com/sourcegraph/scip_semanticdb/Symtab.java index 5324df0e5..5cd54d7cf 100644 --- a/scip-semanticdb/src/main/java/com/sourcegraph/scip_semanticdb/Symtab.java +++ b/scip-semanticdb/src/main/java/com/sourcegraph/scip_semanticdb/Symtab.java @@ -1,6 +1,6 @@ package com.sourcegraph.scip_semanticdb; -import com.sourcegraph.semanticdb_javac.Semanticdb; +import com.sourcegraph.semanticdb.Semanticdb; import java.util.HashMap; diff --git a/semanticdb-java/BUILD b/semanticdb-java/BUILD deleted file mode 100644 index ea48f270f..000000000 --- a/semanticdb-java/BUILD +++ /dev/null @@ -1,13 +0,0 @@ -load("@rules_java//java:defs.bzl", "java_library") - -package( - default_visibility = ["//visibility:public"], -) - -java_library( - name = "semanticdb-java", - srcs = glob(["src/main/java/**/*.java"]), - deps = [ - "//semanticdb-java/src/main/protobuf:semanticdb_java_proto", - ], -) diff --git a/semanticdb-java/src/main/protobuf/BUILD b/semanticdb-java/src/main/protobuf/BUILD deleted file mode 100644 index 85ba0e731..000000000 --- a/semanticdb-java/src/main/protobuf/BUILD +++ /dev/null @@ -1,16 +0,0 @@ -load("@com_google_protobuf//bazel:java_proto_library.bzl", "java_proto_library") -load("@com_google_protobuf//bazel:proto_library.bzl", "proto_library") - -package( - default_visibility = ["//visibility:public"], -) - -java_proto_library( - name = "semanticdb_java_proto", - deps = [":semanticdb_proto"], -) - -proto_library( - name = "semanticdb_proto", - srcs = ["semanticdb.proto"], -) diff --git a/semanticdb-javac/BUILD b/semanticdb-javac/BUILD index af5538d4a..b243e7e6d 100644 --- a/semanticdb-javac/BUILD +++ b/semanticdb-javac/BUILD @@ -31,8 +31,6 @@ java_library( srcs = glob(["src/main/java/**/*.java"]), resources = ["src/main/resources/META-INF/services/com.sun.source.util.Plugin"], deps = [ - "//semanticdb-java", - "//semanticdb-java/src/main/protobuf:semanticdb_java_proto", "//semanticdb-shared", ], ) diff --git a/semanticdb-javac/src/main/java/com/sourcegraph/semanticdb_javac/SemanticdbSignatures.java b/semanticdb-javac/src/main/java/com/sourcegraph/semanticdb_javac/SemanticdbSignatures.java index 6e4fedf0e..884d2b743 100644 --- a/semanticdb-javac/src/main/java/com/sourcegraph/semanticdb_javac/SemanticdbSignatures.java +++ b/semanticdb-javac/src/main/java/com/sourcegraph/semanticdb_javac/SemanticdbSignatures.java @@ -1,6 +1,8 @@ package com.sourcegraph.semanticdb_javac; -import com.sourcegraph.semanticdb_javac.Semanticdb.*; +import com.sourcegraph.semanticdb.Semanticdb; + +import com.sourcegraph.semanticdb.Semanticdb.*; import javax.lang.model.element.Element; import javax.lang.model.element.TypeElement; @@ -13,7 +15,7 @@ import java.util.List; import java.util.stream.Collectors; -import static com.sourcegraph.semanticdb_javac.SemanticdbBuilders.*; +import static com.sourcegraph.semanticdb.SemanticdbBuilders.*; import static com.sourcegraph.semanticdb_javac.SemanticdbTypeVisitor.UNRESOLVED_TYPE_REF; public final class SemanticdbSignatures { diff --git a/semanticdb-javac/src/main/java/com/sourcegraph/semanticdb_javac/SemanticdbTaskListener.java b/semanticdb-javac/src/main/java/com/sourcegraph/semanticdb_javac/SemanticdbTaskListener.java index bba83849f..049b370f4 100644 --- a/semanticdb-javac/src/main/java/com/sourcegraph/semanticdb_javac/SemanticdbTaskListener.java +++ b/semanticdb-javac/src/main/java/com/sourcegraph/semanticdb_javac/SemanticdbTaskListener.java @@ -1,5 +1,7 @@ package com.sourcegraph.semanticdb_javac; +import com.sourcegraph.semanticdb.Semanticdb; + import com.sun.source.util.JavacTask; import com.sun.source.util.TaskEvent; import com.sun.source.util.TaskListener; diff --git a/semanticdb-javac/src/main/java/com/sourcegraph/semanticdb_javac/SemanticdbTrees.java b/semanticdb-javac/src/main/java/com/sourcegraph/semanticdb_javac/SemanticdbTrees.java index f78b5abe6..63ec3eb09 100644 --- a/semanticdb-javac/src/main/java/com/sourcegraph/semanticdb_javac/SemanticdbTrees.java +++ b/semanticdb-javac/src/main/java/com/sourcegraph/semanticdb_javac/SemanticdbTrees.java @@ -1,5 +1,7 @@ package com.sourcegraph.semanticdb_javac; +import com.sourcegraph.semanticdb.Semanticdb; + import com.sun.source.tree.*; import com.sun.source.util.Trees; import javax.lang.model.element.Element; @@ -14,7 +16,7 @@ import java.util.List; import java.util.stream.Collectors; -import static com.sourcegraph.semanticdb_javac.SemanticdbBuilders.*; +import static com.sourcegraph.semanticdb.SemanticdbBuilders.*; import static com.sourcegraph.semanticdb_javac.SemanticdbTypeVisitor.ARRAY_SYMBOL; public class SemanticdbTrees { diff --git a/semanticdb-javac/src/main/java/com/sourcegraph/semanticdb_javac/SemanticdbTypeVisitor.java b/semanticdb-javac/src/main/java/com/sourcegraph/semanticdb_javac/SemanticdbTypeVisitor.java index 0733dbbfd..c7c3e64d4 100644 --- a/semanticdb-javac/src/main/java/com/sourcegraph/semanticdb_javac/SemanticdbTypeVisitor.java +++ b/semanticdb-javac/src/main/java/com/sourcegraph/semanticdb_javac/SemanticdbTypeVisitor.java @@ -1,5 +1,7 @@ package com.sourcegraph.semanticdb_javac; +import com.sourcegraph.semanticdb.Semanticdb; + import javax.lang.model.element.Element; import javax.lang.model.util.SimpleTypeVisitor8; import javax.lang.model.type.TypeMirror; @@ -14,7 +16,7 @@ import javax.lang.model.util.Types; import java.util.ArrayList; -import static com.sourcegraph.semanticdb_javac.SemanticdbBuilders.*; +import static com.sourcegraph.semanticdb.SemanticdbBuilders.*; /** A TypeMirror tree visitor that constructs a recursive SemanticDB Type structure. */ class SemanticdbTypeVisitor extends SimpleTypeVisitor8 { diff --git a/semanticdb-javac/src/main/java/com/sourcegraph/semanticdb_javac/SemanticdbVisitor.java b/semanticdb-javac/src/main/java/com/sourcegraph/semanticdb_javac/SemanticdbVisitor.java index c99907116..cf2a20f70 100644 --- a/semanticdb-javac/src/main/java/com/sourcegraph/semanticdb_javac/SemanticdbVisitor.java +++ b/semanticdb-javac/src/main/java/com/sourcegraph/semanticdb_javac/SemanticdbVisitor.java @@ -1,5 +1,7 @@ package com.sourcegraph.semanticdb_javac; +import com.sourcegraph.semanticdb.Semanticdb; + import com.sourcegraph.semanticdb.SemanticdbSymbols; import com.sun.source.util.SourcePositions; @@ -35,9 +37,9 @@ import javax.lang.model.type.DeclaredType; import javax.lang.model.util.Types; import javax.lang.model.util.Elements; -import com.sourcegraph.semanticdb_javac.Semanticdb.SymbolInformation.Kind; -import com.sourcegraph.semanticdb_javac.Semanticdb.SymbolInformation.Property; -import com.sourcegraph.semanticdb_javac.Semanticdb.SymbolOccurrence.Role; +import com.sourcegraph.semanticdb.Semanticdb.SymbolInformation.Kind; +import com.sourcegraph.semanticdb.Semanticdb.SymbolInformation.Property; +import com.sourcegraph.semanticdb.Semanticdb.SymbolOccurrence.Role; import java.io.IOException; import java.nio.file.Path; @@ -53,7 +55,7 @@ import java.security.NoSuchAlgorithmException; import java.util.stream.Collectors; -import static com.sourcegraph.semanticdb_javac.SemanticdbBuilders.*; +import static com.sourcegraph.semanticdb.SemanticdbBuilders.*; /** Walks the AST of a typechecked compilation unit and generates a SemanticDB TextDocument. */ public class SemanticdbVisitor extends TreePathScanner { diff --git a/semanticdb-kotlinc/src/main/java/com/sourcegraph/semanticdb_kotlinc/SemanticdbBuilders.kt b/semanticdb-kotlinc/src/main/java/com/sourcegraph/semanticdb_kotlinc/SemanticdbBuilders.kt index 652ebe267..d1e85c809 100644 --- a/semanticdb-kotlinc/src/main/java/com/sourcegraph/semanticdb_kotlinc/SemanticdbBuilders.kt +++ b/semanticdb-kotlinc/src/main/java/com/sourcegraph/semanticdb_kotlinc/SemanticdbBuilders.kt @@ -3,6 +3,8 @@ package com.sourcegraph.semanticdb_kotlinc +import com.sourcegraph.semanticdb.Semanticdb + import kotlin.DslMarker import kotlin.Unit import kotlin.annotation.AnnotationRetention diff --git a/semanticdb-kotlinc/src/main/kotlin/com/sourcegraph/semanticdb_kotlinc/AnalyzerRegistrar.kt b/semanticdb-kotlinc/src/main/kotlin/com/sourcegraph/semanticdb_kotlinc/AnalyzerRegistrar.kt index 410dee517..212e64069 100644 --- a/semanticdb-kotlinc/src/main/kotlin/com/sourcegraph/semanticdb_kotlinc/AnalyzerRegistrar.kt +++ b/semanticdb-kotlinc/src/main/kotlin/com/sourcegraph/semanticdb_kotlinc/AnalyzerRegistrar.kt @@ -1,5 +1,7 @@ package com.sourcegraph.semanticdb_kotlinc +import com.sourcegraph.semanticdb.Semanticdb + import kotlin.contracts.ExperimentalContracts import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension import org.jetbrains.kotlin.compiler.plugin.CompilerPluginRegistrar diff --git a/semanticdb-kotlinc/src/main/kotlin/com/sourcegraph/semanticdb_kotlinc/PostAnalysisExtension.kt b/semanticdb-kotlinc/src/main/kotlin/com/sourcegraph/semanticdb_kotlinc/PostAnalysisExtension.kt index d002b7fbb..57526a2b9 100644 --- a/semanticdb-kotlinc/src/main/kotlin/com/sourcegraph/semanticdb_kotlinc/PostAnalysisExtension.kt +++ b/semanticdb-kotlinc/src/main/kotlin/com/sourcegraph/semanticdb_kotlinc/PostAnalysisExtension.kt @@ -1,5 +1,7 @@ package com.sourcegraph.semanticdb_kotlinc +import com.sourcegraph.semanticdb.Semanticdb + import java.io.PrintWriter import java.io.Writer import java.nio.file.Files diff --git a/semanticdb-kotlinc/src/main/kotlin/com/sourcegraph/semanticdb_kotlinc/SemanticdbTextDocumentBuilder.kt b/semanticdb-kotlinc/src/main/kotlin/com/sourcegraph/semanticdb_kotlinc/SemanticdbTextDocumentBuilder.kt index d37d5bee1..0584aafba 100644 --- a/semanticdb-kotlinc/src/main/kotlin/com/sourcegraph/semanticdb_kotlinc/SemanticdbTextDocumentBuilder.kt +++ b/semanticdb-kotlinc/src/main/kotlin/com/sourcegraph/semanticdb_kotlinc/SemanticdbTextDocumentBuilder.kt @@ -1,6 +1,8 @@ package com.sourcegraph.semanticdb_kotlinc -import com.sourcegraph.semanticdb_kotlinc.Semanticdb.SymbolOccurrence.Role +import com.sourcegraph.semanticdb.Semanticdb + +import com.sourcegraph.semanticdb.Semanticdb.SymbolOccurrence.Role import java.nio.file.Path import java.nio.file.Paths import java.security.MessageDigest diff --git a/semanticdb-kotlinc/src/main/kotlin/com/sourcegraph/semanticdb_kotlinc/SemanticdbVisitor.kt b/semanticdb-kotlinc/src/main/kotlin/com/sourcegraph/semanticdb_kotlinc/SemanticdbVisitor.kt index 2fa28c96f..268d2b480 100644 --- a/semanticdb-kotlinc/src/main/kotlin/com/sourcegraph/semanticdb_kotlinc/SemanticdbVisitor.kt +++ b/semanticdb-kotlinc/src/main/kotlin/com/sourcegraph/semanticdb_kotlinc/SemanticdbVisitor.kt @@ -1,6 +1,8 @@ package com.sourcegraph.semanticdb_kotlinc -import com.sourcegraph.semanticdb_kotlinc.Semanticdb.SymbolOccurrence.Role +import com.sourcegraph.semanticdb.Semanticdb + +import com.sourcegraph.semanticdb.Semanticdb.SymbolOccurrence.Role import java.nio.file.Path import kotlin.contracts.ExperimentalContracts import org.jetbrains.kotlin.KtSourceElement diff --git a/semanticdb-kotlinc/src/main/proto/com.sourcegraph.semanticdb_kotlin/semanticdb.proto b/semanticdb-kotlinc/src/main/proto/com.sourcegraph.semanticdb_kotlin/semanticdb.proto deleted file mode 100644 index f09cf9231..000000000 --- a/semanticdb-kotlinc/src/main/proto/com.sourcegraph.semanticdb_kotlin/semanticdb.proto +++ /dev/null @@ -1,192 +0,0 @@ -// Original source: https://github.com/scalameta/scalameta/blob/cf796cf2436b40494baf2bdc266623dc65264ad5/semanticdb/semanticdb/semanticdb.proto -// Local modifications: -// - Removes unused fields to minimize the amount of generated code. -// - Adds SymbolInformation.documentation that is pending upstream approval. -// - Adds SymbolOccurrence.enclosing_range to support SCIP's enclosing_range field. - -syntax = "proto3"; - -package com.sourcegraph.semanticdb_kotlinc; - -option java_package = "com.sourcegraph.semanticdb_kotlinc"; -option java_multiple_files = false; - -enum Schema { - LEGACY = 0; - SEMANTICDB3 = 3; - SEMANTICDB4 = 4; -} - -message TextDocuments { - repeated TextDocument documents = 1; -} - -message TextDocument { - reserved 4, 8, 9; - Schema schema = 1; - string uri = 2; - string text = 3; - string md5 = 11; - Language language = 10; - repeated SymbolInformation symbols = 5; - repeated SymbolOccurrence occurrences = 6; -} - -enum Language { - UNKNOWN_LANGUAGE = 0; - SCALA = 1; - JAVA = 2; - KOTLIN = 3; -} - -message Range { - int32 start_line = 1; - int32 start_character = 2; - int32 end_line = 3; - int32 end_character = 4; -} - -message Signature { - oneof sealed_value { - ClassSignature class_signature = 1; - MethodSignature method_signature = 2; - TypeSignature type_signature = 3; - ValueSignature value_signature = 4; - } -} - -message ClassSignature { - Scope type_parameters = 1; - repeated Type parents = 2; - Scope declarations = 4; -} - -message MethodSignature { - Scope type_parameters = 1; - repeated Scope parameter_lists = 2; - Type return_type = 3; -} - -message TypeSignature { - Scope type_parameters = 1; - Type lower_bound = 2; - Type upper_bound = 3; -} - -message ValueSignature { - Type tpe = 1; -} - -message SymbolInformation { - enum Kind { - reserved 1, 2, 4, 5, 15, 16; - UNKNOWN_KIND = 0; - LOCAL = 19; - FIELD = 20; - METHOD = 3; - CONSTRUCTOR = 21; - TYPE = 7; - PARAMETER = 8; - TYPE_PARAMETER = 9; - PACKAGE = 11; - CLASS = 13; - INTERFACE = 18; - } - enum Property { - UNKNOWN_PROPERTY = 0; - reserved 0x1; - reserved 0x2; - ABSTRACT = 0x4; - FINAL = 0x8; - SEALED = 0x10; - STATIC = 0x1000; - ENUM = 0x4000; - } - reserved 2, 6, 7, 8, 9, 10, 11, 12, 14, 15; - string symbol = 1; - Language language = 16; - Kind kind = 3; - int32 properties = 4; - string display_name = 5; - Signature signature = 17; - Access access = 18; - repeated string overridden_symbols = 19; - // NOTE: this field does not exist in the upstream SemanticDB spec. - // It is added to support documentation strings (e.g., KDoc). - Documentation documentation = 20; -} - -message Access { - oneof sealed_value { - PrivateAccess private_access = 1; - PrivateWithinAccess private_within_access = 3; - ProtectedAccess protected_access = 4; - PublicAccess public_access = 7; - } -} - -message PrivateAccess {} - -message PrivateWithinAccess { - string symbol = 1; -} - -message ProtectedAccess {} - -message PublicAccess {} - -message Documentation { - enum Format { - HTML = 0; - MARKDOWN = 1; - JAVADOC = 2; - SCALADOC = 3; - KDOC = 4; - } - string message = 1; - Format format = 2; -} - -message SymbolOccurrence { - enum Role { - UNKNOWN_ROLE = 0; - REFERENCE = 1; - DEFINITION = 2; - } - Range range = 1; - string symbol = 2; - Role role = 3; - // NOTE: this field does not exist in the upstream SemanticDB spec. - // It is added to support SCIP's enclosing_range field. - // This is the range of the nearest non-trivial enclosing AST node. - optional Range enclosing_range = 4; -} - -message Scope { - repeated string symlinks = 1; - repeated SymbolInformation hardlinks = 2; -} - -message Type { - reserved 1, 3, 4, 5, 6, 11, 12, 15, 16; - oneof sealed_value { - TypeRef type_ref = 2; - ExistentialType existential_type = 9; - IntersectionType intersection_type = 17; - } -} - -message TypeRef { - string symbol = 2; - repeated Type type_arguments = 3; -} - -message IntersectionType { - repeated Type types = 1; -} - -message ExistentialType { - reserved 2; - Type tpe = 1; - Scope declarations = 3; -} diff --git a/semanticdb-kotlinc/src/test/kotlin/com/sourcegraph/semanticdb_kotlinc/test/AnalyzerTest.kt b/semanticdb-kotlinc/src/test/kotlin/com/sourcegraph/semanticdb_kotlinc/test/AnalyzerTest.kt index 09724ed34..9ce6d24e6 100644 --- a/semanticdb-kotlinc/src/test/kotlin/com/sourcegraph/semanticdb_kotlinc/test/AnalyzerTest.kt +++ b/semanticdb-kotlinc/src/test/kotlin/com/sourcegraph/semanticdb_kotlinc/test/AnalyzerTest.kt @@ -1,9 +1,11 @@ package com.sourcegraph.semanticdb_kotlinc.test +import com.sourcegraph.semanticdb.Semanticdb + import com.sourcegraph.semanticdb_kotlinc.* -import com.sourcegraph.semanticdb_kotlinc.Semanticdb.Language.KOTLIN -import com.sourcegraph.semanticdb_kotlinc.Semanticdb.SymbolOccurrence.Role -import com.sourcegraph.semanticdb_kotlinc.Semanticdb.TextDocument +import com.sourcegraph.semanticdb.Semanticdb.Language.KOTLIN +import com.sourcegraph.semanticdb.Semanticdb.SymbolOccurrence.Role +import com.sourcegraph.semanticdb.Semanticdb.TextDocument import com.tschuchort.compiletesting.KotlinCompilation import com.tschuchort.compiletesting.PluginOption import com.tschuchort.compiletesting.SourceFile diff --git a/semanticdb-kotlinc/src/test/kotlin/com/sourcegraph/semanticdb_kotlinc/test/SemanticdbSymbolsTest.kt b/semanticdb-kotlinc/src/test/kotlin/com/sourcegraph/semanticdb_kotlinc/test/SemanticdbSymbolsTest.kt index d3cef3027..90f451dda 100644 --- a/semanticdb-kotlinc/src/test/kotlin/com/sourcegraph/semanticdb_kotlinc/test/SemanticdbSymbolsTest.kt +++ b/semanticdb-kotlinc/src/test/kotlin/com/sourcegraph/semanticdb_kotlinc/test/SemanticdbSymbolsTest.kt @@ -1,9 +1,11 @@ package com.sourcegraph.semanticdb_kotlinc.test +import com.sourcegraph.semanticdb.Semanticdb + import com.sourcegraph.semanticdb_kotlinc.* -import com.sourcegraph.semanticdb_kotlinc.Semanticdb.Documentation.Format -import com.sourcegraph.semanticdb_kotlinc.Semanticdb.Language -import com.sourcegraph.semanticdb_kotlinc.Semanticdb.SymbolOccurrence.Role +import com.sourcegraph.semanticdb.Semanticdb.Documentation.Format +import com.sourcegraph.semanticdb.Semanticdb.Language +import com.sourcegraph.semanticdb.Semanticdb.SymbolOccurrence.Role import com.sourcegraph.semanticdb_kotlinc.test.ExpectedSymbols.SemanticdbData import com.sourcegraph.semanticdb_kotlinc.test.ExpectedSymbols.SymbolCacheData import com.tschuchort.compiletesting.SourceFile diff --git a/semanticdb-kotlinc/src/test/kotlin/com/sourcegraph/semanticdb_kotlinc/test/Utils.kt b/semanticdb-kotlinc/src/test/kotlin/com/sourcegraph/semanticdb_kotlinc/test/Utils.kt index 77ffc63d2..f41bfd7d7 100644 --- a/semanticdb-kotlinc/src/test/kotlin/com/sourcegraph/semanticdb_kotlinc/test/Utils.kt +++ b/semanticdb-kotlinc/src/test/kotlin/com/sourcegraph/semanticdb_kotlinc/test/Utils.kt @@ -1,5 +1,7 @@ package com.sourcegraph.semanticdb_kotlinc.test +import com.sourcegraph.semanticdb.Semanticdb + import com.sourcegraph.semanticdb_kotlinc.* import com.sourcegraph.semanticdb_kotlinc.AnalyzerCheckers.Companion.visitors import com.tschuchort.compiletesting.KotlinCompilation diff --git a/semanticdb-shared/BUILD b/semanticdb-shared/BUILD index 2efbc3ea3..099906958 100644 --- a/semanticdb-shared/BUILD +++ b/semanticdb-shared/BUILD @@ -1,10 +1,24 @@ +load("@com_google_protobuf//bazel:java_proto_library.bzl", "java_proto_library") +load("@com_google_protobuf//bazel:proto_library.bzl", "proto_library") load("@rules_java//java:defs.bzl", "java_library") package( default_visibility = ["//visibility:public"], ) +proto_library( + name = "semanticdb_proto", + srcs = ["src/main/protobuf/semanticdb.proto"], +) + +java_proto_library( + name = "semanticdb_java_proto", + deps = [":semanticdb_proto"], +) + java_library( name = "semanticdb-shared", srcs = glob(["src/main/java/**/*.java"]), + exports = [":semanticdb_java_proto"], + deps = [":semanticdb_java_proto"], ) diff --git a/semanticdb-java/src/main/java/com/sourcegraph/semanticdb_javac/SemanticdbBuilders.java b/semanticdb-shared/src/main/java/com/sourcegraph/semanticdb/SemanticdbBuilders.java similarity index 99% rename from semanticdb-java/src/main/java/com/sourcegraph/semanticdb_javac/SemanticdbBuilders.java rename to semanticdb-shared/src/main/java/com/sourcegraph/semanticdb/SemanticdbBuilders.java index f91e7a9ed..2a238bbbf 100644 --- a/semanticdb-java/src/main/java/com/sourcegraph/semanticdb_javac/SemanticdbBuilders.java +++ b/semanticdb-shared/src/main/java/com/sourcegraph/semanticdb/SemanticdbBuilders.java @@ -1,4 +1,4 @@ -package com.sourcegraph.semanticdb_javac; +package com.sourcegraph.semanticdb; import java.util.List; diff --git a/semanticdb-java/src/main/protobuf/semanticdb.proto b/semanticdb-shared/src/main/protobuf/semanticdb.proto similarity index 97% rename from semanticdb-java/src/main/protobuf/semanticdb.proto rename to semanticdb-shared/src/main/protobuf/semanticdb.proto index a671f4689..bfc289c5e 100644 --- a/semanticdb-java/src/main/protobuf/semanticdb.proto +++ b/semanticdb-shared/src/main/protobuf/semanticdb.proto @@ -2,10 +2,15 @@ // Local modifications: // - Removes unused fields to minimize the amount of generated code. // - Adds SymbolInformation.documentation that is pending upstream approval. +// - Adds SymbolOccurrence.enclosing_range to support SCIP's enclosing_range field. syntax = "proto3"; -package com.sourcegraph.semanticdb_javac; +package com.sourcegraph.semanticdb; + +option java_package = "com.sourcegraph.semanticdb"; +option java_multiple_files = false; +option java_outer_classname = "Semanticdb"; enum Schema { LEGACY = 0; diff --git a/tests/snapshots/src/main/scala/tests/SemanticdbFile.scala b/tests/snapshots/src/main/scala/tests/SemanticdbFile.scala index 0ba4dbd9a..c73c4c919 100644 --- a/tests/snapshots/src/main/scala/tests/SemanticdbFile.scala +++ b/tests/snapshots/src/main/scala/tests/SemanticdbFile.scala @@ -6,8 +6,8 @@ import scala.meta.internal.io.FileIO import scala.meta.io.AbsolutePath import scala.meta.io.RelativePath -import com.sourcegraph.semanticdb_javac.Semanticdb.TextDocument -import com.sourcegraph.semanticdb_javac.Semanticdb.TextDocuments +import com.sourcegraph.semanticdb.Semanticdb.TextDocument +import com.sourcegraph.semanticdb.Semanticdb.TextDocuments case class SemanticdbFile( sourceroot: AbsolutePath, diff --git a/tests/unit/src/main/scala/tests/CompileResult.scala b/tests/unit/src/main/scala/tests/CompileResult.scala index 5c582337f..21e76f470 100644 --- a/tests/unit/src/main/scala/tests/CompileResult.scala +++ b/tests/unit/src/main/scala/tests/CompileResult.scala @@ -1,6 +1,6 @@ package tests -import com.sourcegraph.semanticdb_javac.Semanticdb +import com.sourcegraph.semanticdb.Semanticdb case class CompileResult( byteCode: Array[Byte], diff --git a/tests/unit/src/main/scala/tests/TestCompiler.scala b/tests/unit/src/main/scala/tests/TestCompiler.scala index 37c4e86b6..a4ea44db7 100644 --- a/tests/unit/src/main/scala/tests/TestCompiler.scala +++ b/tests/unit/src/main/scala/tests/TestCompiler.scala @@ -13,7 +13,7 @@ import scala.meta.Input import scala.meta.internal.io.FileIO import scala.meta.io.AbsolutePath -import com.sourcegraph.semanticdb_javac.Semanticdb +import com.sourcegraph.semanticdb.Semanticdb object TestCompiler { val PROCESSOR_PATH = System.getProperty("java.class.path") diff --git a/tests/unit/src/test/scala/tests/GeneratedConstructorSuite.scala b/tests/unit/src/test/scala/tests/GeneratedConstructorSuite.scala index 6862c7d56..d371838e5 100644 --- a/tests/unit/src/test/scala/tests/GeneratedConstructorSuite.scala +++ b/tests/unit/src/test/scala/tests/GeneratedConstructorSuite.scala @@ -2,7 +2,7 @@ package tests import scala.meta.inputs.Input -import com.sourcegraph.semanticdb_javac.Semanticdb.TextDocument +import com.sourcegraph.semanticdb.Semanticdb.TextDocument import munit.FunSuite import munit.TestOptions diff --git a/tests/unit/src/test/scala/tests/TargetedSuite.scala b/tests/unit/src/test/scala/tests/TargetedSuite.scala index 1fa200d51..284804738 100644 --- a/tests/unit/src/test/scala/tests/TargetedSuite.scala +++ b/tests/unit/src/test/scala/tests/TargetedSuite.scala @@ -7,8 +7,8 @@ import scala.meta.Input import scala.meta.Position import scala.meta.internal.inputs._ -import com.sourcegraph.semanticdb_javac.Semanticdb -import com.sourcegraph.semanticdb_javac.Semanticdb.TextDocument +import com.sourcegraph.semanticdb.Semanticdb +import com.sourcegraph.semanticdb.Semanticdb.TextDocument import munit.FunSuite import munit.TestOptions From f3922a3739286e7f976de99954fe682354bc30ff Mon Sep 17 00:00:00 2001 From: jupblb Date: Wed, 3 Jun 2026 16:13:35 +0200 Subject: [PATCH 3/5] Share MD5, path, and write helpers between Java/Kotlin plugins Extracts SemanticdbMd5, SemanticdbPaths and SemanticdbWriter into semanticdb-shared so the javac and kotlinc plugins stop duplicating the digest, output-path, URI, and single-document write logic. Side effect: semanticdb-kotlinc URIs are now joined with '/' regardless of platform, matching semanticdb-javac (and resolving the existing 'unix-style only' TODO in SemanticdbTextDocumentBuilder). --- .../com/sourcegraph/semanticdb_javac/MD5.java | 32 --------- .../SemanticdbTaskListener.java | 23 +++---- .../semanticdb_javac/SemanticdbVisitor.java | 21 ++---- .../PostAnalysisExtension.kt | 22 ++---- .../SemanticdbTextDocumentBuilder.kt | 14 ++-- .../sourcegraph/semanticdb/SemanticdbMd5.java | 46 +++++++++++++ .../semanticdb/SemanticdbPaths.java | 69 +++++++++++++++++++ .../semanticdb/SemanticdbWriter.java | 22 ++++++ 8 files changed, 162 insertions(+), 87 deletions(-) delete mode 100644 semanticdb-javac/src/main/java/com/sourcegraph/semanticdb_javac/MD5.java create mode 100644 semanticdb-shared/src/main/java/com/sourcegraph/semanticdb/SemanticdbMd5.java create mode 100644 semanticdb-shared/src/main/java/com/sourcegraph/semanticdb/SemanticdbPaths.java create mode 100644 semanticdb-shared/src/main/java/com/sourcegraph/semanticdb/SemanticdbWriter.java diff --git a/semanticdb-javac/src/main/java/com/sourcegraph/semanticdb_javac/MD5.java b/semanticdb-javac/src/main/java/com/sourcegraph/semanticdb_javac/MD5.java deleted file mode 100644 index 3d5be0659..000000000 --- a/semanticdb-javac/src/main/java/com/sourcegraph/semanticdb_javac/MD5.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.sourcegraph.semanticdb_javac; - -import java.nio.CharBuffer; -import java.nio.charset.StandardCharsets; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; - -/** Utility to compute MD5 checksums of strings. */ -public final class MD5 { - private static final char[] HEX_ARRAY; - - static { - HEX_ARRAY = "0123456789ABCDEF".toCharArray(); - } - - private static String bytesToHex(byte[] bytes) { - char[] hexChars = new char[bytes.length * 2]; - int j = 0; - while (j < bytes.length) { - int v = bytes[j] & 0xFF; - hexChars[j * 2] = HEX_ARRAY[v >>> 4]; - hexChars[j * 2 + 1] = HEX_ARRAY[v & 0x0F]; - j += 1; - } - return new String(hexChars); - } - - public static String digest(CharSequence chars) throws NoSuchAlgorithmException { - MessageDigest md5 = MessageDigest.getInstance("MD5"); - return bytesToHex(md5.digest(chars.toString().getBytes())); - } -} diff --git a/semanticdb-javac/src/main/java/com/sourcegraph/semanticdb_javac/SemanticdbTaskListener.java b/semanticdb-javac/src/main/java/com/sourcegraph/semanticdb_javac/SemanticdbTaskListener.java index 049b370f4..db7ae270c 100644 --- a/semanticdb-javac/src/main/java/com/sourcegraph/semanticdb_javac/SemanticdbTaskListener.java +++ b/semanticdb-javac/src/main/java/com/sourcegraph/semanticdb_javac/SemanticdbTaskListener.java @@ -1,6 +1,8 @@ package com.sourcegraph.semanticdb_javac; import com.sourcegraph.semanticdb.Semanticdb; +import com.sourcegraph.semanticdb.SemanticdbPaths; +import com.sourcegraph.semanticdb.SemanticdbWriter; import com.sun.source.util.JavacTask; import com.sun.source.util.TaskEvent; @@ -16,6 +18,7 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.util.HashSet; +import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; @@ -127,10 +130,7 @@ private void onFinishedAnalyze(TaskEvent e) { private void writeSemanticdb(TaskEvent event, Path output, Semanticdb.TextDocument textDocument) { try { - byte[] bytes = - Semanticdb.TextDocuments.newBuilder().addDocuments(textDocument).build().toByteArray(); - Files.createDirectories(output.getParent()); - Files.write(output, bytes); + SemanticdbWriter.writeTextDocument(output, textDocument); } catch (IOException e) { this.reportException(e, event); } @@ -280,17 +280,10 @@ private void inferBazelSourceroot(JavaFileObject file) { private Result semanticdbOutputPath(SemanticdbJavacOptions options, TaskEvent e) { Path absolutePath = absolutePathFromUri(options, e.getSourceFile()); - if (absolutePath.startsWith(options.sourceroot)) { - Path relativePath = options.sourceroot.relativize(absolutePath); - String filename = relativePath.getFileName().toString() + ".semanticdb"; - Path semanticdbOutputPath = - options - .targetroot - .resolve("META-INF") - .resolve("semanticdb") - .resolve(relativePath) - .resolveSibling(filename); - return Result.ok(semanticdbOutputPath); + Optional happyPath = + SemanticdbPaths.semanticdbPath(options.targetroot, options.sourceroot, absolutePath); + if (happyPath.isPresent()) { + return Result.ok(happyPath.get()); } switch (options.noRelativePath) { diff --git a/semanticdb-javac/src/main/java/com/sourcegraph/semanticdb_javac/SemanticdbVisitor.java b/semanticdb-javac/src/main/java/com/sourcegraph/semanticdb_javac/SemanticdbVisitor.java index cf2a20f70..356102091 100644 --- a/semanticdb-javac/src/main/java/com/sourcegraph/semanticdb_javac/SemanticdbVisitor.java +++ b/semanticdb-javac/src/main/java/com/sourcegraph/semanticdb_javac/SemanticdbVisitor.java @@ -2,6 +2,8 @@ import com.sourcegraph.semanticdb.Semanticdb; +import com.sourcegraph.semanticdb.SemanticdbMd5; +import com.sourcegraph.semanticdb.SemanticdbPaths; import com.sourcegraph.semanticdb.SemanticdbSymbols; import com.sun.source.util.SourcePositions; @@ -51,8 +53,6 @@ import java.util.Set; import java.util.Objects; import java.util.Optional; -import java.util.Iterator; -import java.security.NoSuchAlgorithmException; import java.util.stream.Collectors; import static com.sourcegraph.semanticdb.SemanticdbBuilders.*; @@ -560,8 +560,8 @@ private String semanticdbText() { private String semanticdbMd5() { try { - return MD5.digest(compUnitTree.getSourceFile().getCharContent(true).toString()); - } catch (IOException | NoSuchAlgorithmException e) { + return SemanticdbMd5.digest(compUnitTree.getSourceFile().getCharContent(true).toString()); + } catch (IOException e) { return ""; } } @@ -667,18 +667,7 @@ private static String semanticdbUri( CompilationUnitTree compUnitTree, SemanticdbJavacOptions options) { Path absolutePath = SemanticdbTaskListener.absolutePathFromUri(options, compUnitTree.getSourceFile()); - Path uriPath = - absolutePath.startsWith(options.sourceroot) - ? options.sourceroot.relativize(absolutePath) - : absolutePath; - StringBuilder out = new StringBuilder(); - Iterator it = uriPath.iterator(); - if (it.hasNext()) out.append(it.next().getFileName().toString()); - while (it.hasNext()) { - Path part = it.next(); - out.append('/').append(part.getFileName().toString()); - } - return out.toString(); + return SemanticdbPaths.semanticdbUri(options.sourceroot, absolutePath); } private Semanticdb.Documentation semanticdbDocumentation(Tree tree) { diff --git a/semanticdb-kotlinc/src/main/kotlin/com/sourcegraph/semanticdb_kotlinc/PostAnalysisExtension.kt b/semanticdb-kotlinc/src/main/kotlin/com/sourcegraph/semanticdb_kotlinc/PostAnalysisExtension.kt index 57526a2b9..fca98c91c 100644 --- a/semanticdb-kotlinc/src/main/kotlin/com/sourcegraph/semanticdb_kotlinc/PostAnalysisExtension.kt +++ b/semanticdb-kotlinc/src/main/kotlin/com/sourcegraph/semanticdb_kotlinc/PostAnalysisExtension.kt @@ -1,10 +1,11 @@ package com.sourcegraph.semanticdb_kotlinc import com.sourcegraph.semanticdb.Semanticdb +import com.sourcegraph.semanticdb.SemanticdbPaths +import com.sourcegraph.semanticdb.SemanticdbWriter import java.io.PrintWriter import java.io.Writer -import java.nio.file.Files import java.nio.file.Path import java.nio.file.Paths import kotlin.contracts.ExperimentalContracts @@ -29,8 +30,8 @@ class PostAnalysisExtension( for ((ktSourceFile, visitor) in AnalyzerCheckers.visitors) { try { val document = visitor.build() - semanticdbOutPathForFile(ktSourceFile)?.apply { - Files.write(this, TextDocuments { addDocuments(document) }.toByteArray()) + semanticdbOutPathForFile(ktSourceFile)?.let { outPath -> + SemanticdbWriter.writeTextDocument(outPath, document) } callback(document) } catch (e: Exception) { @@ -44,18 +45,9 @@ class PostAnalysisExtension( private fun semanticdbOutPathForFile(file: KtSourceFile): Path? { val normalizedPath = Paths.get(file.path).normalize() - if (normalizedPath.startsWith(sourceRoot)) { - val relative = sourceRoot.relativize(normalizedPath) - val filename = relative.fileName.toString() + ".semanticdb" - val semanticdbOutPath = - targetRoot - .resolve("META-INF") - .resolve("semanticdb") - .resolve(relative) - .resolveSibling(filename) - - Files.createDirectories(semanticdbOutPath.parent) - return semanticdbOutPath + val outPath = SemanticdbPaths.semanticdbPath(targetRoot, sourceRoot, normalizedPath) + if (outPath.isPresent) { + return outPath.get() } System.err.println( "given file is not under the sourceroot.\n\tSourceroot: $sourceRoot\n\tFile path: ${file.path}\n\tNormalized file path: $normalizedPath") diff --git a/semanticdb-kotlinc/src/main/kotlin/com/sourcegraph/semanticdb_kotlinc/SemanticdbTextDocumentBuilder.kt b/semanticdb-kotlinc/src/main/kotlin/com/sourcegraph/semanticdb_kotlinc/SemanticdbTextDocumentBuilder.kt index 0584aafba..56f7380d4 100644 --- a/semanticdb-kotlinc/src/main/kotlin/com/sourcegraph/semanticdb_kotlinc/SemanticdbTextDocumentBuilder.kt +++ b/semanticdb-kotlinc/src/main/kotlin/com/sourcegraph/semanticdb_kotlinc/SemanticdbTextDocumentBuilder.kt @@ -3,9 +3,10 @@ package com.sourcegraph.semanticdb_kotlinc import com.sourcegraph.semanticdb.Semanticdb import com.sourcegraph.semanticdb.Semanticdb.SymbolOccurrence.Role +import com.sourcegraph.semanticdb.SemanticdbMd5 +import com.sourcegraph.semanticdb.SemanticdbPaths import java.nio.file.Path import java.nio.file.Paths -import java.security.MessageDigest import kotlin.contracts.ExperimentalContracts import org.jetbrains.kotlin.KtSourceElement import org.jetbrains.kotlin.KtSourceFile @@ -147,16 +148,11 @@ class SemanticdbTextDocumentBuilder( } } - private fun semanticdbURI(): String { - // TODO: unix-style only - val relative = sourceroot.relativize(Paths.get(file.path)) - return relative.toString() - } + private fun semanticdbURI(): String = + SemanticdbPaths.semanticdbUri(sourceroot, Paths.get(file.path)) private fun semanticdbMD5(): String = - MessageDigest.getInstance("MD5") - .digest(file.getContentsAsStream().readBytes()) - .joinToString("") { "%02X".format(it) } + SemanticdbMd5.digest(file.getContentsAsStream().readBytes()) private fun semanticdbDocumentation(element: FirElement): Semanticdb.Documentation = Documentation { format = Semanticdb.Documentation.Format.MARKDOWN diff --git a/semanticdb-shared/src/main/java/com/sourcegraph/semanticdb/SemanticdbMd5.java b/semanticdb-shared/src/main/java/com/sourcegraph/semanticdb/SemanticdbMd5.java new file mode 100644 index 000000000..d703e7cd3 --- /dev/null +++ b/semanticdb-shared/src/main/java/com/sourcegraph/semanticdb/SemanticdbMd5.java @@ -0,0 +1,46 @@ +package com.sourcegraph.semanticdb; + +import java.nio.charset.StandardCharsets; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +/** + * Utility to compute uppercase-hex MD5 checksums for SemanticDB {@code TextDocument.md5} fields. + * + *

The uppercase-hex format is shared by every SemanticDB producer and matches the prior + * per-plugin implementations in {@code semanticdb-javac} and {@code semanticdb-kotlinc}. + */ +public final class SemanticdbMd5 { + private static final char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray(); + + private SemanticdbMd5() {} + + /** Computes the uppercase-hex MD5 digest of the given UTF-8 encoded text. */ + public static String digest(CharSequence text) { + return digest(text.toString().getBytes(StandardCharsets.UTF_8)); + } + + /** Computes the uppercase-hex MD5 digest of the given bytes. */ + public static String digest(byte[] bytes) { + return bytesToHex(newMd5().digest(bytes)); + } + + private static MessageDigest newMd5() { + try { + return MessageDigest.getInstance("MD5"); + } catch (NoSuchAlgorithmException e) { + // MD5 is a JDK-required algorithm and is always available. + throw new AssertionError("MD5 algorithm unavailable in this JVM", e); + } + } + + private static String bytesToHex(byte[] bytes) { + char[] hexChars = new char[bytes.length * 2]; + for (int j = 0; j < bytes.length; j++) { + int v = bytes[j] & 0xFF; + hexChars[j * 2] = HEX_ARRAY[v >>> 4]; + hexChars[j * 2 + 1] = HEX_ARRAY[v & 0x0F]; + } + return new String(hexChars); + } +} diff --git a/semanticdb-shared/src/main/java/com/sourcegraph/semanticdb/SemanticdbPaths.java b/semanticdb-shared/src/main/java/com/sourcegraph/semanticdb/SemanticdbPaths.java new file mode 100644 index 000000000..2181ca4d1 --- /dev/null +++ b/semanticdb-shared/src/main/java/com/sourcegraph/semanticdb/SemanticdbPaths.java @@ -0,0 +1,69 @@ +package com.sourcegraph.semanticdb; + +import java.nio.file.Path; +import java.util.Iterator; +import java.util.Optional; + +/** + * Shared helpers for the canonical SemanticDB output-path and URI layout. + * + *

Every SemanticDB producer writes payloads under {@code + * /META-INF/semanticdb/.semanticdb} and labels documents with a + * unix-style {@code } URI. Both {@code semanticdb-javac} and {@code + * semanticdb-kotlinc} converged on the same layout, so the policy lives here. + * + *

Plugin-specific behavior for files that are not under the sourceroot (e.g. javac's + * {@code NoRelativePathMode} fallbacks or kotlinc's "skip with warning") stays in the plugins; this + * class only covers the in-sourceroot happy path. + */ +public final class SemanticdbPaths { + /** Subdirectory of the target root that holds the generated {@code .semanticdb} payloads. */ + public static final String SEMANTICDB_ROOT = "META-INF/semanticdb"; + + private SemanticdbPaths() {} + + /** + * Returns the on-disk {@code .semanticdb} payload path for an absolute source file under {@code + * sourceRoot}, or {@link Optional#empty()} when the source file is not under {@code sourceRoot}. + */ + public static Optional semanticdbPath( + Path targetRoot, Path sourceRoot, Path absoluteSourcePath) { + if (!absoluteSourcePath.startsWith(sourceRoot)) { + return Optional.empty(); + } + Path relative = sourceRoot.relativize(absoluteSourcePath); + return Optional.of(semanticdbPathForRelativeSource(targetRoot, relative)); + } + + /** + * Returns the on-disk {@code .semanticdb} payload path for a source file expressed as a path + * relative to the source root. + */ + public static Path semanticdbPathForRelativeSource(Path targetRoot, Path relativeSourcePath) { + String filename = relativeSourcePath.getFileName().toString() + ".semanticdb"; + return targetRoot + .resolve("META-INF") + .resolve("semanticdb") + .resolve(relativeSourcePath) + .resolveSibling(filename); + } + + /** + * Returns the unix-style {@code TextDocument.uri} for the given absolute source file. When the + * file lives under {@code sourceRoot}, the URI is the source-root-relative path; otherwise it is + * the file's absolute path. Both cases are joined with {@code '/'} regardless of platform. + */ + public static String semanticdbUri(Path sourceRoot, Path absoluteSourcePath) { + Path uriPath = + absoluteSourcePath.startsWith(sourceRoot) + ? sourceRoot.relativize(absoluteSourcePath) + : absoluteSourcePath; + StringBuilder out = new StringBuilder(); + Iterator it = uriPath.iterator(); + if (it.hasNext()) out.append(it.next().getFileName().toString()); + while (it.hasNext()) { + out.append('/').append(it.next().getFileName().toString()); + } + return out.toString(); + } +} diff --git a/semanticdb-shared/src/main/java/com/sourcegraph/semanticdb/SemanticdbWriter.java b/semanticdb-shared/src/main/java/com/sourcegraph/semanticdb/SemanticdbWriter.java new file mode 100644 index 000000000..691252695 --- /dev/null +++ b/semanticdb-shared/src/main/java/com/sourcegraph/semanticdb/SemanticdbWriter.java @@ -0,0 +1,22 @@ +package com.sourcegraph.semanticdb; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; + +/** Shared helper for serializing a single SemanticDB {@link Semanticdb.TextDocument} to disk. */ +public final class SemanticdbWriter { + private SemanticdbWriter() {} + + /** + * Wraps {@code document} in a singleton {@link Semanticdb.TextDocuments} message and writes it to + * {@code output}, creating parent directories as needed. + */ + public static void writeTextDocument(Path output, Semanticdb.TextDocument document) + throws IOException { + byte[] bytes = + Semanticdb.TextDocuments.newBuilder().addDocuments(document).build().toByteArray(); + Files.createDirectories(output.getParent()); + Files.write(output, bytes); + } +} From b029082f28535c2029ad25145a1ad741fc42d1de Mon Sep 17 00:00:00 2001 From: jupblb Date: Wed, 3 Jun 2026 16:17:11 +0200 Subject: [PATCH 4/5] Reformat build.sbt --- build.sbt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/build.sbt b/build.sbt index d4c56a8f0..973e22502 100644 --- a/build.sbt +++ b/build.sbt @@ -83,8 +83,7 @@ lazy val semanticdbShared = project javaOnlySettings, (Compile / PB.targets) := Seq(PB.gens.java(V.protobuf) -> (Compile / sourceManaged).value), - libraryDependencies += - "com.google.protobuf" % "protobuf-java" % V.protobuf + libraryDependencies += "com.google.protobuf" % "protobuf-java" % V.protobuf ) lazy val agent = project From 6092214ad32542f40424f5ce7c8ba71fa92a5736 Mon Sep 17 00:00:00 2001 From: jupblb Date: Wed, 3 Jun 2026 17:15:58 +0200 Subject: [PATCH 5/5] Inline MD5 instead of using a SemanticdbMd5 helper MessageDigest is stdlib, and each plugin can express its own hex conversion idiomatically (Kotlin one-liner via joinToString, small Java loop). The helper added no real value beyond hiding 3 lines. --- .../semanticdb_javac/SemanticdbVisitor.java | 17 +++++-- .../SemanticdbTextDocumentBuilder.kt | 6 ++- .../sourcegraph/semanticdb/SemanticdbMd5.java | 46 ------------------- 3 files changed, 18 insertions(+), 51 deletions(-) delete mode 100644 semanticdb-shared/src/main/java/com/sourcegraph/semanticdb/SemanticdbMd5.java diff --git a/semanticdb-javac/src/main/java/com/sourcegraph/semanticdb_javac/SemanticdbVisitor.java b/semanticdb-javac/src/main/java/com/sourcegraph/semanticdb_javac/SemanticdbVisitor.java index 356102091..bc0f233a6 100644 --- a/semanticdb-javac/src/main/java/com/sourcegraph/semanticdb_javac/SemanticdbVisitor.java +++ b/semanticdb-javac/src/main/java/com/sourcegraph/semanticdb_javac/SemanticdbVisitor.java @@ -2,7 +2,6 @@ import com.sourcegraph.semanticdb.Semanticdb; -import com.sourcegraph.semanticdb.SemanticdbMd5; import com.sourcegraph.semanticdb.SemanticdbPaths; import com.sourcegraph.semanticdb.SemanticdbSymbols; @@ -44,7 +43,10 @@ import com.sourcegraph.semanticdb.Semanticdb.SymbolOccurrence.Role; import java.io.IOException; +import java.nio.charset.StandardCharsets; import java.nio.file.Path; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; import java.util.List; import java.util.ArrayList; import java.util.LinkedHashMap; @@ -560,8 +562,17 @@ private String semanticdbText() { private String semanticdbMd5() { try { - return SemanticdbMd5.digest(compUnitTree.getSourceFile().getCharContent(true).toString()); - } catch (IOException e) { + byte[] bytes = + compUnitTree + .getSourceFile() + .getCharContent(true) + .toString() + .getBytes(StandardCharsets.UTF_8); + byte[] digest = MessageDigest.getInstance("MD5").digest(bytes); + StringBuilder sb = new StringBuilder(digest.length * 2); + for (byte b : digest) sb.append(String.format("%02X", b)); + return sb.toString(); + } catch (IOException | NoSuchAlgorithmException e) { return ""; } } diff --git a/semanticdb-kotlinc/src/main/kotlin/com/sourcegraph/semanticdb_kotlinc/SemanticdbTextDocumentBuilder.kt b/semanticdb-kotlinc/src/main/kotlin/com/sourcegraph/semanticdb_kotlinc/SemanticdbTextDocumentBuilder.kt index 56f7380d4..062193221 100644 --- a/semanticdb-kotlinc/src/main/kotlin/com/sourcegraph/semanticdb_kotlinc/SemanticdbTextDocumentBuilder.kt +++ b/semanticdb-kotlinc/src/main/kotlin/com/sourcegraph/semanticdb_kotlinc/SemanticdbTextDocumentBuilder.kt @@ -3,10 +3,10 @@ package com.sourcegraph.semanticdb_kotlinc import com.sourcegraph.semanticdb.Semanticdb import com.sourcegraph.semanticdb.Semanticdb.SymbolOccurrence.Role -import com.sourcegraph.semanticdb.SemanticdbMd5 import com.sourcegraph.semanticdb.SemanticdbPaths import java.nio.file.Path import java.nio.file.Paths +import java.security.MessageDigest import kotlin.contracts.ExperimentalContracts import org.jetbrains.kotlin.KtSourceElement import org.jetbrains.kotlin.KtSourceFile @@ -152,7 +152,9 @@ class SemanticdbTextDocumentBuilder( SemanticdbPaths.semanticdbUri(sourceroot, Paths.get(file.path)) private fun semanticdbMD5(): String = - SemanticdbMd5.digest(file.getContentsAsStream().readBytes()) + MessageDigest.getInstance("MD5") + .digest(file.getContentsAsStream().readBytes()) + .joinToString("") { "%02X".format(it) } private fun semanticdbDocumentation(element: FirElement): Semanticdb.Documentation = Documentation { format = Semanticdb.Documentation.Format.MARKDOWN diff --git a/semanticdb-shared/src/main/java/com/sourcegraph/semanticdb/SemanticdbMd5.java b/semanticdb-shared/src/main/java/com/sourcegraph/semanticdb/SemanticdbMd5.java deleted file mode 100644 index d703e7cd3..000000000 --- a/semanticdb-shared/src/main/java/com/sourcegraph/semanticdb/SemanticdbMd5.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.sourcegraph.semanticdb; - -import java.nio.charset.StandardCharsets; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; - -/** - * Utility to compute uppercase-hex MD5 checksums for SemanticDB {@code TextDocument.md5} fields. - * - *

The uppercase-hex format is shared by every SemanticDB producer and matches the prior - * per-plugin implementations in {@code semanticdb-javac} and {@code semanticdb-kotlinc}. - */ -public final class SemanticdbMd5 { - private static final char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray(); - - private SemanticdbMd5() {} - - /** Computes the uppercase-hex MD5 digest of the given UTF-8 encoded text. */ - public static String digest(CharSequence text) { - return digest(text.toString().getBytes(StandardCharsets.UTF_8)); - } - - /** Computes the uppercase-hex MD5 digest of the given bytes. */ - public static String digest(byte[] bytes) { - return bytesToHex(newMd5().digest(bytes)); - } - - private static MessageDigest newMd5() { - try { - return MessageDigest.getInstance("MD5"); - } catch (NoSuchAlgorithmException e) { - // MD5 is a JDK-required algorithm and is always available. - throw new AssertionError("MD5 algorithm unavailable in this JVM", e); - } - } - - private static String bytesToHex(byte[] bytes) { - char[] hexChars = new char[bytes.length * 2]; - for (int j = 0; j < bytes.length; j++) { - int v = bytes[j] & 0xFF; - hexChars[j * 2] = HEX_ARRAY[v >>> 4]; - hexChars[j * 2 + 1] = HEX_ARRAY[v & 0x0F]; - } - return new String(hexChars); - } -}