Skip to content

Commit

Permalink
Disable ExtractSemanticDB phase when writing to output directory de…
Browse files Browse the repository at this point in the history
…fined as JAR. (#16790)

Change extracted from #15322 where
the issue was discovered

Writing to outputDirectory when it is a JAR can lead to producing
malformed file, it is using FileOutputStream which works somehow
correct, but if we would open the same JAR again in later phase (eg.
genBCode) header of the file would be malformed: the result file grows
in size respectively to provided input, but we can read only files
written by SemanticDB phase.
  • Loading branch information
WojciechMazur authored Jan 30, 2023
2 parents 2fafeaa + 942e184 commit 3e21f03
Showing 1 changed file with 12 additions and 8 deletions.
20 changes: 12 additions & 8 deletions compiler/src/dotty/tools/dotc/semanticdb/ExtractSemanticDB.scala
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import scala.annotation.{ threadUnsafe => tu, tailrec }
import scala.PartialFunction.condOpt

import dotty.tools.dotc.{semanticdb => s}
import dotty.tools.io.{AbstractFile, JarArchive}

/** Extract symbol references and uses to semanticdb files.
* See https://scalameta.org/docs/semanticdb/specification.html#symbol-1
Expand All @@ -38,7 +39,9 @@ class ExtractSemanticDB extends Phase:
override val description: String = ExtractSemanticDB.description

override def isRunnable(using Context) =
super.isRunnable && ctx.settings.Xsemanticdb.value
import ExtractSemanticDB.{semanticdbTarget, outputDirectory}
def writesToOutputJar = semanticdbTarget.isEmpty && outputDirectory.isInstanceOf[JarArchive]
super.isRunnable && ctx.settings.Xsemanticdb.value && !writesToOutputJar

// Check not needed since it does not transform trees
override def isCheckable: Boolean = false
Expand Down Expand Up @@ -475,21 +478,22 @@ object ExtractSemanticDB:
val name: String = "extractSemanticDB"
val description: String = "extract info into .semanticdb files"

private def semanticdbTarget(using Context): Option[Path] =
Option(ctx.settings.semanticdbTarget.value)
.filterNot(_.isEmpty)
.map(Paths.get(_))

private def outputDirectory(using Context): AbstractFile = ctx.settings.outputDir.value

def write(
source: SourceFile,
occurrences: List[SymbolOccurrence],
symbolInfos: List[SymbolInformation],
synthetics: List[Synthetic],
)(using Context): Unit =
def absolutePath(path: Path): Path = path.toAbsolutePath.normalize
val semanticdbTarget =
val semanticdbTargetSetting = ctx.settings.semanticdbTarget.value
absolutePath(
if semanticdbTargetSetting.isEmpty then ctx.settings.outputDir.value.jpath
else Paths.get(semanticdbTargetSetting)
)
val relPath = SourceFile.relativePath(source, ctx.settings.sourceroot.value)
val outpath = semanticdbTarget
val outpath = absolutePath(semanticdbTarget.getOrElse(outputDirectory.jpath))
.resolve("META-INF")
.resolve("semanticdb")
.resolve(relPath)
Expand Down

0 comments on commit 3e21f03

Please sign in to comment.