@@ -635,6 +635,21 @@ trait Applications extends Compatibility {
635635
636636 inline def tailOf [A ](list : List [A ]): List [A ] = if list.isEmpty then list else list.tail // list.drop(1)
637637
638+ def hasDeprecatedName (pname : Name , other : Name , t : Trees .Tree [T ]): Boolean = ! ctx.isAfterTyper &&
639+ methRef.symbol.paramSymss.flatten.find(_.name == pname).flatMap(_.getAnnotation(defn.DeprecatedNameAnnot )).match
640+ case Some (annot) =>
641+ val name = annot.argumentConstantString(0 )
642+ val version = annot.argumentConstantString(1 ).filter(! _.isEmpty)
643+ val since = version.map(v => s " (since $v) " ).getOrElse(" " )
644+ name.map(_.toTermName) match
645+ case Some (`other`) =>
646+ report.deprecationWarning(em " the parameter name $other is deprecated $since: use $pname instead " , t.srcPos)
647+ case Some (`pname`) | None =>
648+ report.deprecationWarning(em " naming parameter $pname is deprecated $since" , t.srcPos)
649+ case _ =>
650+ true
651+ case _ => false
652+
638653 /** Reorder the suffix of named args per a list of required names.
639654 *
640655 * @param pnames The list of parameter names that are missing arguments
@@ -650,25 +665,32 @@ trait Applications extends Compatibility {
650665 */
651666 def handleNamed (pnames : List [Name ], args : List [Trees .Tree [T ]],
652667 nameToArg : Map [Name , Trees .NamedArg [T ]], toDrop : Set [Name ],
653- missingArgs : Boolean ): List [Trees .Tree [T ]] = pnames match
654- case pname :: pnames if nameToArg.contains(pname) =>
655- // there is a named argument for this parameter; pick it
656- nameToArg(pname) :: handleNamed(pnames, args, nameToArg - pname, toDrop + pname, missingArgs)
668+ missingArgs : Boolean ): List [Trees .Tree [T ]] =
669+ pnames match
670+ case pname :: pnames if nameToArg.contains(pname) => // use the named argument for this parameter
671+ val arg = nameToArg(pname)
672+ hasDeprecatedName(pname, nme.NO_NAME , arg)
673+ arg :: handleNamed(pnames, args, nameToArg - pname, toDrop + pname, missingArgs)
657674 case _ =>
658675 args match
659- case (arg @ NamedArg (aname, _)) :: args1 =>
660- if toDrop.contains(aname) // named argument is already passed
661- then handleNamed(pnames, args1, nameToArg, toDrop - aname, missingArgs)
662- else if nameToArg.contains(aname) && pnames.nonEmpty // argument is missing, pass an empty tree
663- then genericEmptyTree :: handleNamed(pnames.tail, args, nameToArg, toDrop, missingArgs = true )
676+ case allArgs @ (arg @ NamedArg (aname, _)) :: args =>
677+ if toDrop.contains(aname) then // named argument was already picked
678+ handleNamed(pnames, args, nameToArg, toDrop - aname, missingArgs)
679+ else if pnames.nonEmpty && nameToArg.contains(aname) then
680+ val pname = pnames.head
681+ if hasDeprecatedName(pname, aname, arg) then // name was deprecated alt, so try again with canonical name
682+ val parg = cpy.NamedArg (arg)(pname, arg.arg).asInstanceOf [Trees .NamedArg [T ]]
683+ handleNamed(pnames, parg :: args, nameToArg.removed(aname).updated(pname, parg), toDrop, missingArgs)
684+ else // argument for pname is missing, pass an empty tree
685+ genericEmptyTree :: handleNamed(pnames.tail, allArgs, nameToArg, toDrop, missingArgs = true )
664686 else // name not (or no longer) available for named arg
665687 def msg =
666688 if methodType.paramNames.contains(aname) then
667689 em " parameter $aname of $methString is already instantiated "
668690 else
669691 em " $methString does not have a parameter $aname"
670692 fail(msg, arg.asInstanceOf [Arg ])
671- arg :: handleNamed(tailOf(pnames), args1 , nameToArg, toDrop, missingArgs)
693+ arg :: handleNamed(tailOf(pnames), args , nameToArg, toDrop, missingArgs)
672694 case arg :: args =>
673695 if toDrop.nonEmpty || missingArgs then
674696 report.error(i " positional after named argument " , arg.srcPos)
@@ -680,8 +702,10 @@ trait Applications extends Compatibility {
680702 /** Skip prefix of positional args, then handleNamed */
681703 def handlePositional (pnames : List [Name ], args : List [Trees .Tree [T ]]): List [Trees .Tree [T ]] =
682704 args match
705+ case (arg @ NamedArg (name, _)) :: args if ! pnames.isEmpty && pnames.head == name =>
706+ hasDeprecatedName(name, nme.NO_NAME , arg)
707+ arg :: handlePositional(pnames.tail, args)
683708 case (_ : NamedArg ) :: _ =>
684- // val nameAssocs = for case arg @ NamedArg(name, _) <- args yield (name, arg)
685709 val nameAssocs = args.collect { case arg @ NamedArg (name, _) => name -> arg }
686710 handleNamed(pnames, args, nameAssocs.toMap, toDrop = Set .empty, missingArgs = false )
687711 case arg :: args =>
0 commit comments