summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2013-01-14 23:29:50 -0800
committerPaul Phillips <paulp@improving.org>2013-01-26 11:19:36 -0800
commit5878099cbb3ca0b0224c9931d3510c7234e7c686 (patch)
tree16bf55b9b7b71dda990fc296c4dfb81bb6489a1e
parente626ecd2346b917d1b3397e0159bca4862214e9d (diff)
downloadscala-5878099cbb3ca0b0224c9931d3510c7234e7c686.tar.gz
scala-5878099cbb3ca0b0224c9931d3510c7234e7c686.tar.bz2
scala-5878099cbb3ca0b0224c9931d3510c7234e7c686.zip
Renamed methods to be less ambiguous in intent.
isNamed => isNamedArg isIdentity => allArgsArePositional nameOf => nameOfNamedArg Moved mkNamedArg into TreeGen.
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/Parsers.scala11
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala9
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Infer.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala14
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala32
-rw-r--r--src/reflect/scala/reflect/internal/TreeGen.scala4
-rw-r--r--src/reflect/scala/reflect/internal/TreeInfo.scala8
7 files changed, 38 insertions, 42 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
index 744644fd49..37da1b44bb 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
@@ -1584,14 +1584,9 @@ self =>
* }}}
*/
def argumentExprs(): List[Tree] = {
- def args(): List[Tree] = commaSeparated {
- val maybeNamed = isIdent
- expr() match {
- case a @ Assign(id, rhs) if maybeNamed =>
- atPos(a.pos) { AssignOrNamedArg(id, rhs) }
- case e => e
- }
- }
+ def args(): List[Tree] = commaSeparated(
+ if (isIdent) treeInfo.assignmentToMaybeNamedArg(expr()) else expr()
+ )
in.token match {
case LBRACE => List(blockExpr())
case LPAREN => inParens(if (in.token == RPAREN) Nil else args())
diff --git a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala
index 39270719fb..379261906a 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala
@@ -171,15 +171,10 @@ abstract class TreeBuilder {
/** Create tree representing (unencoded) binary operation expression or pattern. */
def makeBinop(isExpr: Boolean, left: Tree, op: TermName, right: Tree, opPos: Position): Tree = {
- def mkNamed(args: List[Tree]) =
- if (isExpr) args map {
- case a @ Assign(id @ Ident(name), rhs) =>
- atPos(a.pos) { AssignOrNamedArg(id, rhs) }
- case e => e
- } else args
+ def mkNamed(args: List[Tree]) = if (isExpr) args map treeInfo.assignmentToMaybeNamedArg else args
val arguments = right match {
case Parens(args) => mkNamed(args)
- case _ => List(right)
+ case _ => List(right)
}
if (isExpr) {
if (treeInfo.isLeftAssoc(op)) {
diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
index 4177b7cdfa..07b3a926a0 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
@@ -866,7 +866,7 @@ trait Infer extends Checkable {
val (argtpes1, argPos, namesOK) = checkNames(argtpes0, params)
// when using named application, the vararg param has to be specified exactly once
( namesOK
- && (isIdentity(argPos) || sameLength(formals, params))
+ && (allArgsArePositional(argPos) || sameLength(formals, params))
&& typesCompatible(reorderArgs(argtpes1, argPos)) // nb. arguments and names are OK, check if types are compatible
)
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
index f5884e5c34..dd60b292bf 100644
--- a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
@@ -41,11 +41,11 @@ trait NamesDefaults { self: Analyzer =>
blockTyper: Typer
) { }
- def nameOf(arg: Tree) = arg match {
- case AssignOrNamedArg(Ident(name), rhs) => Some(name)
- case _ => None
+ private def nameOfNamedArg(arg: Tree) = Some(arg) collect { case AssignOrNamedArg(Ident(name), _) => name }
+ def isNamedArg(arg: Tree) = arg match {
+ case AssignOrNamedArg(Ident(_), _) => true
+ case _ => false
}
- def isNamed(arg: Tree) = nameOf(arg).isDefined
/** @param pos maps indices from old to new */
def reorderArgs[T: ClassTag](args: List[T], pos: Int => Int): List[T] = {
@@ -55,13 +55,13 @@ trait NamesDefaults { self: Analyzer =>
}
/** @param pos maps indices from new to old (!) */
- def reorderArgsInv[T: ClassTag](args: List[T], pos: Int => Int): List[T] = {
+ private def reorderArgsInv[T: ClassTag](args: List[T], pos: Int => Int): List[T] = {
val argsArray = args.toArray
(argsArray.indices map (i => argsArray(pos(i)))).toList
}
/** returns `true` if every element is equal to its index */
- def isIdentity(a: Array[Int]) = (0 until a.length).forall(i => a(i) == i)
+ def allArgsArePositional(a: Array[Int]) = (0 until a.length).forall(i => a(i) == i)
/**
* Transform a function application into a Block, and assigns typer.context
@@ -359,7 +359,7 @@ trait NamesDefaults { self: Analyzer =>
}
}
- def missingParams[T](args: List[T], params: List[Symbol], argName: T => Option[Name] = nameOf _): (List[Symbol], Boolean) = {
+ def missingParams[T](args: List[T], params: List[Symbol], argName: T => Option[Name] = nameOfNamedArg _): (List[Symbol], Boolean) = {
val namedArgs = args.dropWhile(arg => {
val n = argName(arg)
n.isEmpty || params.forall(p => p.name != n.get)
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index dcc2ee0f23..e8d0a497ca 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -117,10 +117,6 @@ trait Typers extends Adaptations with Tags {
}
}
- private def mkNamedArg(tree: Tree, name: Name): Tree = {
- atPos(tree.pos)(new AssignOrNamedArg(Ident(name), tree))
- }
-
/** Find implicit arguments and pass them to given tree.
*/
def applyImplicitArgs(fun: Tree): Tree = fun.tpe match {
@@ -130,9 +126,7 @@ trait Typers extends Adaptations with Tags {
// paramFailed cannot be initialized with params.exists(_.tpe.isError) because that would
// hide some valid errors for params preceding the erroneous one.
var paramFailed = false
-
- def mkPositionalArg(argTree: Tree, paramName: Name) = argTree
- var mkArg: (Tree, Name) => Tree = mkPositionalArg
+ var mkArg: (Name, Tree) => Tree = (_, tree) => tree
// DEPMETTODO: instantiate type vars that depend on earlier implicit args (see adapt (4.1))
//
@@ -147,9 +141,9 @@ trait Typers extends Adaptations with Tags {
argResultsBuff += res
if (res.isSuccess) {
- argBuff += mkArg(res.tree, param.name)
+ argBuff += mkArg(param.name, res.tree)
} else {
- mkArg = mkNamedArg // don't pass the default argument (if any) here, but start emitting named arguments for the following args
+ mkArg = gen.mkNamedArg // don't pass the default argument (if any) here, but start emitting named arguments for the following args
if (!param.hasDefault && !paramFailed) {
context.errBuffer.find(_.kind == ErrorKinds.Divergent) match {
case Some(divergentImplicit) =>
@@ -3104,10 +3098,10 @@ trait Typers extends Adaptations with Tags {
val (namelessArgs, argPos) = removeNames(Typer.this)(args, params)
if (namelessArgs exists (_.isErroneous)) {
duplErrTree
- } else if (!isIdentity(argPos) && !sameLength(formals, params))
- // !isIdentity indicates that named arguments are used to re-order arguments
+ } else if (!allArgsArePositional(argPos) && !sameLength(formals, params))
+ // !allArgsArePositional indicates that named arguments are used to re-order arguments
duplErrorTree(MultipleVarargError(tree))
- else if (isIdentity(argPos) && !isNamedApplyBlock(fun)) {
+ else if (allArgsArePositional(argPos) && !isNamedApplyBlock(fun)) {
// if there's no re-ordering, and fun is not transformed, no need to transform
// more than an optimization, e.g. important in "synchronized { x = update-x }"
checkNotMacro()
@@ -3157,7 +3151,7 @@ trait Typers extends Adaptations with Tags {
}
if (!sameLength(formals, args) || // wrong nb of arguments
- (args exists isNamed) || // uses a named argument
+ (args exists isNamedArg) || // uses a named argument
isNamedApplyBlock(fun)) { // fun was transformed to a named apply block =>
// integrate this application into the block
if (dyna.isApplyDynamicNamed(fun)) dyna.typedNamedApply(tree, fun, args, mode, pt)
@@ -3464,7 +3458,7 @@ trait Typers extends Adaptations with Tags {
}
// begin typedAnnotation
- val treeInfo.Applied(fun0, targs, argss) = treeInfo.dissectApplied(ann)
+ val treeInfo.Applied(fun0, targs, argss) = ann
val typedFun0 = typed(fun0, mode.forFunMode, WildcardType)
val typedFunPart = (
// If there are dummy type arguments in typeFun part, it suggests we
@@ -3475,7 +3469,7 @@ trait Typers extends Adaptations with Tags {
else
typedFun0
)
- val typedFun @ Select(New(annTpt), _) = treeInfo.dissectApplied(typedFunPart).core
+ val treeInfo.Applied(typedFun @ Select(New(annTpt), _), _, _) = typedFunPart
val annType = annTpt.tpe
val res = if (typedFun.isErroneous) ErroneousAnnotation
@@ -3489,15 +3483,15 @@ trait Typers extends Adaptations with Tags {
} else if (argss.length > 1) {
reportAnnotationError(MultipleArgumentListForAnnotationError(ann))
} else {
+ val args = argss match {
+ case (arg :: Nil) :: Nil if !isNamedArg(arg) => gen.mkNamedArg(nme.value, arg) :: Nil
+ case args :: Nil => args
+ }
val annScope = annType.decls
.filter(sym => sym.isMethod && !sym.isConstructor && sym.isJavaDefined)
val names = new scala.collection.mutable.HashSet[Symbol]
names ++= (if (isJava) annScope.iterator
else typedFun.tpe.params.iterator)
- val args = argss match {
- case (arg :: Nil) :: Nil if !isNamed(arg) => mkNamedArg(arg, nme.value) :: Nil
- case args :: Nil => args
- }
val nvPairs = args map {
case arg @ AssignOrNamedArg(Ident(name), rhs) =>
diff --git a/src/reflect/scala/reflect/internal/TreeGen.scala b/src/reflect/scala/reflect/internal/TreeGen.scala
index 6a2006e56f..54a85dee86 100644
--- a/src/reflect/scala/reflect/internal/TreeGen.scala
+++ b/src/reflect/scala/reflect/internal/TreeGen.scala
@@ -271,6 +271,10 @@ abstract class TreeGen extends macros.TreeBuilder {
case _ => Constant(null)
}
+ /** Wrap an expression in a named argument. */
+ def mkNamedArg(name: Name, tree: Tree): Tree = mkNamedArg(Ident(name), tree)
+ def mkNamedArg(lhs: Tree, rhs: Tree): Tree = atPos(rhs.pos)(AssignOrNamedArg(lhs, rhs))
+
/** Builds a tuple */
def mkTuple(elems: List[Tree]): Tree =
if (elems.isEmpty) Literal(Constant())
diff --git a/src/reflect/scala/reflect/internal/TreeInfo.scala b/src/reflect/scala/reflect/internal/TreeInfo.scala
index c90e94c1c1..45720053a8 100644
--- a/src/reflect/scala/reflect/internal/TreeInfo.scala
+++ b/src/reflect/scala/reflect/internal/TreeInfo.scala
@@ -370,6 +370,14 @@ abstract class TreeInfo {
case _ => false
}
+ /** Translates an Assign(_, _) node to AssignOrNamedArg(_, _) if
+ * the lhs is a simple ident. Otherwise returns unchanged.
+ */
+ def assignmentToMaybeNamedArg(tree: Tree) = tree match {
+ case t @ Assign(id: Ident, rhs) => atPos(t.pos)(AssignOrNamedArg(id, rhs))
+ case t => t
+ }
+
/** Is name a left-associative operator? */
def isLeftAssoc(operator: Name) = operator.nonEmpty && (operator.endChar != ':')