@@ -62,45 +62,26 @@ final class newMain extends MainAnnotation[FromString, Any]:
62
62
import newMain ._
63
63
import MainAnnotation ._
64
64
65
- private inline val argMarker = " --"
66
- private inline val shortArgMarker = " -"
67
-
68
65
private val longArgRegex = " --[a-zA-Z][a-zA-Z0-9]+" .r
69
66
private val shortArgRegex = " -[a-zA-Z]" .r
70
67
71
68
extension (param : Parameter )
72
69
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
86
71
87
72
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"
90
75
else assert(false , " invalid name" )
91
76
92
- private def longNameWithMarker (name : String ): String = argMarker + name
93
- private def shortNameWithMarker (name : String ): String = shortArgMarker + name
94
-
95
77
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
99
80
Help .printUsage(info)
100
81
Help .printExplain(info)
101
82
None
102
83
else
103
- preProcessArgs(info, canonicalNames , args).orElse {
84
+ preProcessArgs(info, names , args).orElse {
104
85
Help .printUsage(info)
105
86
None
106
87
}
@@ -122,7 +103,7 @@ final class newMain extends MainAnnotation[FromString, Any]:
122
103
def run (execProgram : () => Any ): Unit =
123
104
if ! hasParseErrors then execProgram()
124
105
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 ]] =
126
107
var hasError : Boolean = false
127
108
def error (msg : String ): Unit = {
128
109
hasError = true
@@ -142,7 +123,7 @@ final class newMain extends MainAnnotation[FromString, Any]:
142
123
case longArgRegex() | shortArgRegex() =>
143
124
error(s " missing argument for ${name}" )
144
125
case value =>
145
- canonicalNames.getName (name) match
126
+ names.canonicalName (name) match
146
127
case Some (canonicalName) =>
147
128
byNameArgs += ((canonicalName, value))
148
129
case None =>
@@ -168,7 +149,7 @@ final class newMain extends MainAnnotation[FromString, Any]:
168
149
byNameArgsMap.get(param.name) match
169
150
case Some (byNameVarargs) => acc ::: byNameVarargs.toList ::: remainingArgs
170
151
case None => acc ::: remainingArgs
171
- else byNameArgsMap.get(param.name) match
152
+ else byNameArgsMap.get(getNameWithMarker( param.name) ) match
172
153
case Some (argValues) =>
173
154
assert(argValues.nonEmpty, s " ${param.name} present in byNameArgsMap, but it has no argument value " )
174
155
if argValues.length > 1 then
@@ -208,12 +189,12 @@ final class newMain extends MainAnnotation[FromString, Any]:
208
189
/** The name of the special argument to display the method's help.
209
190
* If one of the method's parameters is called the same, will be ignored.
210
191
*/
211
- private inline val helpArg = " help"
192
+ private inline val helpArg = " -- help"
212
193
213
194
/** The short name of the special argument to display the method's help.
214
195
* If one of the method's parameters uses the same short name, will be ignored.
215
196
*/
216
- private inline val shortHelpArg = 'h'
197
+ private inline val shortHelpArg = " -h "
217
198
218
199
private inline val maxUsageLineLength = 120
219
200
@@ -222,7 +203,7 @@ final class newMain extends MainAnnotation[FromString, Any]:
222
203
for (param <- info.parameters)
223
204
yield {
224
205
val canonicalName = getNameWithMarker(param.name)
225
- val namesPrint = (canonicalName +: param.longAliases ++: param.shortAliases ).mkString(" [" , " | " , " ]" )
206
+ val namesPrint = (canonicalName +: param.aliasNames ).mkString(" [" , " | " , " ]" )
226
207
val shortTypeName = param.typeName.split('.' ).last
227
208
if param.isVarargs then s " [< $shortTypeName> [< $shortTypeName> [...]]] "
228
209
else if param.hasDefault then s " [ $namesPrint < $shortTypeName>] "
@@ -276,7 +257,7 @@ final class newMain extends MainAnnotation[FromString, Any]:
276
257
println(" Arguments:" )
277
258
for param <- info.parameters do
278
259
val canonicalName = getNameWithMarker(param.name)
279
- val otherNames = ( param.longAliases ++ param.shortAliases) match {
260
+ val otherNames = param.aliasNames match {
280
261
case Seq () => " "
281
262
case names => names.mkString(" (" , " , " , " ) " )
282
263
}
@@ -297,59 +278,52 @@ final class newMain extends MainAnnotation[FromString, Any]:
297
278
}
298
279
end printExplain
299
280
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))
305
286
306
287
end Help
307
288
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 ):
317
290
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()
325
292
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
327
298
328
- def getShortName (name : String ): Option [String ] = shortNamesToCanonicalName .get(name.drop( 1 ) )
299
+ def canonicalName (name : String ): Option [String ] = namesToCanonicalName .get(name)
329
300
330
- override def toString (): String =
331
- s " CanonicalNames( $namesToCanonicalName, $shortNamesToCanonicalName) "
301
+ override def toString (): String = s " Names( $namesToCanonicalName) "
332
302
333
- def checkNames (): Unit =
303
+ private def checkNames (): Unit =
334
304
def checkDuplicateNames () =
335
305
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)
337
307
}
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
340
310
throw IllegalArgumentException (s " $name is used for multiple parameters: ${canonicalNames.mkString(" , " )}" )
341
311
def checkValidNames () =
342
312
def isValidArgName (name : String ): Boolean =
343
- longArgRegex.matches(argMarker + name) || shortArgRegex.matches(shortArgMarker + name)
313
+ longArgRegex.matches(s " -- $ name" ) || shortArgRegex.matches(s " - $ name" )
344
314
for param <- info.parameters do
345
315
if ! isValidArgName(param.name) then
346
316
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 _ =>
349
323
350
324
checkValidNames()
351
325
checkDuplicateNames()
352
- end CanonicalNames
326
+ end Names
353
327
354
328
end newMain
355
329
0 commit comments