@@ -600,12 +600,17 @@ trait Applications extends Compatibility {
600
600
* - "does not have parameter" if a named parameter does not mention a formal
601
601
* parameter name.
602
602
*/
603
- def reorder [T <: Untyped ](args : List [Trees .Tree [T ]]): List [Trees .Tree [T ]] = {
603
+ def reorder [T <: Untyped ](args : List [Trees .Tree [T ]]): List [Trees .Tree [T ]] =
604
604
605
- /** @param pnames The list of parameter names that are missing arguments
605
+ inline def tailOf [A ](list : List [A ]): List [A ] = if list.isEmpty then list else list.tail // list.drop(1)
606
+
607
+ /** Reorder the suffix of named args per a list of required names.
608
+ *
609
+ * @param pnames The list of parameter names that are missing arguments
606
610
* @param args The list of arguments that are not yet passed, or that are waiting to be dropped
607
611
* @param nameToArg A map from as yet unseen names to named arguments
608
- * @param toDrop A set of names that have already be passed as named arguments
612
+ * @param toDrop A set of names that have already been passed as named arguments
613
+ * @param missingArgs true if args were already missing, so error on positional
609
614
*
610
615
* For a well-typed application we have the invariants
611
616
*
@@ -614,49 +619,46 @@ trait Applications extends Compatibility {
614
619
*/
615
620
def handleNamed (pnames : List [Name ], args : List [Trees .Tree [T ]],
616
621
nameToArg : Map [Name , Trees .NamedArg [T ]], toDrop : Set [Name ],
617
- missingArgs : Boolean ): List [Trees .Tree [T ]] = pnames match {
618
- case pname :: pnames1 if nameToArg contains pname =>
622
+ missingArgs : Boolean ): List [Trees .Tree [T ]] = pnames match
623
+ case pname :: pnames if nameToArg. contains( pname) =>
619
624
// there is a named argument for this parameter; pick it
620
- nameToArg(pname) :: handleNamed(pnames1 , args, nameToArg - pname, toDrop + pname, missingArgs)
625
+ nameToArg(pname) :: handleNamed(pnames , args, nameToArg - pname, toDrop + pname, missingArgs)
621
626
case _ =>
622
- def pnamesRest = if (pnames.isEmpty) pnames else pnames.tail
623
- args match {
627
+ args match
624
628
case (arg @ NamedArg (aname, _)) :: args1 =>
625
- if ( toDrop contains aname) // argument is already passed
626
- handleNamed(pnames, args1, nameToArg, toDrop - aname, missingArgs)
627
- else if (( nameToArg contains aname) && pnames.nonEmpty) // argument is missing, pass an empty tree
628
- genericEmptyTree :: handleNamed(pnames.tail, args, nameToArg, toDrop, missingArgs = true )
629
- else { // name not (or no longer) available for named arg
629
+ if toDrop. contains( aname) // named argument is already passed
630
+ then handleNamed(pnames, args1, nameToArg, toDrop - aname, missingArgs)
631
+ else if nameToArg. contains( aname) && pnames.nonEmpty // argument is missing, pass an empty tree
632
+ then genericEmptyTree :: handleNamed(pnames.tail, args, nameToArg, toDrop, missingArgs = true )
633
+ else // name not (or no longer) available for named arg
630
634
def msg =
631
- if ( methodType.paramNames contains aname)
635
+ if methodType.paramNames. contains( aname) then
632
636
em " parameter $aname of $methString is already instantiated "
633
637
else
634
638
em " $methString does not have a parameter $aname"
635
639
fail(msg, arg.asInstanceOf [Arg ])
636
- arg :: handleNamed(pnamesRest, args1, nameToArg, toDrop, missingArgs)
637
- }
638
- case arg :: args1 =>
640
+ arg :: handleNamed(tailOf(pnames), args1, nameToArg, toDrop, missingArgs)
641
+ case arg :: args =>
639
642
if toDrop.nonEmpty || missingArgs then
640
643
report.error(i " positional after named argument " , arg.srcPos)
641
- arg :: handleNamed(pnamesRest, args1, nameToArg, toDrop, missingArgs) // unnamed argument; pick it
642
- case Nil => // no more args, continue to pick up any preceding named args
643
- if (pnames.isEmpty) Nil
644
- else handleNamed(pnamesRest, args, nameToArg, toDrop, missingArgs)
645
- }
646
- }
644
+ arg :: handleNamed(tailOf(pnames), args, nameToArg, toDrop, missingArgs) // unnamed argument; pick it
645
+ case nil => // no more args, continue to pick up any preceding named args
646
+ if pnames.isEmpty then nil
647
+ else handleNamed(tailOf(pnames), nil, nameToArg, toDrop, missingArgs)
647
648
649
+ /** Skip prefix of positional args, then handleNamed */
648
650
def handlePositional (pnames : List [Name ], args : List [Trees .Tree [T ]]): List [Trees .Tree [T ]] =
649
- args match {
650
- case (arg : NamedArg @ unchecked ) :: _ =>
651
- val nameAssocs = for ( case arg @ NamedArg (name, _) <- args) yield (name, arg)
652
- handleNamed(pnames, args, nameAssocs.toMap, toDrop = Set (), missingArgs = false )
653
- case arg :: args1 =>
654
- arg :: handlePositional( if (pnames.isEmpty) Nil else pnames.tail, args1)
655
- case Nil => Nil
656
- }
651
+ args match
652
+ case (_ : NamedArg ) :: _ =>
653
+ // val nameAssocs = for case arg @ NamedArg(name, _) <- args yield (name, arg)
654
+ val nameAssocs = args.collect { case arg @ NamedArg (name, _) => name -> arg }
655
+ handleNamed(pnames, args, nameAssocs.toMap, toDrop = Set .empty, missingArgs = false )
656
+ case arg :: args =>
657
+ arg :: handlePositional(tailOf(pnames), args)
658
+ case nil => nil
657
659
658
660
handlePositional(methodType.paramNames, args)
659
- }
661
+ end reorder
660
662
661
663
/** Is `sym` a constructor of a Java-defined annotation? */
662
664
def isJavaAnnotConstr (sym : Symbol ): Boolean =
0 commit comments