All Downloads are FREE. Search and download functionalities are using the official Maven repository.

scala.build.postprocessing.SemanticDbPostProcessor.scala Maven / Gradle / Ivy

package scala.build.postprocessing

import java.nio.file.FileSystemException

import scala.annotation.tailrec
import scala.build.{GeneratedSource, Logger}
import scala.util.{Either, Right}
case object SemanticDbPostProcessor extends PostProcessor {
  def postProcess(
    generatedSources: Seq[GeneratedSource],
    mappings: Map[String, (String, Int)],
    workspace: os.Path,
    output: os.Path,
    logger: Logger,
    scalaVersion: String
  ): Either[String, Unit] = Right {
    logger.debug("Moving semantic DBs around")
    val semDbRoot = output / "META-INF" / "semanticdb"
    for (source <- generatedSources; originalSource <- source.reportingPath) {
      val fromSourceRoot = source.generated.relativeTo(workspace)
      val actual         = originalSource.relativeTo(workspace)

      val semDbSubPath = {
        val dirSegments = fromSourceRoot.segments.dropRight(1)
        os.sub / dirSegments / s"${fromSourceRoot.last}.semanticdb"
      }
      val semDbFile = semDbRoot / semDbSubPath
      if (os.exists(semDbFile)) {
        val finalSemDbFile = {
          val dirSegments = actual.segments.dropRight(1)
          semDbRoot / dirSegments / s"${actual.last}.semanticdb"
        }
        SemanticdbProcessor.postProcess(
          os.read(originalSource),
          originalSource.relativeTo(workspace),
          if (source.topWrapperLen == 0) n => Some(n)
          else
            LineConversion.scalaLineToScLine(
              os.read(originalSource),
              os.read(source.generated),
              source.topWrapperLen
            ),
          semDbFile,
          finalSemDbFile
        )
        try os.remove(semDbFile)
        catch {
          case ex: FileSystemException =>
            logger.debug(s"Ignoring $ex while removing $semDbFile")
        }
        deleteSubPathIfEmpty(semDbRoot, semDbSubPath / os.up, logger)
      }
    }
  }

  @tailrec
  private def deleteSubPathIfEmpty(base: os.Path, subPath: os.SubPath, logger: Logger): Unit =
    if (subPath.segments.nonEmpty) {
      val p = base / subPath
      if (os.isDir(p) && os.list.stream(p).headOption.isEmpty) {
        try os.remove(p)
        catch {
          case e: FileSystemException =>
            logger.debug(s"Ignoring $e while cleaning up $p")
        }
        deleteSubPathIfEmpty(base, subPath / os.up, logger)
      }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy