Skip to content

Commit 3e21f03

Browse files
Disable ExtractSemanticDB phase when writing to output directory defined 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.
2 parents 2fafeaa + 942e184 commit 3e21f03

File tree

1 file changed

+12
-8
lines changed

1 file changed

+12
-8
lines changed

compiler/src/dotty/tools/dotc/semanticdb/ExtractSemanticDB.scala

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import scala.annotation.{ threadUnsafe => tu, tailrec }
2424
import scala.PartialFunction.condOpt
2525

2626
import dotty.tools.dotc.{semanticdb => s}
27+
import dotty.tools.io.{AbstractFile, JarArchive}
2728

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

4041
override def isRunnable(using Context) =
41-
super.isRunnable && ctx.settings.Xsemanticdb.value
42+
import ExtractSemanticDB.{semanticdbTarget, outputDirectory}
43+
def writesToOutputJar = semanticdbTarget.isEmpty && outputDirectory.isInstanceOf[JarArchive]
44+
super.isRunnable && ctx.settings.Xsemanticdb.value && !writesToOutputJar
4245

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

481+
private def semanticdbTarget(using Context): Option[Path] =
482+
Option(ctx.settings.semanticdbTarget.value)
483+
.filterNot(_.isEmpty)
484+
.map(Paths.get(_))
485+
486+
private def outputDirectory(using Context): AbstractFile = ctx.settings.outputDir.value
487+
478488
def write(
479489
source: SourceFile,
480490
occurrences: List[SymbolOccurrence],
481491
symbolInfos: List[SymbolInformation],
482492
synthetics: List[Synthetic],
483493
)(using Context): Unit =
484494
def absolutePath(path: Path): Path = path.toAbsolutePath.normalize
485-
val semanticdbTarget =
486-
val semanticdbTargetSetting = ctx.settings.semanticdbTarget.value
487-
absolutePath(
488-
if semanticdbTargetSetting.isEmpty then ctx.settings.outputDir.value.jpath
489-
else Paths.get(semanticdbTargetSetting)
490-
)
491495
val relPath = SourceFile.relativePath(source, ctx.settings.sourceroot.value)
492-
val outpath = semanticdbTarget
496+
val outpath = absolutePath(semanticdbTarget.getOrElse(outputDirectory.jpath))
493497
.resolve("META-INF")
494498
.resolve("semanticdb")
495499
.resolve(relPath)

0 commit comments

Comments
 (0)