
scala.build.preprocessing.ExtractedDirectives.scala Maven / Gradle / Ivy
package scala.build.preprocessing
import com.virtuslab.using_directives.UsingDirectivesProcessor
import com.virtuslab.using_directives.custom.model.{
BooleanValue,
EmptyValue,
StringValue,
UsingDirectives,
Value
}
import com.virtuslab.using_directives.custom.utils.ast._
import scala.annotation.targetName
import scala.build.errors.*
import scala.build.preprocessing.UsingDirectivesOps.*
import scala.build.preprocessing.directives.{DirectiveUtil, ScopedDirective, StrictDirective}
import scala.build.{Logger, Position}
import scala.collection.mutable
import scala.jdk.CollectionConverters.*
case class ExtractedDirectives(
directives: Seq[StrictDirective],
position: Option[Position.File]
) {
@targetName("append")
def ++(other: ExtractedDirectives): ExtractedDirectives =
ExtractedDirectives(directives ++ other.directives, position)
}
object ExtractedDirectives {
def empty: ExtractedDirectives = ExtractedDirectives(Seq.empty, None)
def from(
contentChars: Array[Char],
path: Either[String, os.Path],
logger: Logger,
maybeRecoverOnError: BuildException => Option[BuildException]
): Either[BuildException, ExtractedDirectives] = {
val errors = new mutable.ListBuffer[Diagnostic]
val reporter = CustomDirectivesReporter.create(path) { diag =>
if (diag.severity == Severity.Warning)
logger.log(Seq(diag))
else
errors += diag
}
val processor = new UsingDirectivesProcessor(reporter)
val allDirectives = processor.extract(contentChars).asScala
val malformedDirectiveErrors =
errors.map(diag => new MalformedDirectiveError(diag.message, diag.positions)).toSeq
val maybeCompositeMalformedDirectiveError =
if (malformedDirectiveErrors.nonEmpty)
maybeRecoverOnError(CompositeBuildException(malformedDirectiveErrors))
else None
if (malformedDirectiveErrors.isEmpty || maybeCompositeMalformedDirectiveError.isEmpty) {
val directivesOpt = allDirectives.headOption
val directivesPositionOpt = directivesOpt match {
case Some(directives)
if directives.containsTargetDirectives ||
directives.isEmpty => None
case Some(directives) => Some(directives.getPosition(path))
case None => None
}
val strictDirectives = directivesOpt.toSeq.flatMap { directives =>
def toStrictValue(value: UsingValue): Seq[Value[_]] = value match {
case uvs: UsingValues => uvs.values.asScala.toSeq.flatMap(toStrictValue)
case el: EmptyLiteral => Seq(EmptyValue(el))
case sl: StringLiteral => Seq(StringValue(sl.getValue(), sl))
case bl: BooleanLiteral => Seq(BooleanValue(bl.getValue(), bl))
}
def toStrictDirective(ud: UsingDef) = StrictDirective(
ud.getKey(),
toStrictValue(ud.getValue()),
ud.getPosition().getColumn()
)
directives.getAst match
case uds: UsingDefs => uds.getUsingDefs.asScala.toSeq.map(toStrictDirective)
case ud: UsingDef => Seq(toStrictDirective(ud))
case _ => Nil // There should be nothing else here other than UsingDefs or UsingDef
}
Right(ExtractedDirectives(strictDirectives.reverse, directivesPositionOpt))
}
else
maybeCompositeMalformedDirectiveError match {
case Some(e) => Left(e)
case None => Right(ExtractedDirectives.empty)
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy