@@ -62,45 +62,26 @@ final class newMain extends MainAnnotation[FromString, Any]:
6262 import newMain ._
6363 import MainAnnotation ._
6464
65- private inline val argMarker = " --"
66- private inline val shortArgMarker = " -"
67-
6865 private val longArgRegex = " --[a-zA-Z][a-zA-Z0-9]+" .r
6966 private val shortArgRegex = " -[a-zA-Z]" .r
7067
7168 extension (param : Parameter )
7269 private def aliasNames : Seq [String ] =
73- param.annotations.collect{ case a : Alias => a.aliases }.flatten
74-
75- private def longAliases : Seq [String ] =
76- param.aliasNames.filter(_.size > 1 ).map(longNameWithMarker)
77-
78- private def shortAliases : Seq [String ] =
79- param.aliasNames.filter(_.size == 1 ).map(shortNameWithMarker)
80-
81- private def isLongName (name : String ): Boolean =
82- name.length > 1
83-
84- private def isShortName (name : String ): Boolean =
85- name.length == 1
70+ param.annotations.collect{ case a : Alias => a.aliases.map(getNameWithMarker) }.flatten
8671
8772 private def getNameWithMarker (name : String ): String =
88- if isLongName( name) then argMarker + name
89- else if isShortName( name) then shortArgMarker + name
73+ if name.length > 1 then s " -- $ name"
74+ else if name.length == 1 then s " - $ name"
9075 else assert(false , " invalid name" )
9176
92- private def longNameWithMarker (name : String ): String = argMarker + name
93- private def shortNameWithMarker (name : String ): String = shortArgMarker + name
94-
9577 def command (info : Info , args : Seq [String ]): Option [Seq [String ]] =
96- val canonicalNames = CanonicalNames (info)
97- canonicalNames.checkNames()
98- if Help .hasHelpArg(canonicalNames, args) then
78+ val names = Names (info)
79+ if Help .shouldPrintDefaultHelp(names, args) then
9980 Help .printUsage(info)
10081 Help .printExplain(info)
10182 None
10283 else
103- preProcessArgs(info, canonicalNames , args).orElse {
84+ preProcessArgs(info, names , args).orElse {
10485 Help .printUsage(info)
10586 None
10687 }
@@ -122,7 +103,7 @@ final class newMain extends MainAnnotation[FromString, Any]:
122103 def run (execProgram : () => Any ): Unit =
123104 if ! hasParseErrors then execProgram()
124105
125- private def preProcessArgs (info : Info , canonicalNames : CanonicalNames , args : Seq [String ]): Option [Seq [String ]] =
106+ private def preProcessArgs (info : Info , names : Names , args : Seq [String ]): Option [Seq [String ]] =
126107 var hasError : Boolean = false
127108 def error (msg : String ): Unit = {
128109 hasError = true
@@ -142,7 +123,7 @@ final class newMain extends MainAnnotation[FromString, Any]:
142123 case longArgRegex() | shortArgRegex() =>
143124 error(s " missing argument for ${name}" )
144125 case value =>
145- canonicalNames.getName (name) match
126+ names.canonicalName (name) match
146127 case Some (canonicalName) =>
147128 byNameArgs += ((canonicalName, value))
148129 case None =>
@@ -168,7 +149,7 @@ final class newMain extends MainAnnotation[FromString, Any]:
168149 byNameArgsMap.get(param.name) match
169150 case Some (byNameVarargs) => acc ::: byNameVarargs.toList ::: remainingArgs
170151 case None => acc ::: remainingArgs
171- else byNameArgsMap.get(param.name) match
152+ else byNameArgsMap.get(getNameWithMarker( param.name) ) match
172153 case Some (argValues) =>
173154 assert(argValues.nonEmpty, s " ${param.name} present in byNameArgsMap, but it has no argument value " )
174155 if argValues.length > 1 then
@@ -208,12 +189,12 @@ final class newMain extends MainAnnotation[FromString, Any]:
208189 /** The name of the special argument to display the method's help.
209190 * If one of the method's parameters is called the same, will be ignored.
210191 */
211- private inline val helpArg = " help"
192+ private inline val helpArg = " -- help"
212193
213194 /** The short name of the special argument to display the method's help.
214195 * If one of the method's parameters uses the same short name, will be ignored.
215196 */
216- private inline val shortHelpArg = 'h'
197+ private inline val shortHelpArg = " -h "
217198
218199 private inline val maxUsageLineLength = 120
219200
@@ -222,7 +203,7 @@ final class newMain extends MainAnnotation[FromString, Any]:
222203 for (param <- info.parameters)
223204 yield {
224205 val canonicalName = getNameWithMarker(param.name)
225- val namesPrint = (canonicalName +: param.longAliases ++: param.shortAliases ).mkString(" [" , " | " , " ]" )
206+ val namesPrint = (canonicalName +: param.aliasNames ).mkString(" [" , " | " , " ]" )
226207 val shortTypeName = param.typeName.split('.' ).last
227208 if param.isVarargs then s " [< $shortTypeName> [< $shortTypeName> [...]]] "
228209 else if param.hasDefault then s " [ $namesPrint < $shortTypeName>] "
@@ -276,7 +257,7 @@ final class newMain extends MainAnnotation[FromString, Any]:
276257 println(" Arguments:" )
277258 for param <- info.parameters do
278259 val canonicalName = getNameWithMarker(param.name)
279- val otherNames = ( param.longAliases ++ param.shortAliases) match {
260+ val otherNames = param.aliasNames match {
280261 case Seq () => " "
281262 case names => names.mkString(" (" , " , " , " ) " )
282263 }
@@ -297,59 +278,52 @@ final class newMain extends MainAnnotation[FromString, Any]:
297278 }
298279 end printExplain
299280
300- def hasHelpArg ( canonicalNames : CanonicalNames , args : Seq [String ]): Boolean =
301- val helpIsOverridden = canonicalNames.getName(argMarker + helpArg).isDefined
302- val shortHelpIsOverridden = canonicalNames.getShortName(shortArgMarker + shortHelpArg).isDefined
303- (! helpIsOverridden && args.contains(longNameWithMarker( helpArg) )) ||
304- (! shortHelpIsOverridden && args.contains(shortNameWithMarker( shortHelpArg.toString) ))
281+ def shouldPrintDefaultHelp ( names : Names , args : Seq [String ]): Boolean =
282+ val helpIsOverridden = names.canonicalName( helpArg).isDefined
283+ val shortHelpIsOverridden = names.canonicalName( shortHelpArg).isDefined
284+ (! helpIsOverridden && args.contains(helpArg)) ||
285+ (! shortHelpIsOverridden && args.contains(shortHelpArg))
305286
306287 end Help
307288
308- private class CanonicalNames (info : Info ):
309-
310- private val namesToCanonicalName : Map [String , String ] = info.parameters.flatMap(
311- param =>
312- val names = param.longAliases.map(_.drop(2 ))
313- val canonicalName = param.name
314- if isLongName(canonicalName) then (canonicalName +: names).map(_ -> canonicalName)
315- else names.map(_ -> canonicalName)
316- ).toMap
289+ private class Names (info : Info ):
317290
318- private val shortNamesToCanonicalName : Map [String , String ] = info.parameters.flatMap(
319- param =>
320- val names = param.shortAliases.map(_.drop(1 ))
321- val canonicalName = param.name
322- if isShortName(canonicalName) then (canonicalName +: names).map(_ -> canonicalName)
323- else names.map(_ -> canonicalName)
324- ).toMap
291+ checkNames()
325292
326- def getName (name : String ): Option [String ] = namesToCanonicalName.get(name.drop(2 )).orElse(getShortName(name))
293+ private lazy val namesToCanonicalName : Map [String , String ] =
294+ info.parameters.flatMap(param =>
295+ val canonicalName = getNameWithMarker(param.name)
296+ (canonicalName -> canonicalName) +: param.aliasNames.map(_ -> canonicalName)
297+ ).toMap
327298
328- def getShortName (name : String ): Option [String ] = shortNamesToCanonicalName .get(name.drop( 1 ) )
299+ def canonicalName (name : String ): Option [String ] = namesToCanonicalName .get(name)
329300
330- override def toString (): String =
331- s " CanonicalNames( $namesToCanonicalName, $shortNamesToCanonicalName) "
301+ override def toString (): String = s " Names( $namesToCanonicalName) "
332302
333- def checkNames (): Unit =
303+ private def checkNames (): Unit =
334304 def checkDuplicateNames () =
335305 val nameAndCanonicalName = info.parameters.flatMap { paramInfo =>
336- (getNameWithMarker(paramInfo.name) +: paramInfo.longAliases ++: paramInfo.shortAliases ).map(_ -> paramInfo.name)
306+ (getNameWithMarker(paramInfo.name) +: paramInfo.aliasNames ).map(_ -> paramInfo.name)
337307 }
338- val nameToCanonicalNames = nameAndCanonicalName.groupMap(_._1)(_._2)
339- for (name, canonicalNames) <- nameToCanonicalNames if canonicalNames.length > 1 do
308+ val nameToNames = nameAndCanonicalName.groupMap(_._1)(_._2)
309+ for (name, canonicalNames) <- nameToNames if canonicalNames.length > 1 do
340310 throw IllegalArgumentException (s " $name is used for multiple parameters: ${canonicalNames.mkString(" , " )}" )
341311 def checkValidNames () =
342312 def isValidArgName (name : String ): Boolean =
343- longArgRegex.matches(argMarker + name) || shortArgRegex.matches(shortArgMarker + name)
313+ longArgRegex.matches(s " -- $ name" ) || shortArgRegex.matches(s " - $ name" )
344314 for param <- info.parameters do
345315 if ! isValidArgName(param.name) then
346316 throw IllegalArgumentException (s " The following argument name is invalid: ${param.name}" )
347- for alias <- param.aliasNames if ! isValidArgName(alias) do
348- throw IllegalArgumentException (s " The following alias is invalid: $alias" )
317+ for annot <- param.annotations do
318+ annot match
319+ case alias : Alias =>
320+ for name <- alias.aliases if ! isValidArgName(name) do
321+ throw IllegalArgumentException (s " The following alias is invalid: $name" )
322+ case _ =>
349323
350324 checkValidNames()
351325 checkDuplicateNames()
352- end CanonicalNames
326+ end Names
353327
354328end newMain
355329
0 commit comments