Skip to content

Commit 9efd7ab

Browse files
committed
WIP simplify error reporting
1 parent 108b9e9 commit 9efd7ab

File tree

1 file changed

+21
-14
lines changed

1 file changed

+21
-14
lines changed

library/src/scala/annotation/newMain.scala

+21-14
Original file line numberDiff line numberDiff line change
@@ -79,14 +79,6 @@ final class newMain extends MainAnnotation[FromString, Any]:
7979

8080
private var info: Info = _ // TODO remove this var
8181

82-
/** A buffer for all errors */
83-
private val errors = new mutable.ArrayBuffer[String]
84-
85-
/** Issue an error, and return an uncallable getter */
86-
private def error(msg: String): () => Nothing =
87-
errors += msg
88-
() => throw new AssertionError("trying to get invalid argument")
89-
9082
private def getAliases(param: Parameter): Seq[String] =
9183
param.annotations.collect{ case a: Alias => a }.flatMap(_.aliases)
9284

@@ -117,6 +109,12 @@ final class newMain extends MainAnnotation[FromString, Any]:
117109
def command(info: Info, args: Seq[String]): Option[Seq[String]] =
118110
this.info = info
119111

112+
val errors = new mutable.ArrayBuffer[String]
113+
114+
def error(msg: String): Unit = {
115+
errors += msg
116+
}
117+
120118
val namesToCanonicalName: Map[String, String] = info.parameters.flatMap(
121119
infos =>
122120
val names = getAlternativeNames(infos)
@@ -316,24 +314,33 @@ final class newMain extends MainAnnotation[FromString, Any]:
316314

317315
def argGetter[T](param: Parameter, arg: String, defaultArgument: Option[() => T])(using p: FromString[T]): () => T = {
318316
if arg.nonEmpty then parse[T](param, arg)
319-
else defaultArgument match
320-
case Some(defaultGetter) => defaultGetter
321-
case None => error(s"missing argument for ${param.name}")
317+
else
318+
assert(param.hasDefault)
319+
320+
defaultArgument.get
322321
}
323322

324323
def varargGetter[T](param: Parameter, args: Seq[String])(using p: FromString[T]): () => Seq[T] = {
325324
val getters = args.map(arg => parse[T](param, arg))
326325
() => getters.map(_())
327326
}
328327

328+
/** A buffer for all parsing errors errors */
329+
private lazy val parseErrors = new mutable.ArrayBuffer[String]
330+
331+
/** Issue an error, and return an uncallable getter */
332+
private def parseError(msg: String): () => Nothing =
333+
parseErrors += msg
334+
() => throw new AssertionError("trying to get invalid argument")
335+
329336
private def parse[T](param: Parameter, arg: String)(using p: FromString[T]): () => T =
330337
p.fromStringOption(arg) match
331338
case Some(t) => () => t
332-
case None => error(s"could not parse argument for `${param.name}` of type ${param.typeName.split('.').last}: $arg")
339+
case None => parseError(s"could not parse argument for `${param.name}` of type ${param.typeName.split('.').last}: $arg")
333340

334341
def run(execProgram: () => Any): Unit = {
335-
if errors.nonEmpty then
336-
for msg <- errors do println(s"Error: $msg")
342+
if parseErrors.nonEmpty then
343+
for msg <- parseErrors do println(s"Error: $msg")
337344
usage()
338345
else
339346
execProgram()

0 commit comments

Comments
 (0)