@@ -604,6 +604,21 @@ trait Applications extends Compatibility {
604604
605605 inline def tailOf [A ](list : List [A ]): List [A ] = if list.isEmpty then list else list.tail // list.drop(1)
606606
607+ def hasDeprecatedName (pname : Name , other : Name , t : Trees .Tree [T ]): Boolean = ! ctx.isAfterTyper &&
608+ methRef.symbol.paramSymss.flatten.find(_.name == pname).flatMap(_.getAnnotation(defn.DeprecatedNameAnnot )).match
609+ case Some (annot) =>
610+ val name = annot.argumentConstantString(0 )
611+ val version = annot.argumentConstantString(1 ).filter(! _.isEmpty)
612+ val since = version.map(v => s " (since $v) " ).getOrElse(" " )
613+ name.map(_.toTermName) match
614+ case Some (`other`) =>
615+ report.deprecationWarning(em " the parameter name $other is deprecated $since: use $pname instead " , t.srcPos)
616+ case Some (`pname`) | None =>
617+ report.deprecationWarning(em " naming parameter $pname is deprecated $since" , t.srcPos)
618+ case _ =>
619+ true
620+ case _ => false
621+
607622 /** Reorder the suffix of named args per a list of required names.
608623 *
609624 * @param pnames The list of parameter names that are missing arguments
@@ -619,25 +634,32 @@ trait Applications extends Compatibility {
619634 */
620635 def handleNamed (pnames : List [Name ], args : List [Trees .Tree [T ]],
621636 nameToArg : Map [Name , Trees .NamedArg [T ]], toDrop : Set [Name ],
622- missingArgs : Boolean ): List [Trees .Tree [T ]] = pnames match
623- case pname :: pnames if nameToArg.contains(pname) =>
624- // there is a named argument for this parameter; pick it
625- nameToArg(pname) :: handleNamed(pnames, args, nameToArg - pname, toDrop + pname, missingArgs)
637+ missingArgs : Boolean ): List [Trees .Tree [T ]] =
638+ pnames match
639+ case pname :: pnames if nameToArg.contains(pname) => // use the named argument for this parameter
640+ val arg = nameToArg(pname)
641+ hasDeprecatedName(pname, nme.NO_NAME , arg)
642+ arg :: handleNamed(pnames, args, nameToArg - pname, toDrop + pname, missingArgs)
626643 case _ =>
627644 args match
628- case (arg @ NamedArg (aname, _)) :: args1 =>
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 )
645+ case allArgs @ (arg @ NamedArg (aname, _)) :: args =>
646+ if toDrop.contains(aname) then // named argument was already picked
647+ handleNamed(pnames, args, nameToArg, toDrop - aname, missingArgs)
648+ else if pnames.nonEmpty && nameToArg.contains(aname) then
649+ val pname = pnames.head
650+ if hasDeprecatedName(pname, aname, arg) then // name was deprecated alt, so try again with canonical name
651+ val parg = cpy.NamedArg (arg)(pname, arg.arg).asInstanceOf [Trees .NamedArg [T ]]
652+ handleNamed(pnames, parg :: args, nameToArg.removed(aname).updated(pname, parg), toDrop, missingArgs)
653+ else // argument for pname is missing, pass an empty tree
654+ genericEmptyTree :: handleNamed(pnames.tail, allArgs, nameToArg, toDrop, missingArgs = true )
633655 else // name not (or no longer) available for named arg
634656 def msg =
635657 if methodType.paramNames.contains(aname) then
636658 em " parameter $aname of $methString is already instantiated "
637659 else
638660 em " $methString does not have a parameter $aname"
639661 fail(msg, arg.asInstanceOf [Arg ])
640- arg :: handleNamed(tailOf(pnames), args1 , nameToArg, toDrop, missingArgs)
662+ arg :: handleNamed(tailOf(pnames), args , nameToArg, toDrop, missingArgs)
641663 case arg :: args =>
642664 if toDrop.nonEmpty || missingArgs then
643665 report.error(i " positional after named argument " , arg.srcPos)
@@ -649,8 +671,10 @@ trait Applications extends Compatibility {
649671 /** Skip prefix of positional args, then handleNamed */
650672 def handlePositional (pnames : List [Name ], args : List [Trees .Tree [T ]]): List [Trees .Tree [T ]] =
651673 args match
674+ case (arg @ NamedArg (name, _)) :: args if ! pnames.isEmpty && pnames.head == name =>
675+ hasDeprecatedName(name, nme.NO_NAME , arg)
676+ arg :: handlePositional(pnames.tail, args)
652677 case (_ : NamedArg ) :: _ =>
653- // val nameAssocs = for case arg @ NamedArg(name, _) <- args yield (name, arg)
654678 val nameAssocs = args.collect { case arg @ NamedArg (name, _) => name -> arg }
655679 handleNamed(pnames, args, nameAssocs.toMap, toDrop = Set .empty, missingArgs = false )
656680 case arg :: args =>
0 commit comments