Skip to content

Commit

Permalink
Cleanup of reorder
Browse files Browse the repository at this point in the history
  • Loading branch information
som-snytt committed Feb 17, 2025
1 parent 41d4762 commit 262fcdf
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 32 deletions.
1 change: 1 addition & 0 deletions compiler/src/dotty/tools/dotc/core/Definitions.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1029,6 +1029,7 @@ class Definitions {
@tu lazy val DeprecatedAnnot: ClassSymbol = requiredClass("scala.deprecated")
@tu lazy val DeprecatedOverridingAnnot: ClassSymbol = requiredClass("scala.deprecatedOverriding")
@tu lazy val DeprecatedInheritanceAnnot: ClassSymbol = requiredClass("scala.deprecatedInheritance")
@tu lazy val DeprecatedNameAnnot: ClassSymbol = requiredClass("scala.deprecatedName")
@tu lazy val ImplicitAmbiguousAnnot: ClassSymbol = requiredClass("scala.annotation.implicitAmbiguous")
@tu lazy val ImplicitNotFoundAnnot: ClassSymbol = requiredClass("scala.annotation.implicitNotFound")
@tu lazy val InlineParamAnnot: ClassSymbol = requiredClass("scala.annotation.internal.InlineParam")
Expand Down
66 changes: 34 additions & 32 deletions compiler/src/dotty/tools/dotc/typer/Applications.scala
Original file line number Diff line number Diff line change
Expand Up @@ -631,12 +631,17 @@ trait Applications extends Compatibility {
* - "does not have parameter" if a named parameter does not mention a formal
* parameter name.
*/
def reorder[T <: Untyped](args: List[Trees.Tree[T]]): List[Trees.Tree[T]] = {
def reorder[T <: Untyped](args: List[Trees.Tree[T]]): List[Trees.Tree[T]] =

/** @param pnames The list of parameter names that are missing arguments
inline def tailOf[A](list: List[A]): List[A] = if list.isEmpty then list else list.tail // list.drop(1)

/** Reorder the suffix of named args per a list of required names.
*
* @param pnames The list of parameter names that are missing arguments
* @param args The list of arguments that are not yet passed, or that are waiting to be dropped
* @param nameToArg A map from as yet unseen names to named arguments
* @param toDrop A set of names that have already be passed as named arguments
* @param toDrop A set of names that have already been passed as named arguments
* @param missingArgs true if args were already missing, so error on positional
*
* For a well-typed application we have the invariants
*
Expand All @@ -645,49 +650,46 @@ trait Applications extends Compatibility {
*/
def handleNamed(pnames: List[Name], args: List[Trees.Tree[T]],
nameToArg: Map[Name, Trees.NamedArg[T]], toDrop: Set[Name],
missingArgs: Boolean): List[Trees.Tree[T]] = pnames match {
case pname :: pnames1 if nameToArg contains pname =>
missingArgs: Boolean): List[Trees.Tree[T]] = pnames match
case pname :: pnames if nameToArg.contains(pname) =>
// there is a named argument for this parameter; pick it
nameToArg(pname) :: handleNamed(pnames1, args, nameToArg - pname, toDrop + pname, missingArgs)
nameToArg(pname) :: handleNamed(pnames, args, nameToArg - pname, toDrop + pname, missingArgs)
case _ =>
def pnamesRest = if (pnames.isEmpty) pnames else pnames.tail
args match {
args match
case (arg @ NamedArg(aname, _)) :: args1 =>
if (toDrop contains aname) // argument is already passed
handleNamed(pnames, args1, nameToArg, toDrop - aname, missingArgs)
else if ((nameToArg contains aname) && pnames.nonEmpty) // argument is missing, pass an empty tree
genericEmptyTree :: handleNamed(pnames.tail, args, nameToArg, toDrop, missingArgs = true)
else { // name not (or no longer) available for named arg
if toDrop.contains(aname) // named argument is already passed
then handleNamed(pnames, args1, nameToArg, toDrop - aname, missingArgs)
else if nameToArg.contains(aname) && pnames.nonEmpty // argument is missing, pass an empty tree
then genericEmptyTree :: handleNamed(pnames.tail, args, nameToArg, toDrop, missingArgs = true)
else // name not (or no longer) available for named arg
def msg =
if (methodType.paramNames contains aname)
if methodType.paramNames.contains(aname) then
em"parameter $aname of $methString is already instantiated"
else
em"$methString does not have a parameter $aname"
fail(msg, arg.asInstanceOf[Arg])
arg :: handleNamed(pnamesRest, args1, nameToArg, toDrop, missingArgs)
}
case arg :: args1 =>
arg :: handleNamed(tailOf(pnames), args1, nameToArg, toDrop, missingArgs)
case arg :: args =>
if toDrop.nonEmpty || missingArgs then
report.error(i"positional after named argument", arg.srcPos)
arg :: handleNamed(pnamesRest, args1, nameToArg, toDrop, missingArgs) // unnamed argument; pick it
case Nil => // no more args, continue to pick up any preceding named args
if (pnames.isEmpty) Nil
else handleNamed(pnamesRest, args, nameToArg, toDrop, missingArgs)
}
}
arg :: handleNamed(tailOf(pnames), args, nameToArg, toDrop, missingArgs) // unnamed argument; pick it
case nil => // no more args, continue to pick up any preceding named args
if pnames.isEmpty then nil
else handleNamed(tailOf(pnames), nil, nameToArg, toDrop, missingArgs)

/** Skip prefix of positional args, then handleNamed */
def handlePositional(pnames: List[Name], args: List[Trees.Tree[T]]): List[Trees.Tree[T]] =
args match {
case (arg: NamedArg @unchecked) :: _ =>
val nameAssocs = for (case arg @ NamedArg(name, _) <- args) yield (name, arg)
handleNamed(pnames, args, nameAssocs.toMap, toDrop = Set(), missingArgs = false)
case arg :: args1 =>
arg :: handlePositional(if (pnames.isEmpty) Nil else pnames.tail, args1)
case Nil => Nil
}
args match
case (_: NamedArg) :: _ =>
//val nameAssocs = for case arg @ NamedArg(name, _) <- args yield (name, arg)
val nameAssocs = args.collect { case arg @ NamedArg(name, _) => name -> arg }
handleNamed(pnames, args, nameAssocs.toMap, toDrop = Set.empty, missingArgs = false)
case arg :: args =>
arg :: handlePositional(tailOf(pnames), args)
case nil => nil

handlePositional(methodType.paramNames, args)
}
end reorder

/** Is `sym` a constructor of a Java-defined annotation? */
def isJavaAnnotConstr(sym: Symbol): Boolean =
Expand Down

0 comments on commit 262fcdf

Please sign in to comment.