@@ -529,50 +529,104 @@ trait Applications extends Compatibility {
529
529
* 1. `(args diff toDrop)` can be reordered to match `pnames`
530
530
* 2. For every `(name -> arg)` in `nameToArg`, `arg` is an element of `args`
531
531
*/
532
- def handleNamed (pnames : List [Name ], args : List [Trees .Tree [T ]],
533
- nameToArg : Map [Name , Trees .NamedArg [T ]], toDrop : Set [Name ],
534
- missingArgs : Boolean ): List [Trees .Tree [T ]] = pnames match {
535
- case pname :: pnames1 if nameToArg contains pname =>
536
- // there is a named argument for this parameter; pick it
537
- nameToArg(pname) :: handleNamed(pnames1, args, nameToArg - pname, toDrop + pname, missingArgs)
538
- case _ =>
539
- def pnamesRest = if (pnames.isEmpty) pnames else pnames.tail
540
- args match {
541
- case (arg @ NamedArg (aname, _)) :: args1 =>
542
- if (toDrop contains aname) // argument is already passed
543
- handleNamed(pnames, args1, nameToArg, toDrop - aname, missingArgs)
544
- else if ((nameToArg contains aname) && pnames.nonEmpty) // argument is missing, pass an empty tree
545
- genericEmptyTree :: handleNamed(pnames.tail, args, nameToArg, toDrop, missingArgs = true )
546
- else { // name not (or no longer) available for named arg
547
- def msg =
548
- if (methodType.paramNames contains aname)
549
- em " parameter $aname of $methString is already instantiated "
550
- else
551
- em " $methString does not have a parameter $aname"
552
- fail(msg, arg.asInstanceOf [Arg ])
553
- arg :: handleNamed(pnamesRest, args1, nameToArg, toDrop, missingArgs)
554
- }
555
- case arg :: args1 =>
556
- if toDrop.nonEmpty || missingArgs then
557
- report.error(i " positional after named argument " , arg.srcPos)
558
- arg :: handleNamed(pnamesRest, args1, nameToArg, toDrop, missingArgs) // unnamed argument; pick it
559
- case Nil => // no more args, continue to pick up any preceding named args
560
- if (pnames.isEmpty) Nil
561
- else handleNamed(pnamesRest, args, nameToArg, toDrop, missingArgs)
562
- }
563
- }
564
-
565
- def handlePositional (pnames : List [Name ], args : List [Trees .Tree [T ]]): List [Trees .Tree [T ]] =
566
- args match {
567
- case (arg : NamedArg @ unchecked) :: _ =>
568
- val nameAssocs = for (case arg @ NamedArg (name, _) <- args) yield (name, arg)
569
- handleNamed(pnames, args, nameAssocs.toMap, toDrop = Set (), missingArgs = false )
532
+ def handleNamed (names : List [(Name , Option [(Name , Annotation )])], args : List [Trees .Tree [T ]],
533
+ nameToArg : Map [Name , Trees .NamedArg [T ]], toDrop : Set [Name ], missingArgs : Boolean ): List [Trees .Tree [T ]] =
534
+
535
+ /** Returns the corresponding name parameter with the name that helped find it */
536
+ def findNameArgument (pname : (Name , Option [(Name , Annotation )])): Option [(Name , Trees .NamedArg [T ])] =
537
+ pname._2 match
538
+ // This parameter has a deprecated name, looking for this first
539
+ case Some (name, annot) => nameToArg.get(name) match
540
+ // Argument with a deprecated name was found: emit a warning and change the parameter name
541
+ case Some (arg) =>
542
+ // println(i"${arg.srcPos}")
543
+ val sinceMsg = annot.argumentConstantString(1 ).map(version => s " (since: $version) " ).getOrElse(" " )
544
+ report.deprecationWarning(em " naming parameter $name is deprecated $sinceMsg" , arg.srcPos)
545
+ Some ((name, arg))
546
+ // fallback to the primary name
547
+ case None => nameToArg.get(pname._1).map((pname._1, _))
548
+ // no-deprecated name, we can look for the argument with the main name
549
+ case None => nameToArg.get(pname._1).map((pname._1, _))
550
+ end findNameArgument
551
+
552
+ names match
553
+ case pname :: pnames =>
554
+ findNameArgument(pname) match
555
+ // named argument was found, move on to the next parameter
556
+ case Some ((name, arg)) =>
557
+ val namesToDrop = pname._2.map(_._1).toSet + pname._1 // drop both the deprecated and the primary name
558
+ arg :: handleNamed(pnames, args, nameToArg - name, toDrop ++ namesToDrop, missingArgs)
559
+ case None => args match
560
+ case (arg @ NamedArg (name, _)) :: args1 =>
561
+ if toDrop.contains(name) then
562
+ handleNamed(names, args1, nameToArg, toDrop - name, missingArgs)
563
+ else if nameToArg.contains(name) && pnames.nonEmpty then // an argument is missing, pass an empty tree
564
+ genericEmptyTree :: handleNamed(pnames, args, nameToArg, toDrop, missingArgs = true )
565
+ else
566
+ def msg =
567
+ if methodType.paramNames contains name then
568
+ em " parameter $name of $methString is already instantiated "
569
+ else
570
+ em " $methString does not have a parameter $name"
571
+ fail(msg, arg.asInstanceOf [Arg ])
572
+ arg :: handleNamed(pnames, args1, nameToArg, toDrop, missingArgs)
573
+ case arg :: args1 =>
574
+ if toDrop.nonEmpty || missingArgs then
575
+ report.error(em " positional after named argument " , arg.srcPos)
576
+ arg :: handleNamed(pnames, args1, nameToArg, toDrop, missingArgs) // unnamed argument; pick it
577
+ // no more args, continue to pick up any preceding named args
578
+ case Nil =>
579
+ if pnames.isEmpty then Nil else handleNamed(pnames, args, nameToArg, toDrop, missingArgs)
580
+ case Nil => args match
581
+ case (arg @ NamedArg (name, _)) :: args1 =>
582
+ if toDrop.contains(name) then
583
+ handleNamed(names, args1, nameToArg, toDrop - name, missingArgs)
584
+ else
585
+ def msg =
586
+ if methodType.paramNames contains name then
587
+ em " parameter $name of $methString is already instantiated "
588
+ else
589
+ em " $methString does not have a parameter $name"
590
+ fail(msg, arg.asInstanceOf [Arg ])
591
+ arg :: handleNamed(Nil , args1, nameToArg, toDrop, missingArgs)
592
+ case arg :: args1 =>
593
+ if toDrop.nonEmpty || missingArgs then
594
+ report.error(em " positional after named argument " , arg.srcPos)
595
+ arg :: handleNamed(Nil , args1, nameToArg, toDrop, missingArgs) // unnamed argument; pick it
596
+ case Nil => Nil // processed all the parameters and all the arguments
597
+ Nil
598
+ end handleNamed
599
+
600
+ def handlePositional (names : List [(Name , Option [(Name , Annotation )])], args : List [Trees .Tree [T ]]): List [Trees .Tree [T ]] =
601
+ args match
602
+ // Named argument, switch to handleNamed processing
603
+ case (_ : NamedArg @ unchecked) :: _ =>
604
+ val nameAssocs = for case arg @ NamedArg (name, _) <- args yield (name, arg)
605
+ handleNamed(names, args, nameAssocs.toMap, toDrop = Set (), missingArgs = false )
606
+ // Positional argument, skip it and move to the next one
570
607
case arg :: args1 =>
571
- arg :: handlePositional(if (pnames .isEmpty) Nil else pnames .tail, args1)
608
+ arg :: handlePositional(if names .isEmpty then Nil else names .tail, args1)
572
609
case Nil => Nil
573
- }
610
+ end handlePositional
611
+
612
+ // format: (primary_name, (deprecated_name, annotation): Option)
613
+ // NB: deprecated_name might be different from (or the same as) primary_name
614
+ // names also has the same order as the parameter list
615
+ val names =
616
+ for p <- methRef.symbol.paramSymss.flatten
617
+ if methodType.paramNames.contains(p.name)
618
+ yield
619
+ p.getAnnotation(defn.DeprecatedNameAnnot ) match
620
+ case Some (annot) =>
621
+ // Get the name of the deprecated
622
+ val deprecated = annot.argumentConstantString(0 ).map(_.toTermName).getOrElse(p.name)
623
+ (p.name, Some (deprecated, annot))
624
+ case None =>
625
+ (p.name, None )
626
+ end names
627
+
628
+ handlePositional(names, args)
574
629
575
- handlePositional(methodType.paramNames, args)
576
630
}
577
631
578
632
/** Is `sym` a constructor of a Java-defined annotation? */
0 commit comments