Skip to content

Commit 78bf107

Browse files
Small refacto
1 parent 1a65a0f commit 78bf107

33 files changed

+287
-272
lines changed

modules/build/src/main/scala/scala/build/Build.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,8 @@ object Build {
6868
else
6969
Left(
7070
new SeveralMainClassesFoundError(
71-
::(foundMainClasses0.head, foundMainClasses0.tail.toList)
71+
::(foundMainClasses0.head, foundMainClasses0.tail.toList),
72+
Nil
7273
)
7374
)
7475

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
11
package scala.build.errors
22

3-
abstract class MainClassError(message: String) extends BuildException(message)
3+
import scala.build.Position
4+
5+
abstract class MainClassError(
6+
message: String,
7+
positions: Seq[Position]
8+
) extends BuildException(message, positions = positions)
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
package scala.build.errors
22

3-
final class NoMainClassFoundError extends MainClassError("No main class found")
3+
final class NoMainClassFoundError extends MainClassError("No main class found", Nil)
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package scala.build.errors
2+
3+
import scala.build.preprocessing.directives.StrictDirective
4+
5+
final class NoValueProvidedError(
6+
val directive: StrictDirective
7+
) extends BuildException(
8+
s"Expected a value for directive ${directive.key}",
9+
positions = Nil // I wish using_directives provided the key position…
10+
) {
11+
assert(directive.numericalOrStringValuesCount == 0)
12+
}
Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
11
package scala.build.errors
22

3-
final class SeveralMainClassesFoundError(mainClasses: ::[String])
4-
extends MainClassError(s"Found several main classes: ${mainClasses.mkString(", ")}")
3+
import scala.build.Position
4+
5+
final class SeveralMainClassesFoundError(
6+
mainClasses: ::[String],
7+
positions: Seq[Position]
8+
) extends MainClassError(
9+
s"Found several main classes: ${mainClasses.mkString(", ")}",
10+
positions = positions
11+
)
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package scala.build.errors
2+
3+
import scala.build.preprocessing.directives.{DirectiveUtil, StrictDirective}
4+
5+
final class SingleValueExpectedError(
6+
val directive: StrictDirective,
7+
val path: Either[String, os.Path]
8+
) extends BuildException(
9+
s"Expected a single value for directive ${directive.key} " +
10+
s"(got ${directive.values.length} values: ${directive.values.map(_.get().toString).mkString(", ")})",
11+
positions = DirectiveUtil.positions(directive.values, path)
12+
) {
13+
assert(directive.numericalOrStringValuesCount > 1)
14+
}

modules/build/src/main/scala/scala/build/preprocessing/ScalaPreprocessor.scala

Lines changed: 33 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,12 @@ import java.nio.charset.StandardCharsets
1515

1616
import scala.build.EitherCps.{either, value}
1717
import scala.build.Ops._
18-
import scala.build.errors.{BuildException, CompositeBuildException, DependencyFormatError}
18+
import scala.build.errors.{
19+
BuildException,
20+
CompositeBuildException,
21+
DependencyFormatError,
22+
UnusedDirectiveError
23+
}
1924
import scala.build.internal.{AmmUtil, Util}
2025
import scala.build.options.{BuildOptions, BuildRequirements, ClassPathOptions, ShadowingSeq}
2126
import scala.build.preprocessing.directives._
@@ -301,7 +306,7 @@ case object ScalaPreprocessor extends Preprocessor {
301306
)
302307
}
303308

304-
val directives2 = updatedRequirements.unused
309+
val unusedDirectives = updatedRequirements.unused
305310

