diff options
author | Paul Phillips <paulp@improving.org> | 2013-01-14 23:29:50 -0800 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2013-01-26 11:19:36 -0800 |
commit | 5878099cbb3ca0b0224c9931d3510c7234e7c686 (patch) | |
tree | 16bf55b9b7b71dda990fc296c4dfb81bb6489a1e | |
parent | e626ecd2346b917d1b3397e0159bca4862214e9d (diff) | |
download | scala-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.
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 != ':') |