diff --git a/bin/packagehub.sh b/bin/packagehub.sh deleted file mode 100755 index 4da72d50d..000000000 --- a/bin/packagehub.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/usr/bin/env bash -/packagehub --host 0.0.0.0 --port "$PORT" --src /src --coursier /coursier --postgres.username="$DB_USER" --postgres.password="$DB_PASS" --postgres.url="$DB_URL" diff --git a/build.sbt b/build.sbt index 973e22502..c889c9ecb 100644 --- a/build.sbt +++ b/build.sbt @@ -15,7 +15,6 @@ lazy val V = val gradle = "7.0" val scala213 = "2.13.13" val scalameta = "4.9.3" - val requests = "0.8.0" val kotlinVersion = "2.2.0" val kotest = "4.6.3" val kctfork = "0.7.1" @@ -86,25 +85,6 @@ lazy val semanticdbShared = project libraryDependencies += "com.google.protobuf" % "protobuf-java" % V.protobuf ) -lazy val agent = project - .in(file("semanticdb-agent")) - .settings( - fatjarPackageSettings, - javaOnlySettings, - moduleName := "semanticdb-agent", - libraryDependencies ++= - List( - "net.bytebuddy" % "byte-buddy" % "1.15.11", - "net.bytebuddy" % "byte-buddy-agent" % "1.15.11" - ), - Compile / packageBin / packageOptions += - Package.ManifestAttributes( - "Agent-Class" -> "com.sourcegraph.semanticdb_javac.SemanticdbAgent", - "Can-Redefine-Classes" -> "true", - "Can-Retransform-Classes" -> "true", - "Premain-Class" -> "com.sourcegraph.semanticdb_javac.SemanticdbAgent" - ) - ) lazy val gradlePlugin = project .in(file("semanticdb-gradle-plugin")) .settings( @@ -155,10 +135,6 @@ lazy val javacPlugin = project // referenced from META-INF/services/com.sun.source.util.Plugin "com.sourcegraph.semanticdb_javac.SemanticdbPlugin" -> "com.sourcegraph.semanticdb_javac.SemanticdbPlugin", - // Don't rename PrintJavaVersion because we load it via FQN to - // detect the Java of a JVM installation. - "com.sourcegraph.semanticdb_javac.PrintJavaVersion" -> - "com.sourcegraph.semanticdb_javac.PrintJavaVersion", // Don't rename InjectSemanticdbOptions because we load it via FQN to // process a list of Java compiler options. "com.sourcegraph.semanticdb_javac.InjectSemanticdbOptions" -> @@ -243,7 +219,6 @@ lazy val cli = project libraryDependencies ++= List( "org.scala-lang.modules" %% "scala-xml" % V.scalaXml, - "com.lihaoyi" %% "requests" % V.requests, "org.scalameta" %% "moped" % V.moped, "org.jetbrains.kotlin" % "kotlin-compiler-embeddable" % V.kotlinVersion, "org.jetbrains.kotlin" % "kotlin-scripting-common" % V.kotlinVersion, @@ -267,10 +242,6 @@ lazy val cli = project (javacPlugin / Compile / Keys.`package`).value, "semanticdb-plugin.jar" ) - addJar( - (agent / Compile / Keys.`package`).value, - "semanticdb-agent.jar" - ) addJar((gradlePlugin / Compile / assembly).value, "gradle-plugin.jar") addJar( (semanticdbKotlinc / Compile / Keys.`package`).value, @@ -532,16 +503,6 @@ lazy val semanticdbKotlincMinimized = project .value ) -commands += - Command.command("nativeImageProfiled") { s => - val targetroot = - file("tests/minimized/.j11/target/scala-2.13/meta").absolutePath - val output = Files.createTempFile("scip-java", "index.scip") - "minimized/compile" :: - s"""nativeImageRunAgent " index-semanticdb --output=$output $targetroot"""" :: - "nativeImage" :: s - } - def minimizedSourceDirectory = file("tests/minimized/src/main/java").getAbsoluteFile @@ -577,7 +538,7 @@ lazy val minimizedSettings = List[Def.Setting[_]]( lazy val minimized = project .in(file("tests/minimized/.j11")) .settings(minimizedSettings, javaOnlySettings) - .dependsOn(agent, javacPlugin) + .dependsOn(javacPlugin) .disablePlugins(JavaFormatterPlugin) def javacModuleOptions = List( @@ -617,15 +578,6 @@ lazy val buildTools = project .in(file("tests/buildTools")) .settings( testSettings, - (Test / javaOptions) ++= - List( - s"-javaagent:${(agent / Compile / Keys.`package`).value}", - s"-Dsemanticdb.pluginpath=${(javacPlugin / Compile / Keys.`package`) - .value}", - s"-Dsemanticdb.sourceroot=${(ThisBuild / baseDirectory).value}", - s"-Dsemanticdb.targetroot=${(agent / Compile / target).value / - "semanticdb-targetroot"}" - ), Test / envVars ++= Map( "SCIP_JAVA_CLI" -> ((cli / pack).value / "bin" / "scip-java").toString @@ -635,7 +587,7 @@ lazy val buildTools = project // everything worse Test / testForkedParallel := !sys.env.contains("CI") ) - .dependsOn(agent, unit) + .dependsOn(unit) lazy val snapshots = project .in(file("tests/snapshots")) diff --git a/scip-java/src/main/scala/com/sourcegraph/scip_java/Embedded.scala b/scip-java/src/main/scala/com/sourcegraph/scip_java/Embedded.scala index 2be327dad..9b8b931ae 100644 --- a/scip-java/src/main/scala/com/sourcegraph/scip_java/Embedded.scala +++ b/scip-java/src/main/scala/com/sourcegraph/scip_java/Embedded.scala @@ -21,8 +21,6 @@ object Embedded { "gradle-plugin.jar" ) - def agentJar(tmpDir: Path): Path = copyFile(tmpDir, "semanticdb-agent.jar") - def semanticdbKotlincJar(tmpDir: Path): Path = copyFile( tmpDir, "semanticdb-kotlinc.jar" @@ -30,12 +28,7 @@ object Embedded { private def javacErrorpath(tmp: Path) = tmp.resolve("errorpath.txt") - def customJavac( - sourceroot: Path, - targetroot: Path, - tmp: Path, - javaAtLeast17: Boolean - ): Path = { + def customJavac(sourceroot: Path, targetroot: Path, tmp: Path): Path = { val bin = tmp.resolve("bin") val javac = bin.resolve("javac") val java = bin.resolve("java") @@ -51,11 +44,9 @@ object Embedded { |""".stripMargin.getBytes(StandardCharsets.UTF_8) ) val newJavacopts = tmp.resolve("javac_newarguments") - val javacModuleOptions = - if (javaAtLeast17) - BuildInfo.javacModuleOptions.mkString(" ") - else - "" + // --add-exports flags required to access internal javac APIs from our + // SemanticDB plugin. Always set; Java 11+ is the supported baseline. + val javacModuleOptions = BuildInfo.javacModuleOptions.mkString(" ") val injectSemanticdbArguments = List[String]( "java", s"-Dsemanticdb.errorpath=$errorpath", diff --git a/scip-java/src/main/scala/com/sourcegraph/scip_java/ScipPrinters.scala b/scip-java/src/main/scala/com/sourcegraph/scip_java/ScipPrinters.scala index 2916a7948..7bd8b3112 100644 --- a/scip-java/src/main/scala/com/sourcegraph/scip_java/ScipPrinters.scala +++ b/scip-java/src/main/scala/com/sourcegraph/scip_java/ScipPrinters.scala @@ -4,7 +4,6 @@ import scala.collection.mutable import scala.jdk.CollectionConverters.CollectionHasAsScala import scala.math.Ordering.Implicits.seqOrdering -import com.sourcegraph.scip_java.commands.CommentSyntax import moped.reporters.Input import moped.reporters.Position import org.scip_code.scip.Document @@ -20,11 +19,10 @@ object ScipPrinters { */ val sourceIndent = " " - def printTextDocument( - doc: Document, - text: String, - comments: CommentSyntax = CommentSyntax.default - ): String = { + // scip-java only indexes Java and Kotlin sources, both of which use `//`. + private val commentSyntax = "//" + + def printTextDocument(doc: Document, text: String): String = { val out = new mutable.StringBuilder() val occurrencesByLine = doc .getOccurrencesList @@ -56,8 +54,6 @@ object ScipPrinters { } ) .toMap - val extension = doc.getRelativePath.split("\\.").lastOption.getOrElse("") - val commentSyntax = comments.extensionSyntax(extension) val input = Input.filename(doc.getRelativePath, text) // Collect enclosing ranges from all occurrences, grouped by start/end line. @@ -118,7 +114,7 @@ object ScipPrinters { (o.getRangeList.asScala.toList.map(_.toInt), o.getSymbol) ) occurrences.foreach { occ => - formatOccurrence(input, out, occ, line, symtab, commentSyntax) + formatOccurrence(input, out, occ, line, symtab) if ((occ.getSymbolRoles & SymbolRole.Definition_VALUE) > 0) { syntheticDefinitions .getOrElse(occ.getSymbol, Nil) @@ -129,7 +125,6 @@ object ScipPrinters { occ, line, symtab, - commentSyntax, syntheticDefinition = Some(syntheticDefinition) ) } @@ -177,7 +172,6 @@ object ScipPrinters { occ: Occurrence, line: String, symtab: Map[String, SymbolInformation], - comment: String, syntheticDefinition: Option[SymbolInformation] = None ): Unit = { val pos = mopedPosition(input, occ) @@ -199,8 +193,8 @@ object ScipPrinters { else "reference" val indent = - if (pos.startColumn + sourceIndent.length > comment.length) - " " * (pos.startColumn + sourceIndent.length - comment.length) + if (pos.startColumn + sourceIndent.length > commentSyntax.length) + " " * (pos.startColumn + sourceIndent.length - commentSyntax.length) else "" val caretCharacter = @@ -220,7 +214,7 @@ object ScipPrinters { val _ = ScipSymbol.parseOrThrowExceptionIfInvalid(symbol) out - .append(comment) + .append(commentSyntax) .append(indent) .append(carets) .append(" ") @@ -235,7 +229,7 @@ object ScipPrinters { syntheticDefinition.orElse(symtab.get(occ.getSymbol)) match { case Some(info) if isDefinition => val prefix = - comment + (" " * indent.length) + (" " * carets.length) + " " + commentSyntax + (" " * indent.length) + (" " * carets.length) + " " if (!info.getDisplayName.isEmpty) { out .append(prefix) diff --git a/scip-java/src/main/scala/com/sourcegraph/scip_java/buildtools/BuildTool.scala b/scip-java/src/main/scala/com/sourcegraph/scip_java/buildtools/BuildTool.scala index 15eb9c649..00a29a981 100644 --- a/scip-java/src/main/scala/com/sourcegraph/scip_java/buildtools/BuildTool.scala +++ b/scip-java/src/main/scala/com/sourcegraph/scip_java/buildtools/BuildTool.scala @@ -57,7 +57,6 @@ object BuildTool { .copy( output = index.finalOutput, targetroot = List(targetroot), - packagehub = index.packagehub, app = index.app ) .run() diff --git a/scip-java/src/main/scala/com/sourcegraph/scip_java/buildtools/ClasspathEntry.scala b/scip-java/src/main/scala/com/sourcegraph/scip_java/buildtools/ClasspathEntry.scala index 2abd3f065..1fa1739de 100644 --- a/scip-java/src/main/scala/com/sourcegraph/scip_java/buildtools/ClasspathEntry.scala +++ b/scip-java/src/main/scala/com/sourcegraph/scip_java/buildtools/ClasspathEntry.scala @@ -23,7 +23,7 @@ case class ClasspathEntry( artifactId: String, version: String ) { - def toPackageHubId: String = s"maven:$groupId:$artifactId:$version" + def mavenCoordinate: String = s"maven:$groupId:$artifactId:$version" def toPackageInformation: MavenPackage = new MavenPackage(entry, groupId, artifactId, version) } diff --git a/scip-java/src/main/scala/com/sourcegraph/scip_java/buildtools/GradleBuildTool.scala b/scip-java/src/main/scala/com/sourcegraph/scip_java/buildtools/GradleBuildTool.scala index 84f5dcfb9..b72a2bd87 100644 --- a/scip-java/src/main/scala/com/sourcegraph/scip_java/buildtools/GradleBuildTool.scala +++ b/scip-java/src/main/scala/com/sourcegraph/scip_java/buildtools/GradleBuildTool.scala @@ -5,6 +5,7 @@ import java.nio.file._ import scala.collection.mutable.ListBuffer import scala.util.Properties +import scala.util.Try import com.sourcegraph.io.DeleteVisitor import com.sourcegraph.scip_java.Embedded @@ -26,13 +27,60 @@ class GradleBuildTool(index: IndexCommand) extends BuildTool("Gradle", index) { } override def generateScip(): Int = { - BuildTool.generateScipFromTargetroot( - generateSemanticdb(), - targetroot, - index - ) + val gradleResult = generateSemanticdb() + if (gradleResult.exitCode == 0) { + reportMissingSemanticdbOutput() + } + BuildTool.generateScipFromTargetroot(gradleResult, targetroot, index) + } + + /** + * Diagnose the case where Gradle finished successfully but our SemanticDB + * compiler plugin never produced any `.semanticdb` files. This used to be + * silently rescued by a `-javaagent` fallback; now it surfaces as a clear + * error pointing at the two known causes. + */ + private def reportMissingSemanticdbOutput(): Unit = { + if (containsFileWithSuffix(targetroot, ".semanticdb")) + return + if (!containsFileWithSuffix(index.workingDirectory, ".class")) + // Project produced no compiled JVM output — nothing to index, stay quiet. + return + index + .app + .reporter + .error( + s"""scip-java: Gradle finished successfully but produced no SemanticDB output in $targetroot. + | + |This means our SemanticDB compiler plugin was not attached to one or more JavaCompile tasks. Two known causes: + | + | 1. The 'compileOnly' configuration was already resolved before our init script ran. + | Check the Gradle output above for warnings of the form: + | "scip-java: failed to attach SemanticDB compiler plugin to project ''" + | Workaround: apply the SemanticDB plugin earlier (e.g. via a settings plugin), + | or restructure the build so that 'compileOnly' is not resolved at evaluation time. + | + | 2. Another Gradle plugin is replacing the compiler arguments we add (rather than appending). + | Verify with: ./gradlew compileJava --info | grep -- '-Xplugin:semanticdb' + | If '-Xplugin:semanticdb' is missing from the printed javac command, another plugin + | is overwriting JavaCompile.options.compilerArgs. + |""".stripMargin + ) } + private def containsFileWithSuffix(root: Path, suffix: String): Boolean = + Files.isDirectory(root) && + Try { + val stream = Files.find( + root, + Integer.MAX_VALUE, + (p, attrs) => + attrs.isRegularFile && p.getFileName.toString.endsWith(suffix) + ) + try stream.findFirst().isPresent + finally stream.close() + }.getOrElse(false) + def targetroot: Path = index.finalTargetroot(defaultTargetroot) private def defaultTargetroot: Path = Paths.get( @@ -62,7 +110,6 @@ class GradleBuildTool(index: IndexCommand) extends BuildTool("Gradle", index) { } private def runCompileCommand( - // toolchains: GradleJavaToolchains, tmp: Path, gradleCommand: String ): CommandResult = { @@ -81,7 +128,6 @@ class GradleBuildTool(index: IndexCommand) extends BuildTool("Gradle", index) { Files.walkFileTree(targetroot, new DeleteVisitor()) val result = index.process(buildCommand, env = Map("TERM" -> "dumb")) - printDebugLogs(tmp) Embedded .reportUnexpectedJavacErrors(index.app.reporter, tmp) .getOrElse(result) @@ -89,19 +135,7 @@ class GradleBuildTool(index: IndexCommand) extends BuildTool("Gradle", index) { private def scipJavaDependencies = "scipJavaDependencies" - private def printDebugLogs(tmp: Path): Unit = { - val path = GradleJavaCompiler.debugPath(tmp) - if (index.verbose && Files.isRegularFile(path)) { - Files - .readAllLines(path) - .forEach { line => - index.app.info(line) - } - } - } - private def initScript(tmp: Path): Path = { - val agentpath = Embedded.agentJar(tmp) val pluginpath = Embedded.semanticdbJar(tmp) val gradlePluginPath = Embedded.gradlePluginJar(tmp) val semanticdbKotlincPath = Embedded.semanticdbKotlincJar(tmp) @@ -122,7 +156,6 @@ class GradleBuildTool(index: IndexCommand) extends BuildTool("Gradle", index) { | project.ext["semanticdbTarget"] = "$targetroot" | project.ext["javacPluginJar"] = "$pluginpath" | project.ext["dependenciesOut"] = "$dependenciesPath" - | project.ext["javacAgentPath"] = "$agentpath" | project.ext["semanticdbKotlincJar"] = "$semanticdbKotlincPath" | apply plugin: SemanticdbGradlePlugin | } diff --git a/scip-java/src/main/scala/com/sourcegraph/scip_java/buildtools/GradleJavaCompiler.scala b/scip-java/src/main/scala/com/sourcegraph/scip_java/buildtools/GradleJavaCompiler.scala deleted file mode 100644 index 135a65652..000000000 --- a/scip-java/src/main/scala/com/sourcegraph/scip_java/buildtools/GradleJavaCompiler.scala +++ /dev/null @@ -1,157 +0,0 @@ -package com.sourcegraph.scip_java.buildtools - -import java.nio.charset.StandardCharsets -import java.nio.file.Files -import java.nio.file.NoSuchFileException -import java.nio.file.Path -import java.nio.file.Paths -import java.nio.file.StandardCopyOption - -import scala.collection.mutable.ListBuffer - -import com.sourcegraph.scip_java.Embedded -import com.sourcegraph.scip_java.commands.IndexCommand - -/** - * Metadata about the Java compiler that is used by a Gradle build. - * - * @see - * https://docs.gradle.org/current/javadoc/org/gradle/jvm/toolchain/JavaCompiler.html - */ -case class GradleJavaCompiler(languageVersion: String, javacPath: Path) { - - def createForwardingToolchain( - index: IndexCommand, - tmp: Path, - targetroot: Path, - pluginPath: Path - ): Path = { - val home = tmp.resolve(s"1.$languageVersion") - val javac = Embedded.customJavac( - index.workingDirectory, - targetroot, - tmp, - GradleJavaToolchains.isJavaAtLeast(languageVersion, "17") - ) - val agent = Embedded.agentJar(tmp) - val debugPath = GradleJavaCompiler.debugPath(tmp) - val javacopts = targetroot.resolve("javacopts.txt") - Files.createDirectories(javacopts.getParent) - - createBinaries( - dir = home, - javac = javac, - agent = agent, - index = index, - javacopts = javacopts, - targetroot = targetroot, - pluginPath = pluginPath, - debugPath = debugPath - ) - createBinaries( - dir = home.resolve("Contents").resolve("Home"), - javac = javac, - agent = agent, - index = index, - javacopts = javacopts, - targetroot = targetroot, - pluginPath = pluginPath, - debugPath = debugPath - ) // for macOS - home - } - - private def createBinaries( - dir: Path, - javac: Path, - agent: Path, - index: IndexCommand, - javacopts: Path, - targetroot: Path, - pluginPath: Path, - debugPath: Path - ): Unit = { - Files.createDirectories(dir.resolve("bin")) - val javaBinary = javacPath.resolveSibling("java") - val javaCommand = ListBuffer[String]( - javaBinary.toString, - s"-javaagent:$agent", - s"-Dsemanticdb.javacopts=$javacopts", - s"-Dsemanticdb.pluginpath=$pluginPath", - s"-Dsemanticdb.targetroot=$targetroot", - s"-Dsemanticdb.sourceroot=${index.workingDirectory}" - ) - if (index.verbose) { - javaCommand += s"-Dsemanticdb.debugpath=${debugPath}" - } - javaCommand += """"$@"""" - Files - .write( - dir.resolve("bin").resolve("java"), - s"""#!/usr/bin/env bash - |set -eu - |echo $$@ >> ${dir.resolve("java_arguments")} - |${javaCommand.mkString(" ")} - |""".stripMargin.getBytes(StandardCharsets.UTF_8) - ) - .toFile - .setExecutable(true) - Files - .copy( - javac, - dir.resolve("bin").resolve("javac"), - StandardCopyOption.REPLACE_EXISTING - ) - .toFile - .setExecutable(true) - - val copyFiles = - (source: Path, destination: Path) => { - Files - .walk(source) - .forEach(t => { - val destPath = destination.resolve(source.relativize(t)) - try { - Files.copy(t, destPath) - } catch { - case _: NoSuchFileException => - return - } - }) - } - - // For compile{Test}Kotlin when using jvm toolchains, we need to have access - // to JDK internals found in /lib in JDK 9+, - // else we get "no class roots are found in the JDK path" from the - // compile{Test}Kotlin tasks. - // https://docs.oracle.com/en/java/javase/12/migrate/index.html#JSMIG-GUID-A78CC891-701D-4549-AA4E-B8DD90228B4B - val javaHome = javacPath.getParent.getParent - val libPath = dir.resolve("lib") - val javacLibPath = javaHome.resolve("lib") - copyFiles(javacLibPath, libPath) - } -} -object GradleJavaCompiler { - - /** - * Path to a file that is used to log debugging information from the - * SemanticDB Java Agent. - */ - def debugPath(tmp: Path): Path = tmp.resolve("debugpath.txt") - - /** - * Parses a single space-separated line into a GradleJavaCompiler instance. - * - * Example input: "11 /javacLibPath/javac" - * - * Example output: `Some(GradleJavaCompiler("11", * /javacLibPath/javac))` - */ - def fromLine(line: String): Option[GradleJavaCompiler] = - line.split(' ') match { - case Array(version, path) => - Some(GradleJavaCompiler(version, Paths.get(path))) - case _ => - None - } - -} diff --git a/scip-java/src/main/scala/com/sourcegraph/scip_java/buildtools/GradleJavaToolchains.scala b/scip-java/src/main/scala/com/sourcegraph/scip_java/buildtools/GradleJavaToolchains.scala deleted file mode 100644 index 48e09ad0d..000000000 --- a/scip-java/src/main/scala/com/sourcegraph/scip_java/buildtools/GradleJavaToolchains.scala +++ /dev/null @@ -1,263 +0,0 @@ -package com.sourcegraph.scip_java.buildtools - -import java.nio.charset.StandardCharsets -import java.nio.file.Files -import java.nio.file.Path - -import scala.annotation.tailrec -import scala.jdk.CollectionConverters._ - -import com.sourcegraph.scip_java.Embedded -import com.sourcegraph.scip_java.commands.IndexCommand -import org.intellij.lang.annotations.Language - -case class GradleJavaToolchains( - toolchains: List[GradleJavaCompiler], - tool: GradleBuildTool, - index: IndexCommand, - gradleVersion: Option[String], - javaVersion: Option[String], - isJavaEnabled: Boolean, - isScalaEnabled: Boolean, - isKotlinEnabled: Boolean, - isKotlinMultiplatformEnabled: Boolean, - gradleCommand: String, - tmp: Path -) { - - def isEmpty: Boolean = toolchains.isEmpty - - def isJavaAtLeast(version: Int): Boolean = { - val actualVersion = javaVersion.getOrElse(sys.props("java.version")) - GradleJavaToolchains.isJavaAtLeast( - actualVersion, - math.max(version, 0).toString() - ) - } - - def executableJavacPath(): Option[Path] = { - if (toolchains.isEmpty) { - Some( - Embedded.customJavac( - index.workingDirectory, - tool.targetroot, - tmp, - isJavaAtLeast(17) - ) - ) - } else { - None - } - } - - def paths(): String = { - val processorPath = Embedded.semanticdbJar(tmp) - toolchains - .map( - _.createForwardingToolchain(index, tmp, tool.targetroot, processorPath) - ) - .mkString(",") - } - -} - -object GradleJavaToolchains { - - /** - * Extracts the "Java toolchains" that are used in this Gradle workspace. - * - * @see - * https://docs.gradle.org/6.7/userguide/toolchains.html - */ - def fromWorkspace( - tool: GradleBuildTool, - index: IndexCommand, - gradleCommand: String, - tmp: Path - ): GradleJavaToolchains = { - val scriptPath = tmp.resolve("java-toolchains.gradle") - val toolchainsPath = tmp.resolve("java-toolchains.txt") - val javaEnabledPath = tmp.resolve("java-enabled.txt") - val scalaEnabledPath = tmp.resolve("scala-enabled.txt") - val kotlinEnabledPath = tmp.resolve("kotlin-enabled.txt") - val javaVersionPath = tmp.resolve("java-version.txt") - val kotlinMultiplatformEnabledPath = tmp.resolve( - "kotlin-multiplatform-enabled.txt" - ) - val gradleVersionPath = tmp.resolve("gradle-version.txt") - val taskName = "scipDetectJavaToolchains" - @Language("Groovy") - val script = - s"""| - |try { - | java.nio.file.Files.write( - | java.nio.file.Paths.get( - | java.net.URI.create('${gradleVersionPath.toUri}')), - | [gradle.gradleVersion], - | java.nio.file.StandardOpenOption.TRUNCATE_EXISTING, - | java.nio.file.StandardOpenOption.CREATE) - | java.nio.file.Files.write( - | java.nio.file.Paths.get( - | java.net.URI.create('${javaVersionPath.toUri}')), - | [System.getProperty("java.version")], - | java.nio.file.StandardOpenOption.TRUNCATE_EXISTING, - | java.nio.file.StandardOpenOption.CREATE) - |} catch (Exception e) { - | // Ignore errors. - |} - | - |def scipJavaAppendLine(path, line) { - | java.nio.file.Files.write( - | java.nio.file.Paths.get(path), - | [line], - | java.nio.file.StandardOpenOption.APPEND, - | java.nio.file.StandardOpenOption.CREATE) - |} - | - |allprojects { - | task $taskName { - | def toolchainsOut = java.nio.file.Paths.get( - | java.net.URI.create('${toolchainsPath.toUri}')) - | doLast { - | try { - | tasks.withType(JavaCompile) { - | def lines = new ArrayList() - | def path = javaCompiler.get().getExecutablePath() - | def version = javaCompiler.get().getMetadata().getLanguageVersion().asInt() - | def line = "$$version $$path" - | java.nio.file.Files.write( - | toolchainsOut, - | [line], - | java.nio.file.StandardOpenOption.APPEND, - | java.nio.file.StandardOpenOption.CREATE) - | scipJavaAppendLine(toolchainsOut, line) - | } - | } catch (Exception e) { - | // Ignore errors. - | } - | project.plugins.each { - | def name = it.getClass().getName() - | if (name.endsWith("org.gradle.api.plugins.JavaPlugin")) - | scipJavaAppendLine('$javaEnabledPath', 'true') - | if (name.endsWith("org.gradle.api.plugins.scala.ScalaPlugin")) - | scipJavaAppendLine('$scalaEnabledPath', 'true') - | if (name.startsWith("org.jetbrains.kotlin.gradle.plugin")) - | scipJavaAppendLine('$kotlinEnabledPath', 'true') - | if (name.equals("org.jetbrains.kotlin.gradle.plugin.KotlinMultiplatformPluginWrapper")) - | scipJavaAppendLine('$kotlinMultiplatformEnabledPath', 'true') - | } - | } - | } - |} - |""".stripMargin - Files.write(scriptPath, script.getBytes(StandardCharsets.UTF_8)) - index.process( - List(gradleCommand, "--init-script", scriptPath.toString, taskName) - ) - val toolchains: List[GradleJavaCompiler] = - if (Files.isRegularFile(toolchainsPath)) { - Files - .readAllLines(toolchainsPath) - .asScala - .flatMap(GradleJavaCompiler.fromLine) - .toList - .distinct - } else { - Nil - } - - val gradleVersion = - if (Files.isRegularFile(gradleVersionPath)) { - Some(new String(Files.readAllBytes(gradleVersionPath)).trim) - } else { - None - } - - val javaVersion = - if (Files.isRegularFile(javaVersionPath)) { - Some(new String(Files.readAllBytes(javaVersionPath)).trim) - } else { - None - } - - GradleJavaToolchains( - toolchains, - tool, - index, - gradleVersion = gradleVersion, - javaVersion = javaVersion, - isJavaEnabled = Files.isRegularFile(javaEnabledPath), - isScalaEnabled = Files.isRegularFile(scalaEnabledPath), - isKotlinEnabled = Files.isRegularFile(kotlinEnabledPath), - isKotlinMultiplatformEnabled = Files.isRegularFile( - kotlinMultiplatformEnabledPath - ), - gradleCommand = gradleCommand, - tmp = tmp - ) - } - - // Copy-pasted from scala.util.Properties.isJavaAtLeast but makes the actual - // version a parameterizeable instead of being hard-coded to - // `Properties.javaVersionSpec`. - def isJavaAtLeast( - actualVersion: String, - comparisonVersion: String - ): Boolean = { - def versionOf(s: String, depth: Int): (Int, String) = - s.indexOf('.') match { - case 0 => - (-2, s.substring(1)) - case 1 if depth == 0 && s.charAt(0) == '1' => - val r0 = s.substring(2) - val (v, r) = versionOf(r0, 1) - val n = - if (v > 8 || r0.isEmpty) - -2 - else - v // accept 1.8, not 1.9 or 1. - (n, r) - case -1 => - val n = - if (!s.isEmpty) - s.toInt - else if (depth == 0) - -2 - else - 0 - (n, "") - case i => - val r = s.substring(i + 1) - val n = - if (depth < 2 && r.isEmpty) - -2 - else - s.substring(0, i).toInt - (n, r) - } - @tailrec - def compareVersions(s: String, v: String, depth: Int): Int = { - if (depth >= 3) - 0 - else { - val (sn, srest) = versionOf(s, depth) - val (vn, vrest) = versionOf(v, depth) - if (vn < 0) - -2 - else if (sn < vn) - -1 - else if (sn > vn) - 1 - else - compareVersions(srest, vrest, depth + 1) - } - } - - compareVersions(actualVersion, comparisonVersion, 0) match { - case -2 => - throw new NumberFormatException(s"Not a version: $comparisonVersion") - case i => - i >= 0 - } - } -} diff --git a/scip-java/src/main/scala/com/sourcegraph/scip_java/buildtools/MavenBuildTool.scala b/scip-java/src/main/scala/com/sourcegraph/scip_java/buildtools/MavenBuildTool.scala index a0b4f8631..4450ba997 100644 --- a/scip-java/src/main/scala/com/sourcegraph/scip_java/buildtools/MavenBuildTool.scala +++ b/scip-java/src/main/scala/com/sourcegraph/scip_java/buildtools/MavenBuildTool.scala @@ -38,13 +38,11 @@ class MavenBuildTool(index: IndexCommand) extends BuildTool("Maven", index) { else { "mvn" } - val start = System.nanoTime() val buildCommand = ListBuffer.empty[String] val executable = Embedded.customJavac( index.workingDirectory, index.finalTargetroot(defaultTargetroot), - tmp, - GradleJavaToolchains.isJavaAtLeast(SystemJavaVersion.detect(), "11") + tmp ) buildCommand ++= List( diff --git a/scip-java/src/main/scala/com/sourcegraph/scip_java/buildtools/SystemJavaVersion.scala b/scip-java/src/main/scala/com/sourcegraph/scip_java/buildtools/SystemJavaVersion.scala deleted file mode 100644 index e3a62dbb1..000000000 --- a/scip-java/src/main/scala/com/sourcegraph/scip_java/buildtools/SystemJavaVersion.scala +++ /dev/null @@ -1,30 +0,0 @@ -package com.sourcegraph.scip_java.buildtools - -import java.nio.file.Files - -import com.sourcegraph.scip_java.Embedded - -object SystemJavaVersion { - // Returns the output of `System.getProperty("java.version")` from a fresh JVM - // instance using the system JVM installation. We can't use this process since - // it may be running on a separate JVM process (that's the case when we run - // `sbt test` in this build at least). - def detect(): String = { - val tmp = Files.createTempDirectory("java-version") - val jar = Embedded.semanticdbJar(tmp) - try { - os.proc( - "java", - "-cp", - jar.toString(), - "com.sourcegraph.semanticdb_javac.PrintJavaVersion" - ) - .call() - .out - .text() - .trim() - } finally { - Files.deleteIfExists(jar) - } - } -} diff --git a/scip-java/src/main/scala/com/sourcegraph/scip_java/commands/CommentSyntax.scala b/scip-java/src/main/scala/com/sourcegraph/scip_java/commands/CommentSyntax.scala deleted file mode 100644 index 6d89c2903..000000000 --- a/scip-java/src/main/scala/com/sourcegraph/scip_java/commands/CommentSyntax.scala +++ /dev/null @@ -1,20 +0,0 @@ -package com.sourcegraph.scip_java.commands - -case class CommentSyntax(value: String) { - private val map = - value - .split("\\s+") - .map(_.split(",")) - .collect { case Array(a, b) => - a -> b - } - .toMap - def extensionSyntax(fileExtension: String): String = map.getOrElse( - fileExtension, - "//" - ) -} -object CommentSyntax { - val default = CommentSyntax("py,# sql,-- yaml,# yml,#") - implicit val codec = moped.macros.deriveCodec(default) -} diff --git a/scip-java/src/main/scala/com/sourcegraph/scip_java/commands/IndexCommand.scala b/scip-java/src/main/scala/com/sourcegraph/scip_java/commands/IndexCommand.scala index 566fc0c0e..0d8128d97 100644 --- a/scip-java/src/main/scala/com/sourcegraph/scip_java/commands/IndexCommand.scala +++ b/scip-java/src/main/scala/com/sourcegraph/scip_java/commands/IndexCommand.scala @@ -34,14 +34,6 @@ case class IndexCommand( "For example, the default value for Gradle is 'build/semanticdb-targetroot' and for Maven it's 'target/semanticdb-targetroot'" ) targetroot: Option[Path] = None, - @Description( - "Whether to enable the -verbose flag in the SemanticDB compiler plugin." - ) - verbose: Boolean = false, - @Description( - "Whether to enable the -text:on flag in the SemanticDB compiler plugin." - ) - text: Boolean = false, @Description( "Explicitly specify which build tool to use. " + "By default, the build tool is automatically detected. " + @@ -51,9 +43,6 @@ case class IndexCommand( buildTool: Option[String] = None, @Description("Whether to remove generated temporary files on exit.") cleanup: Boolean = true, - @Description("URL to a PackageHub instance") - @Hidden // Hidden because it's not supposed to be used yet by normal users. - packagehub: Option[String] = None, @Hidden // Hidden because it's only used for testing purposes temporaryDirectory: Option[Path] = None, @Section("SCIP Build Tool") @@ -128,17 +117,6 @@ case class IndexCommand( ) } - def textFlag: String = - if (text) - "-text:on" - else - "" - def verboseFlag: String = - if (verbose) - "-verbose:on" - else - "" - def workingDirectory: Path = AbsolutePath.of(app.env.workingDirectory) def finalTargetroot(default: Path): Path = AbsolutePath.of( targetroot.getOrElse(default), diff --git a/scip-java/src/main/scala/com/sourcegraph/scip_java/commands/IndexSemanticdbCommand.scala b/scip-java/src/main/scala/com/sourcegraph/scip_java/commands/IndexSemanticdbCommand.scala index a2c06aee3..6b1dbcb23 100644 --- a/scip-java/src/main/scala/com/sourcegraph/scip_java/commands/IndexSemanticdbCommand.scala +++ b/scip-java/src/main/scala/com/sourcegraph/scip_java/commands/IndexSemanticdbCommand.scala @@ -2,7 +2,6 @@ package com.sourcegraph.scip_java.commands import java.nio.file.Path import java.nio.file.Paths -import java.util.concurrent.TimeUnit import scala.jdk.CollectionConverters._ @@ -17,8 +16,6 @@ import moped.cli.Application import moped.cli.Command import moped.cli.CommandParser import org.scip_code.scip.ToolInfo -import ujson.Arr -import ujson.Obj @Description("Converts SemanticDB files into a single SCIP index file.") @Usage("scip-java index-semanticdb [OPTIONS ...] [POSITIONAL ARGUMENTS ...]") @@ -31,18 +28,11 @@ final case class IndexSemanticdbCommand( output: Path = Paths.get("index.scip"), @Description("Whether to process the SemanticDB files in parallel") parallel: Boolean = true, - @Description( - "Whether to infer the location of SemanticDB files based as produced by Bazel" - ) - bazel: Boolean = true, @Description( "Whether to emit parent->child relationships for 'Find references' and 'Find implementations'. " + "This flag exists as a workaround for the issue https://github.com/sourcegraph/sourcegraph/issues/50927" ) emitInverseRelationships: Boolean = true, - @Description("URL to a PackageHub instance") - @Hidden - packagehub: Option[String] = None, @Description("Directories that contain SemanticDB files.") @PositionalArguments() targetroot: List[Path] = Nil, @@ -97,42 +87,11 @@ final case class IndexSemanticdbCommand( allowExportingGlobalSymbolsFromDirectoryEntries ) ScipSemanticdb.run(options) - postPackages(packages) if (!app.reporter.hasErrors()) { app.info(options.output.toString) } app.reporter.exitCode() } - - /** - * If the PackageHub URL is configured, sends an HTTP POST request to register - * the packages that are used in this codebase. - * - * PackageHub is a prototype implementation of this proposal - * https://docs.google.com/document/d/1ZcZbPLZX0vblcTI_xb5VtO_49b_9tR5lOWSLoVEBm2A/edit# - */ - private def postPackages(packages: List[ClasspathEntry]): Unit = { - if (packages.isEmpty) - return - packagehub.foreach { url => - val json = Obj("packages" -> Arr.from(packages.map(_.toPackageHubId))) - app.info(s"Posting ${packages.length} package(s) to PackageHub URL $url") - val response = requests.post( - s"$url/packagehub/packages", - headers = Seq("Content-Type" -> "application/json"), - data = json, - chunkedUpload = false, - readTimeout = TimeUnit.MINUTES.toMillis(1).toInt - ) - val responseJson = ujson.read(response) - for { - errors <- responseJson.obj.get("errors").toList - error <- errors.arr - } { - app.warning(error.str) - } - } - } } object IndexSemanticdbCommand { diff --git a/scip-java/src/main/scala/com/sourcegraph/scip_java/commands/SnapshotCommand.scala b/scip-java/src/main/scala/com/sourcegraph/scip_java/commands/SnapshotCommand.scala index 3c298ff7d..bf7c79e1a 100644 --- a/scip-java/src/main/scala/com/sourcegraph/scip_java/commands/SnapshotCommand.scala +++ b/scip-java/src/main/scala/com/sourcegraph/scip_java/commands/SnapshotCommand.scala @@ -64,11 +64,7 @@ case class SnapshotCommand( Files.readAllBytes(sourcepath), StandardCharsets.UTF_8 ) - val document = ScipPrinters.printTextDocument( - doc, - source, - CommentSyntax.default - ) + val document = ScipPrinters.printTextDocument(doc, source) val snapshotOutput = output.resolve(doc.getRelativePath) Files.createDirectories(snapshotOutput.getParent) Files.write( diff --git a/semanticdb-agent/src/main/java/com/sourcegraph/semanticdb_javac/SemanticdbAgent.java b/semanticdb-agent/src/main/java/com/sourcegraph/semanticdb_javac/SemanticdbAgent.java deleted file mode 100644 index 00ea576a2..000000000 --- a/semanticdb-agent/src/main/java/com/sourcegraph/semanticdb_javac/SemanticdbAgent.java +++ /dev/null @@ -1,220 +0,0 @@ -package com.sourcegraph.semanticdb_javac; - -import static net.bytebuddy.implementation.bytecode.assign.Assigner.Typing.DYNAMIC; -import static net.bytebuddy.matcher.ElementMatchers.named; - -import java.io.File; -import java.io.IOException; -import java.io.OutputStream; -import java.io.PrintStream; -import java.lang.instrument.Instrumentation; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.nio.file.StandardOpenOption; -import java.util.ArrayList; -import java.util.List; -import java.util.NoSuchElementException; -import net.bytebuddy.agent.builder.AgentBuilder; -import net.bytebuddy.asm.Advice; - -/** Java agent that injects SemanticDB into the Java compilation process. */ -public class SemanticdbAgent { - - public static void premain(String agentArgs, Instrumentation inst) { - // NOTE(olafur): Uncoment below if you want see all the loaded classes. - // PrintStream logger = newLogger(); - // inst.addTransformer( - // new ClassFileTransformer() { - // @Override - // public byte[] transform( - // ClassLoader loader, - // String className, - // Class classBeingRedefined, - // ProtectionDomain protectionDomain, - // byte[] classfileBuffer) { - // logger.println(className); - // return classfileBuffer; - // } - // }); - new AgentBuilder.Default() - .disableClassFormatChanges() - .type( - named("org.gradle.api.internal.tasks.compile.DefaultJvmLanguageCompileSpec") - .or(named("tests.GradleDefaultJvmLanguageCompileSpec"))) - .transform( - new AgentBuilder.Transformer.ForAdvice() - .advice( - named("getCompileClasspath"), - DefaultJvmLanguageCompileSpecAdvice.class.getName())) - .installOn(inst); - new AgentBuilder.Default() - .disableClassFormatChanges() - .type( - named("org.gradle.api.internal.tasks.compile.DefaultJavaCompileSpec") - .or(named("tests.GradleDefaultJavaCompileSpec"))) - .transform( - new AgentBuilder.Transformer.ForAdvice() - .advice( - named("getAnnotationProcessorPath"), - DefaultJavaCompileSpecAdvice.class.getName())) - .installOn(inst); - new AgentBuilder.Default() - .type( - named("org.gradle.api.internal.tasks.compile.JavaCompilerArgumentsBuilder") - .or(named("tests.GradleJavaCompilerArgumentsBuilder"))) - .transform( - new AgentBuilder.Transformer.ForAdvice() - .advice(named("build"), JavaCompilerArgumentsBuilderAdvice.class.getName())) - .installOn(inst); - } - - private static PrintStream newLogger() { - Path path = Paths.get(System.getProperty("user.home"), ".scip-java", "logs.txt"); - try { - Files.createDirectories(path.getParent()); - OutputStream fos = - Files.newOutputStream( - path, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING); - return new PrintStream(fos); - } catch (IOException e) { - return new PrintStream( - new OutputStream() { - @Override - public void write(int b) {} - }); - } - } - - @SuppressWarnings("all") - public static class DefaultJvmLanguageCompileSpecAdvice { - @Advice.OnMethodExit - public static void getClasspath( - @Advice.Return(readOnly = false, typing = DYNAMIC) List classpath) { - String PLUGINPATH = System.getProperty("semanticdb.pluginpath"); - if (PLUGINPATH == null) throw new NoSuchElementException("-Dsemanticdb.pluginpath"); - File semanticdbJar = new File(PLUGINPATH); - if (!classpath.contains(semanticdbJar)) { - List newClasspath = new ArrayList<>(classpath); - newClasspath.add(semanticdbJar); - classpath = newClasspath; - } - } - } - - @SuppressWarnings("all") - public static class DefaultJavaCompileSpecAdvice { - @Advice.OnMethodExit - public static void getAnnotationProcessorPath( - @Advice.Return(readOnly = false, typing = DYNAMIC) List classpath) { - if (classpath == null) return; - String PLUGINPATH = System.getProperty("semanticdb.pluginpath"); - if (PLUGINPATH == null) throw new NoSuchElementException("-Dsemanticdb.pluginpath"); - File semanticdbJar = new File(PLUGINPATH); - if (!classpath.contains(semanticdbJar)) { - List newClasspath = new ArrayList<>(classpath); - newClasspath.add(semanticdbJar); - classpath = newClasspath; - } - } - } - - @SuppressWarnings("all") - public static class JavaCompilerArgumentsBuilderAdvice { - - /** - * The bytecode of this method gets injected at the end of the following method in Gradle: - * - *

https://github.com/gradle/gradle/blob/2389365c6e0f29cb84b4727a793fe7a7008c9fc7/subprojects/language-java/src/main/java/org/gradle/api/internal/tasks/compile/JavaCompilerArgumentsBuilder.java#L78 - * - * @param arguments The Java compiler that Gradle intends to use. This method updates the - * options to include "-Xplugin:semanticdb". - */ - @Advice.OnMethodExit - public static void build( - @Advice.Return(readOnly = false, typing = DYNAMIC) List arguments) { - - String PLUGINPATH = System.getProperty("semanticdb.pluginpath"); - if (PLUGINPATH == null) throw new NoSuchElementException("-Dsemanticdb.pluginpath"); - String SOURCEROOT = System.getProperty("semanticdb.sourceroot"); - if (SOURCEROOT == null) throw new NoSuchElementException("-Dsemanticdb.sourceroot"); - String TARGETROOT = System.getProperty("semanticdb.targetroot"); - if (TARGETROOT == null) throw new NoSuchElementException("-Dsemanticdb.targetroot"); - String DEBUGPATH = System.getProperty("semanticdb.debugpath"); - String JAVACOPTS = System.getProperty("semanticdb.javacopts"); - if (JAVACOPTS != null) { - try { - Files.write( - Paths.get(JAVACOPTS), - arguments, - StandardCharsets.UTF_8, - StandardOpenOption.APPEND, - StandardOpenOption.CREATE); - } catch (IOException unused) { - } - } - - boolean isProcessorpathUpdated = false; - boolean semanticdbAlreadyAdded = false; - String previousOption = ""; - - ArrayList newOptions = new ArrayList<>(); - for (String option : arguments) { - switch (previousOption) { - case "-processorpath": - case "-processor-path": - case "-cp": - case "-classpath": - case "-class-path": - isProcessorpathUpdated = true; - newOptions.add(PLUGINPATH + File.pathSeparator + option); - break; - case "-Xlint": - break; - default: - if (option.startsWith("-Xplugin:semanticdb")) { - semanticdbAlreadyAdded = true; - break; - } - if (option.startsWith("-Xplugin:ErrorProne")) { - break; - } - newOptions.add(option); - break; - } - previousOption = option; - } - if (!semanticdbAlreadyAdded) { - - if (!isProcessorpathUpdated) { - newOptions.add("-classpath"); - newOptions.add(PLUGINPATH); - } - newOptions.add( - String.format( - "-Xplugin:semanticdb -sourceroot:%s -targetroot:%s", SOURCEROOT, TARGETROOT)); - - if (DEBUGPATH != null) { - ArrayList debuglines = new ArrayList<>(); - debuglines.add("============== Java Home: " + System.getProperty("java.home")); - debuglines.add("============== Old Options"); - debuglines.addAll(arguments); - debuglines.add("============== New Options"); - debuglines.addAll(newOptions); - - try { - Files.write( - Paths.get(DEBUGPATH), - debuglines, - StandardOpenOption.CREATE, - StandardOpenOption.APPEND); - } catch (IOException e) { - } - } - - arguments = newOptions; - } - } - } -} diff --git a/semanticdb-gradle-plugin/src/main/scala/SemanticdbGradlePlugin.scala b/semanticdb-gradle-plugin/src/main/scala/SemanticdbGradlePlugin.scala index 6788574f0..96d7dafee 100644 --- a/semanticdb-gradle-plugin/src/main/scala/SemanticdbGradlePlugin.scala +++ b/semanticdb-gradle-plugin/src/main/scala/SemanticdbGradlePlugin.scala @@ -49,7 +49,6 @@ class SemanticdbGradlePlugin extends Plugin[Project] { .getOrElse(s"com.sourcegraph:semanticdb-javac:${javacPluginVersion}") val sourceRoot = project.getRootDir() - val agentJar = extraProperties.get("javacAgentPath").map(_.toString) val tasks = project.getTasks() @@ -90,11 +89,15 @@ class SemanticdbGradlePlugin extends Plugin[Project] { true } catch { case exc: Exception => - // If the `compileOnly` configuration has already been evaluated - // by the build, we need to fallback on agent injected into javac + // The `compileOnly` configuration has likely already been + // resolved by another plugin or buildscript, so we can no longer + // add new dependencies to it. The project will be skipped (no + // SemanticDB output) and the post-build check in + // `GradleBuildTool` will surface a clearer error. warn( - s"Failed to add compiler plugin to javac, will go through the agent route (${exc - .getClass()}): ${exc.getMessage()}" + s"scip-java: failed to attach SemanticDB compiler plugin to project '${project + .getName()}' (${exc.getClass().getSimpleName()}: ${exc + .getMessage()}). This subproject will not be indexed." ) false } @@ -181,32 +184,6 @@ class SemanticdbGradlePlugin extends Plugin[Project] { ) } } - - /** - * In some yet to be understood cases we see that compiler plugin - * can be added successfully, but the correct flags are still not - * propagated. - * - * To work around it, we enable the agent unconditionally, and then - * if necessary deduplicate the arguments. - * - * TODO: figure out why this is necessary - */ - agentJar.foreach { agentpath => - javacPluginJar.foreach { pluginpath => - val jvmArgs = task.getOptions.getForkOptions.getJvmArgs - - jvmArgs.addAll( - List( - s"-javaagent:$agentpath", - s"-Dsemanticdb.pluginpath=$pluginpath", - s"-Dsemanticdb.sourceroot=$sourceRoot", - s"-Dsemanticdb.targetroot=$targetRoot" - ).asJava - ) - } - } - } } diff --git a/semanticdb-javac/src/main/java/com/sourcegraph/semanticdb_javac/PrintJavaVersion.java b/semanticdb-javac/src/main/java/com/sourcegraph/semanticdb_javac/PrintJavaVersion.java deleted file mode 100644 index 07826402d..000000000 --- a/semanticdb-javac/src/main/java/com/sourcegraph/semanticdb_javac/PrintJavaVersion.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.sourcegraph.semanticdb_javac; - -public class PrintJavaVersion { - public static void main(String[] args) { - System.out.print(System.getProperty("java.version")); - } -} 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 093c3a733..6f0207bd1 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 @@ -256,9 +256,9 @@ public Void visitPackage(PackageTree node, Void unused) { // Stop traversal at the package declaration. JDK 17+ TreePathScanner // recurses into the package name's identifiers and would emit a // self-reference for `package X.Y;`; JDK 11 does not. Skipping the - // whole package subtree keeps semanticdb output stable across JDKs and - // matches the long-standing JDK 8/11 behavior of not emitting a - // reference for the package declaration itself. + // whole package subtree keeps semanticdb output stable across JDKs by + // matching the JDK 11 behavior of not emitting a reference for the + // package declaration itself. return null; } diff --git a/tests/buildTools/src/main/scala/tests/GradleDefaultJvmLanguageCompileSpec.scala b/tests/buildTools/src/main/scala/tests/GradleDefaultJvmLanguageCompileSpec.scala deleted file mode 100644 index 4043df006..000000000 --- a/tests/buildTools/src/main/scala/tests/GradleDefaultJvmLanguageCompileSpec.scala +++ /dev/null @@ -1,12 +0,0 @@ -package tests - -import java.io.File -import java.util - -import scala.jdk.CollectionConverters._ - -class GradleDefaultJvmLanguageCompileSpec(base: List[String]) { - def getCompileClasspath: util.List[File] = { - base.map(new File(_)).asJava - } -} diff --git a/tests/buildTools/src/main/scala/tests/GradleJavaCompilerArgumentsBuilder.scala b/tests/buildTools/src/main/scala/tests/GradleJavaCompilerArgumentsBuilder.scala deleted file mode 100644 index b59aa6146..000000000 --- a/tests/buildTools/src/main/scala/tests/GradleJavaCompilerArgumentsBuilder.scala +++ /dev/null @@ -1,7 +0,0 @@ -package tests - -import scala.jdk.CollectionConverters._ - -class GradleJavaCompilerArgumentsBuilder(base: List[String]) { - def build(): java.util.List[String] = base.asJava -} diff --git a/tests/buildTools/src/test/scala/tests/BaseBuildToolSuite.scala b/tests/buildTools/src/test/scala/tests/BaseBuildToolSuite.scala index 45b12f5fd..31aca108a 100644 --- a/tests/buildTools/src/test/scala/tests/BaseBuildToolSuite.scala +++ b/tests/buildTools/src/test/scala/tests/BaseBuildToolSuite.scala @@ -113,9 +113,6 @@ abstract class BaseBuildToolSuite extends MopedSuite(ScipJava.app) { targetroot.toString ) ++ extraArguments val exit = app().run(arguments) - if (extraArguments.contains("--verbose")) { - println(app.capturedOutput) - } expectedError match { case Some(fn) => assert(clue(exit) != 0, clues(app.capturedOutput)) @@ -139,7 +136,7 @@ abstract class BaseBuildToolSuite extends MopedSuite(ScipJava.app) { if (expectedPackages.nonEmpty) { val obtainedPackages = ClasspathEntry .fromTargetroot(targetroot, workingDirectory) - .map(_.toPackageHubId) + .map(_.mavenCoordinate) .sorted .distinct .mkString("\n") @@ -151,51 +148,29 @@ abstract class BaseBuildToolSuite extends MopedSuite(ScipJava.app) { } object BaseBuildToolSuite { + // Major version of the JVM that `java` on PATH resolves to. Compiled and + // executed as a subprocess because the test JVM may differ from PATH. lazy val externalJavaVersion: Int = { val tmpDir = os.temp.dir() - var version = Option.empty[String] try { os.write(tmpDir / "PrintJavaVersion.java", PrintJavaVersion) - os.proc("javac", "PrintJavaVersion.java").call(cwd = tmpDir) - - version = Some( - os.proc("java", "PrintJavaVersion").call(cwd = tmpDir).out.text() - ) + os.proc("java", "PrintJavaVersion") + .call(cwd = tmpDir) + .out + .text() + .trim + .toInt } finally { os.remove.all(tmpDir) } - - version - .map(parseJavaVersion) - .getOrElse(sys.error("Failed to detect external JDK version")) - } - - private def parseJavaVersion(raw: String) = { - val prop = raw.takeWhile(c => c.isDigit || c == '.') - - val segments = prop.split("\\.").toList - - segments match { - // Java 17.0.1, 11.0.20.1, .. - case modern :: _ :: _ :: rest => - modern.toInt - // Java 12 - case modern :: Nil => - modern.toInt - case other => - sys.error( - s"Cannot process [java.version] property, unknown format: [$raw]" - ) - } } private val PrintJavaVersion = """ public class PrintJavaVersion { public static void main(String[] args) { - System.out.print(System.getProperty("java.version")); + System.out.print(Runtime.version().feature()); } } - """ } diff --git a/tests/buildTools/src/test/scala/tests/GradleDefaultJvmLanguageCompileSpecSuite.scala b/tests/buildTools/src/test/scala/tests/GradleDefaultJvmLanguageCompileSpecSuite.scala deleted file mode 100644 index dd96add9d..000000000 --- a/tests/buildTools/src/test/scala/tests/GradleDefaultJvmLanguageCompileSpecSuite.scala +++ /dev/null @@ -1,29 +0,0 @@ -package tests - -import scala.jdk.CollectionConverters._ - -import munit.FunSuite -import munit.TestOptions - -class GradleDefaultJvmLanguageCompileSpecSuite extends FunSuite { - val pluginpath = System.getProperty("semanticdb.pluginpath") - def check( - options: TestOptions, - original: List[String], - expected: List[String] - ): Unit = { - test(options) { - val obtained = - new GradleDefaultJvmLanguageCompileSpec(original) - .getCompileClasspath - .asScala - .map(_.toString) - .toList - assertEquals(obtained, expected) - } - } - - check("empty", List(), List(pluginpath)) - check("non-empty", List("foo"), List("foo", pluginpath)) - -} diff --git a/tests/buildTools/src/test/scala/tests/GradleJavaCompilerArgumentsBuilderSuite.scala b/tests/buildTools/src/test/scala/tests/GradleJavaCompilerArgumentsBuilderSuite.scala deleted file mode 100644 index 3f6aa45f7..000000000 --- a/tests/buildTools/src/test/scala/tests/GradleJavaCompilerArgumentsBuilderSuite.scala +++ /dev/null @@ -1,66 +0,0 @@ -package tests - -import java.io.File - -import scala.jdk.CollectionConverters._ - -import munit.FunSuite -import munit.TestOptions - -class GradleJavaCompilerArgumentsBuilderSuite extends FunSuite { - val targetroot = System.getProperty("semanticdb.targetroot") - val sourceroot = System.getProperty("semanticdb.sourceroot") - val pluginpath = System.getProperty("semanticdb.pluginpath") - val Xplugin = - s"-Xplugin:semanticdb -sourceroot:$sourceroot -targetroot:$targetroot" - def check( - options: TestOptions, - original: List[String], - expected: List[String] - ): Unit = { - test(options) { - val obtained = - new GradleJavaCompilerArgumentsBuilder(original).build().asScala.toList - assertEquals(obtained, expected) - } - } - - check( - "basic", - List("-Arandom"), - List("-Arandom", "-classpath", pluginpath, Xplugin) - ) - - check( - "only-classpath", - List("-classpath", "a.jar"), - List( - "-classpath", - List(pluginpath, "a.jar").mkString(File.pathSeparator), - Xplugin - ) - ) - - check( - "only-processorpath", - List("-processorpath", "a.jar"), - List( - "-processorpath", - List(pluginpath, "a.jar").mkString(File.pathSeparator), - Xplugin - ) - ) - - check( - "classpath-and-processorpath", - List("-classpath", "a.jar", "-processorpath", "b.jar"), - List( - "-classpath", - List(pluginpath, "a.jar").mkString(File.pathSeparator), - "-processorpath", - List(pluginpath, "b.jar").mkString(File.pathSeparator), - Xplugin - ) - ) - -}