306311
val updatedContentOpt =
307312
if (codeOffset > 0) {
@@ -318,24 +323,35 @@ case object ScalaPreprocessor extends Preprocessor {
318323
else None
319324

320325
value {
321-
if (directives2.nonEmpty) {
322-
val errors = directives2.map(d =>
323-
new DefaultDirectiveHandler[Nothing].handleValues(d, path, cwd, logger)
324-
).collect {
325-
case Left(e) => e
326-
}
327-
Left(CompositeBuildException(errors))
326+
unusedDirectives match {
327+
case Seq() =>
328+
Right(StrictDirectivesProcessingOutput(
329+
updatedRequirements.global,
330+
updatedOptions.global,
331+
updatedRequirements.scoped,
332+
updatedContentOpt
333+
))
334+
case Seq(h, t @ _*) =>
335+
val errors = ::(
336+
handleUnusedValues(h, path, cwd),
337+
t.map(d => handleUnusedValues(d, path, cwd)).toList
338+
)
339+
Left(CompositeBuildException(errors))
328340
}
329-
else
330-
Right(StrictDirectivesProcessingOutput(
331-
updatedRequirements.global,
332-
updatedOptions.global,
333-
updatedRequirements.scoped,
334-
updatedContentOpt
335-
))
336341
}
337342
}
338343

344+
private def handleUnusedValues(
345+
directive: StrictDirective,
346+
path: Either[String, os.Path],
347+
cwd: ScopePath
348+
): BuildException = {
349+
val values =
350+
DirectiveUtil.stringValues(directive.values, path, cwd) ++
351+
DirectiveUtil.numericValues(directive.values, path, cwd)
352+
new UnusedDirectiveError(directive.key, values.map(_._1.value), values.flatMap(_._1.positions))
353+
}
354+
339355
case class ExtractedDirectives(offset: Int, directives: Seq[StrictDirective])
340356

341357
val changeToSpecialCommentMsg =
@@ -383,7 +399,7 @@ case object ScalaPreprocessor extends Preprocessor {
383399
val usedDirectives =
384400
if (!codeDirectives.getFlattenedMap().isEmpty()) {
385401
val msg =
386-
s"This using directive is ignored. File contains directives outside comments and those has higher precedence."
402+
"This using directive is ignored. File contains directives outside comments and those have higher precedence."
387403
reportWarning(
388404
msg,
389405
getDirectives(plainCommentDirectives) ++ getDirectives(specialCommentDirectives)

modules/build/src/main/scala/scala/build/preprocessing/directives/DefaultDirectiveHandler.scala

Lines changed: 0 additions & 32 deletions
This file was deleted.

modules/build/src/main/scala/scala/build/preprocessing/directives/DirectiveHandler.scala

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,7 @@ package scala.build.preprocessing.directives
22

33
import scala.build.Logger
44
import scala.build.errors.BuildException
5-
import scala.build.preprocessing.{ScopePath, Scoped}
6-
7-
case class ProcessedDirective[T](global: Option[T], scoped: Seq[Scoped[T]])
5+
import scala.build.preprocessing.ScopePath
86

97
trait DirectiveHandler[T] {
108
def name: String
@@ -14,7 +12,6 @@ trait DirectiveHandler[T] {
1412
def usageMd: String = s"`$usage`"
1513
def examples: Seq[String] = Nil
1614

17-
// Strict / using_directives-based directives
1815
def keys: Seq[String]
1916

2017
def handleValues(

modules/build/src/main/scala/scala/build/preprocessing/directives/DirectiveUtil.scala

Lines changed: 33 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2,43 +2,49 @@ package scala.build.preprocessing.directives
22

33
import com.virtuslab.using_directives.custom.model.{NumericValue, StringValue, Value}
44

5-
import scala.build.Position
65
import scala.build.preprocessing.ScopePath
6+
import scala.build.{Position, Positioned}
77

88
object DirectiveUtil {
99
def stringValues(
1010
values: Seq[Value[_]],
1111
path: Either[String, os.Path],
1212
cwd: ScopePath
13-
): Seq[(String, Position, Option[ScopePath])] =
14-
values
15-
.collect {
16-
case v: StringValue =>
17-
val line = v.getRelatedASTNode.getPosition.getLine
18-
val column = v.getRelatedASTNode.getPosition.getColumn + 1 // Using directives are 0 based
19-
Seq((
20-
v.get,
21-
Position.File(path, (line, column), (line, column)),
22-
Option(v.getScope).map((p: String) => cwd / os.RelPath(p))
23-
))
24-
}
25-
.flatten
13+
): Seq[(Positioned[String], Option[ScopePath])] =
14+
values.collect {
15+
case v: StringValue =>
16+
val line = v.getRelatedASTNode.getPosition.getLine
17+
val column = v.getRelatedASTNode.getPosition.getColumn + 1 // Using directives are 0 based
18+
val pos = Position.File(path, (line, column), (line, column))
19+
(
20+
Positioned(pos, v.get),
21+
Option(v.getScope).map((p: String) => cwd / os.RelPath(p))
22+
)
23+
}
2624

2725
def numericValues(
2826
values: Seq[Value[_]],
2927
path: Either[String, os.Path],
3028
cwd: ScopePath
31-
): Seq[(String, Position, Option[ScopePath])] =
32-
values
33-
.collect {
34-
case v: NumericValue =>
35-
val line = v.getRelatedASTNode.getPosition.getLine
36-
val column = v.getRelatedASTNode.getPosition.getColumn
37-
Seq((
38-
v.get,
39-
Position.File(path, (line, column), (line, column)),
40-
Option(v.getScope).map((p: String) => cwd / os.RelPath(p))
41-
))
42-
}
43-
.flatten
29+
): Seq[(Positioned[String], Option[ScopePath])] =
30+
values.collect {
31+
case v: NumericValue =>
32+
val line = v.getRelatedASTNode.getPosition.getLine
33+
val column = v.getRelatedASTNode.getPosition.getColumn
34+
val pos = Position.File(path, (line, column), (line, column))
35+
(
36+
Positioned(pos, v.get),
37+
Option(v.getScope).map((p: String) => cwd / os.RelPath(p))
38+
)
39+
}
40+
41+
def positions(
42+
values: Seq[Value[_]],
43+
path: Either[String, os.Path]
44+
): Seq[Position] =
45+
values.map { v =>
46+
val line = v.getRelatedASTNode.getPosition.getLine
47+
val column = v.getRelatedASTNode.getPosition.getColumn
48+
Position.File(path, (line, column), (line, column))
49+
}
4450
}

0 commit comments

Comments
 (0)