@@ -538,75 +538,73 @@ trait NamesDefaults { self: Analyzer =>
538
538
}
539
539
}
540
540
541
- /**
542
- * Removes name assignments from args. Additionally, returns an array mapping
543
- * argument indices from call-site-order to definition-site-order.
541
+ /** Removes name assignments from args. Additionally, returns an array mapping
542
+ * argument indices from call-site-order to definition-site-order.
544
543
*
545
- * Verifies that names are not specified twice, positional args don't appear
546
- * after named ones.
544
+ * Verifies that names are not specified twice, and positional args don't appear after named ones.
547
545
*/
548
546
def removeNames (typer : Typer )(args : List [Tree ], params : List [Symbol ]): (List [Tree ], Array [Int ]) = {
549
547
implicit val context0 = typer.context
550
- // maps indices from (order written by user) to (order of definition)
551
- val argPos = Array .fill(args.length)(- 1 )
552
- var positionalAllowed = true
553
- val namelessArgs = mapWithIndex(args) { (arg, argIndex) =>
554
- arg match {
555
- case arg @ AssignOrNamedArg (Ident (name), rhs) =>
556
- def matchesName (param : Symbol ) = {
557
- def checkDeprecation (anonOK : Boolean ) =
558
- when (param.deprecatedParamName) {
559
- case Some (`name`) => true
560
- case Some (nme.NO_NAME ) => anonOK
561
- }
562
- def checkName = {
563
- val res = param.name == name
564
- if (res && checkDeprecation(true ))
565
- context0.deprecationWarning(arg.pos, param, s " naming parameter $name has been deprecated. " )
566
- res
567
- }
568
- def checkAltName = {
569
- val res = checkDeprecation(false )
570
- if (res) context0.deprecationWarning(arg.pos, param,
571
- s " the parameter name $name has been deprecated. Use ${param.name} instead. " )
572
- res
573
- }
574
- ! param.isSynthetic && (checkName || checkAltName)
575
- }
576
- val paramPos = params indexWhere matchesName
577
- if (paramPos == - 1 ) {
578
- if (positionalAllowed) {
579
- argPos(argIndex) = argIndex
580
- // prevent isNamed from being true when calling doTypedApply recursively,
581
- // treat the arg as an assignment of type Unit
582
- Assign (arg.lhs, rhs) setPos arg.pos
583
- }
584
- else UnknownParameterNameNamesDefaultError (arg, name)
585
- }
586
- else if (argPos contains paramPos) {
548
+ def matchesName (param : Symbol , name : Name , argIndex : Int ) = {
549
+ def warn (w : String ) = context0.deprecationWarning(args(argIndex).pos, param, w)
550
+ def checkDeprecation (anonOK : Boolean ) =
551
+ when (param.deprecatedParamName) {
552
+ case Some (`name`) => true
553
+ case Some (nme.NO_NAME ) => anonOK
554
+ }
555
+ def checkName = {
556
+ val res = param.name == name
557
+ if (res && checkDeprecation(true )) warn(s " naming parameter $name has been deprecated. " )
558
+ res
559
+ }
560
+ def checkAltName = {
561
+ val res = checkDeprecation(false )
562
+ if (res) warn(s " the parameter name $name has been deprecated. Use ${param.name} instead. " )
563
+ res
564
+ }
565
+ ! param.isSynthetic && (checkName || checkAltName)
566
+ }
567
+ // argPos maps indices from (order written by user) to (order of definition)
568
+ val argPos = Array .fill(args.length)(- 1 )
569
+ val namelessArgs = {
570
+ var positionalAllowed = true
571
+ def stripNamedArg (arg : AssignOrNamedArg , argIndex : Int ): Tree = {
572
+ val AssignOrNamedArg (Ident (name), rhs) = arg
573
+ params indexWhere (p => matchesName(p, name, argIndex)) match {
574
+ case - 1 if positionalAllowed =>
575
+ // prevent isNamed from being true when calling doTypedApply recursively,
576
+ // treat the arg as an assignment of type Unit
577
+ Assign (arg.lhs, rhs) setPos arg.pos
578
+ case - 1 =>
579
+ UnknownParameterNameNamesDefaultError (arg, name)
580
+ case paramPos if argPos contains paramPos =>
587
581
val existingArgIndex = argPos.indexWhere(_ == paramPos)
588
- val otherName = args(paramPos) match {
589
- case AssignOrNamedArg (Ident (oName), rhs) if oName != name => Some (oName)
590
- case _ => None
582
+ val otherName = Some (args(paramPos)) collect {
583
+ case AssignOrNamedArg (Ident (oName), _) if oName != name => oName
591
584
}
592
585
DoubleParamNamesDefaultError (arg, name, existingArgIndex+ 1 , otherName)
593
- } else if ( isAmbiguousAssignment(typer, params(paramPos), arg))
586
+ case paramPos if isAmbiguousAssignment(typer, params(paramPos), arg) =>
594
587
AmbiguousReferenceInNamesDefaultError (arg, name)
595
- else {
596
- // if the named argument is on the original parameter
597
- // position, positional after named is allowed.
598
- if (argIndex != paramPos)
599
- positionalAllowed = false
600
- argPos(argIndex) = paramPos
588
+ case paramPos if paramPos != argIndex =>
589
+ positionalAllowed = false // named arg is not in original parameter order: require names after this
590
+ argPos(argIndex) = paramPos // fix up the arg position
601
591
rhs
602
- }
603
- case _ =>
604
- argPos(argIndex) = argIndex
605
- if (positionalAllowed) arg
606
- else PositionalAfterNamedNamesDefaultError (arg)
592
+ case _ => rhs
593
+ }
594
+ }
595
+ mapWithIndex(args) {
596
+ case (arg : AssignOrNamedArg , argIndex) =>
597
+ val t = stripNamedArg(arg, argIndex)
598
+ if (! t.isErroneous && argPos(argIndex) < 0 ) argPos(argIndex) = argIndex
599
+ t
600
+ case (arg, argIndex) =>
601
+ if (positionalAllowed) {
602
+ argPos(argIndex) = argIndex
603
+ arg
604
+ } else
605
+ PositionalAfterNamedNamesDefaultError (arg)
607
606
}
608
607
}
609
-
610
608
(namelessArgs, argPos)
611
609
}
612
610
}
0 commit comments