From d6519af64cab257fd45d12b818b2117e9c0f5440 Mon Sep 17 00:00:00 2001 From: Lukas Rytz Date: Tue, 30 Jun 2009 20:59:49 +0000 Subject: minor cleanups for named args --- src/compiler/scala/tools/nsc/ast/Trees.scala | 32 ++++++++++++-------- .../scala/tools/nsc/ast/parser/Parsers.scala | 35 +++++++++++----------- .../tools/nsc/symtab/classfile/PickleFormat.scala | 2 +- .../tools/nsc/typechecker/NamesDefaults.scala | 6 ++-- .../scala/tools/nsc/typechecker/Typers.scala | 12 ++++---- test/files/pos/t1782/Test_1.scala | 5 ++++ test/files/run/names-defaults.check | 1 + test/files/run/names-defaults.scala | 1 + 8 files changed, 55 insertions(+), 39 deletions(-) diff --git a/src/compiler/scala/tools/nsc/ast/Trees.scala b/src/compiler/scala/tools/nsc/ast/Trees.scala index 662f3c9908..1abdc04ee2 100644 --- a/src/compiler/scala/tools/nsc/ast/Trees.scala +++ b/src/compiler/scala/tools/nsc/ast/Trees.scala @@ -690,17 +690,13 @@ trait Trees { /** Assignment */ case class Assign(lhs: Tree, rhs: Tree) - extends TermTree { - def namedArg = false - } + extends TermTree /** Either an assignment or a named argument. Only appears in argument lists, - * eliminated by typecheck. + * eliminated by typecheck (doTypedApply) */ - class AssignOrNamedArg(lhs: Tree, rhs: Tree) - extends Assign(lhs, rhs) { - override def namedArg = true - } + case class AssignOrNamedArg(lhs: Tree, rhs: Tree) + extends TermTree /** Conditional expression */ case class If(cond: Tree, thenp: Tree, elsep: Tree) @@ -964,6 +960,8 @@ trait Trees { // vparams => body where vparams:List[ValDef] case Assign(lhs, rhs) => // lhs = rhs + case AssignOrNamedArg(lhs, rhs) => (eliminated by typecheck) + // lhs = rhs case If(cond, thenp, elsep) => // if (cond) thenp else elsep case Match(selector, cases) => @@ -1037,6 +1035,7 @@ trait Trees { def ArrayValue(tree: Tree, elemtpt: Tree, trees: List[Tree]): ArrayValue def Function(tree: Tree, vparams: List[ValDef], body: Tree): Function def Assign(tree: Tree, lhs: Tree, rhs: Tree): Assign + def AssignOrNamedArg(tree: Tree, lhs: Tree, rhs: Tree): AssignOrNamedArg def If(tree: Tree, cond: Tree, thenp: Tree, elsep: Tree): If def Match(tree: Tree, selector: Tree, cases: List[CaseDef]): Match def Return(tree: Tree, expr: Tree): Return @@ -1101,10 +1100,10 @@ trait Trees { new ArrayValue(elemtpt, trees).copyAttrs(tree) def Function(tree: Tree, vparams: List[ValDef], body: Tree) = new Function(vparams, body).copyAttrs(tree) - def Assign(tree: Tree, lhs: Tree, rhs: Tree) = tree match { - case t: AssignOrNamedArg => new AssignOrNamedArg(lhs, rhs).copyAttrs(tree) - case _ => new Assign(lhs, rhs).copyAttrs(tree) - } + def Assign(tree: Tree, lhs: Tree, rhs: Tree) = + new Assign(lhs, rhs).copyAttrs(tree) + def AssignOrNamedArg(tree: Tree, lhs: Tree, rhs: Tree) = + new AssignOrNamedArg(lhs, rhs).copyAttrs(tree) def If(tree: Tree, cond: Tree, thenp: Tree, elsep: Tree) = new If(cond, thenp, elsep).copyAttrs(tree) def Match(tree: Tree, selector: Tree, cases: List[CaseDef]) = @@ -1256,6 +1255,11 @@ trait Trees { if (lhs0 == lhs) && (rhs0 == rhs) => t case _ => treeCopy.Assign(tree, lhs, rhs) } + def AssignOrNamedArg(tree: Tree, lhs: Tree, rhs: Tree) = tree match { + case t @ AssignOrNamedArg(lhs0, rhs0) + if (lhs0 == lhs) && (rhs0 == rhs) => t + case _ => treeCopy.AssignOrNamedArg(tree, lhs, rhs) + } def If(tree: Tree, cond: Tree, thenp: Tree, elsep: Tree) = tree match { case t @ If(cond0, thenp0, elsep0) if (cond0 == cond) && (thenp0 == thenp) && (elsep0 == elsep) => t @@ -1441,6 +1445,8 @@ trait Trees { } case Assign(lhs, rhs) => treeCopy.Assign(tree, transform(lhs), transform(rhs)) + case AssignOrNamedArg(lhs, rhs) => + treeCopy.AssignOrNamedArg(tree, transform(lhs), transform(rhs)) case If(cond, thenp, elsep) => treeCopy.If(tree, transform(cond), transform(thenp), transform(elsep)) case Match(selector, cases) => @@ -1589,6 +1595,8 @@ trait Trees { } case Assign(lhs, rhs) => traverse(lhs); traverse(rhs) + case AssignOrNamedArg(lhs, rhs) => + traverse(lhs); traverse(rhs) case If(cond, thenp, elsep) => traverse(cond); traverse(thenp); traverse(elsep) case Match(selector, cases) => diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala index 9d6a8af329..5b22914b23 100755 --- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala @@ -471,6 +471,16 @@ self => } } + /** part {`,' part} */ + def commaSeparated(part: () => Tree): List[Tree] = { + val ts = new ListBuffer[Tree] += part() + while (in.token == COMMA) { + in.nextToken() + ts += part() + } + ts.toList + } + /* --------- OPERAND/OPERATOR STACK --------------------------------------- */ /** modes for infix types */ @@ -690,7 +700,7 @@ self => /** Types ::= Type {`,' Type} */ def types(isPattern: Boolean, isTypeApply: Boolean, isFuncArg: Boolean): List[Tree] = - exprs(() => argType(isPattern, isTypeApply, isFuncArg)) + commaSeparated(() => argType(isPattern, isTypeApply, isFuncArg)) /** Type ::= InfixType `=>' Type * | `(' [`=>' Type] `)' `=>' Type @@ -906,17 +916,6 @@ self => expr() } - /** Exprs ::= Expr {`,' Expr} - */ - def exprs(part: () => Tree = expr _): List[Tree] = { - val ts = new ListBuffer[Tree] += part() - while (in.token == COMMA) { - in.nextToken() - ts += part() - } - ts.toList - } - def condExpr(): Tree = { if (in.token == LPAREN) { in.nextToken() @@ -1174,7 +1173,7 @@ self => id case LPAREN => atPos(in.skipToken()) { - val ts = if (in.token == RPAREN) List() else exprs() + val ts = if (in.token == RPAREN) List() else commaSeparated(expr _) accept(RPAREN) Parens(ts) } @@ -1237,11 +1236,11 @@ self => * | [nl] BlockExpr */ def argumentExprs(): List[Tree] = { - def args(): List[Tree] = exprs(() => { + def args(): List[Tree] = commaSeparated(() => { val maybeNamed = isIdent expr() match { case a @ Assign(id, rhs) if maybeNamed => - atPos(a.pos) { new AssignOrNamedArg(id, rhs) } + atPos(a.pos) { AssignOrNamedArg(id, rhs) } case e => e } }) @@ -1255,7 +1254,7 @@ self => rhs match { case Ident(`pname1`) | Typed(Ident(`pname1`), _) => placeholderParams = vd :: placeholderParams - atPos(arg.pos) { new AssignOrNamedArg(Ident(aname), Ident(pname1)) } + atPos(arg.pos) { AssignOrNamedArg(Ident(aname), Ident(pname1)) } case _ => arg } case _ => arg @@ -1359,7 +1358,7 @@ self => * SeqPatterns ::= SeqPattern { `,' SeqPattern } */ def patterns(seqOK: Boolean): List[Tree] = - exprs(() => pattern(seqOK)) + commaSeparated(() => pattern(seqOK)) /** Pattern ::= Pattern1 { `|' Pattern1 } * SeqPattern ::= SeqPattern1 { `|' SeqPattern1 } @@ -1828,7 +1827,7 @@ self => */ def importClause(): List[Tree] = { accept(IMPORT) - exprs(() => importExpr()) + commaSeparated(() => importExpr()) } /** ImportExpr ::= StableId `.' (Id | `_' | ImportSelectors) diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/PickleFormat.scala b/src/compiler/scala/tools/nsc/symtab/classfile/PickleFormat.scala index a553fdece8..0b0b7216b9 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/PickleFormat.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/PickleFormat.scala @@ -40,7 +40,7 @@ object PickleFormat { * | 19 CLASSINFOtpe len_Nat classsym_Ref {tpe_Ref} * | 20 METHODtpe len_Nat tpe_Ref {sym_Ref} * | 21 POLYTtpe len_Nat tpe_Ref {sym_Ref} - * | 22 IMPLICITMETHODtpe len_Nat tpe_Ref {tpe_Ref} + * | 22 IMPLICITMETHODtpe len_Nat tpe_Ref {sym_Ref} * | 52 SUPERtpe len_Nat tpe_Ref tpe_Ref * | 24 LITERALunit len_Nat * | 25 LITERALboolean len_Nat value_Long diff --git a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala index 34f832f2a6..e8750104f0 100644 --- a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala +++ b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala @@ -23,7 +23,7 @@ trait NamesDefaults { self: Analyzer => val noApplyInfo = NamedApplyInfo(None, Nil, Nil, null) def nameOf(arg: Tree) = arg match { - case a @ Assign(Ident(name), rhs) if a.namedArg => Some(name) + case AssignOrNamedArg(Ident(name), rhs) => Some(name) case _ => None } def isNamed(arg: Tree) = nameOf(arg).isDefined @@ -327,7 +327,7 @@ trait NamesDefaults { self: Analyzer => val default2 = (default1 /: previousArgss)((tree, args) => Apply(tree, args.map(_.duplicate)).setPos(pos)) if (positional) default2 - else atPos(pos) { new AssignOrNamedArg(Ident(p.name), default2) } + else atPos(pos) { AssignOrNamedArg(Ident(p.name), default2) } }) (givenArgs ::: defaultArgs, Nil) } else (givenArgs, missing filter (! _.hasFlag(DEFAULTPARAM))) @@ -348,7 +348,7 @@ trait NamesDefaults { self: Analyzer => val argPos = (new Array[Int](args.length)) map (x => -1) var positionalAllowed = true val namelessArgs = for ((arg, index) <- (args.zipWithIndex)) yield arg match { - case a @ Assign(Ident(name), rhs) if a.namedArg => + case a @ AssignOrNamedArg(Ident(name), rhs) => val pos = params.indexWhere(p => p.name == name && !p.hasFlag(SYNTHETIC)) if (pos == -1) { if (positionalAllowed) { diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 90a680a514..b0226af4e3 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -274,8 +274,7 @@ trait Typers { self: Analyzer => case _ => ex.getMessage() } - if (context.retyping) context.error(pos, msg) - else context.unit.error(pos, msg) + context.error(pos, msg) if (sym == ObjectClass) throw new FatalError("cannot redefine root "+sym) case _ => @@ -1919,7 +1918,7 @@ trait Typers { self: Analyzer => def shapeType(arg: Tree): Type = arg match { case Function(vparams, body) => functionType(vparams map (vparam => AnyClass.tpe), shapeType(body)) - case a @ Assign(Ident(name), rhs) if a.namedArg => + case AssignOrNamedArg(Ident(name), rhs) => NamedType(name, shapeType(rhs)) case _ => NothingClass.tpe @@ -1950,7 +1949,7 @@ trait Typers { self: Analyzer => val argtpes = new ListBuffer[Type] val amode = argMode(fun, mode) val args1 = args map { - case arg @ Assign(Ident(name), rhs) if arg.namedArg => + case arg @ AssignOrNamedArg(Ident(name), rhs) => // named args: only type the righthand sides ("unknown identifier" errors otherwise) val rhs1 = typedArg(rhs, amode, 0, WildcardType) argtpes += NamedType(name, rhs1.tpe.deconst) @@ -2350,7 +2349,7 @@ trait Typers { self: Analyzer => names ++= (if (isJava) annScope.iterator else typedFun.tpe.params.iterator) val nvPairs = args map { - case arg @ Assign(Ident(name), rhs) if arg.namedArg => + case arg @ AssignOrNamedArg(Ident(name), rhs) => val sym = if (isJava) annScope.lookupWithContext(name)(context.owner) else typedFun.tpe.params.find(p => p.name == name).getOrElse(NoSymbol) if (sym == NoSymbol) { @@ -3541,6 +3540,9 @@ trait Typers { self: Analyzer => case Assign(lhs, rhs) => typedAssign(lhs, rhs) + case AssignOrNamedArg(lhs, rhs) => // called by NamesDefaults in silent typecheck + typedAssign(lhs, rhs) + case If(cond, thenp, elsep) => typedIf(cond, thenp, elsep) diff --git a/test/files/pos/t1782/Test_1.scala b/test/files/pos/t1782/Test_1.scala index 021dfc6d53..e61ef8eaf5 100644 --- a/test/files/pos/t1782/Test_1.scala +++ b/test/files/pos/t1782/Test_1.scala @@ -8,4 +8,9 @@ class Provider { // test enumeration java annotations @Ann(Days.Friday) def someMethod() = () + + // #2103 + @scala.reflect.BeanProperty + @Ann(value = Days.Sunday) + val t2103 = "test" } diff --git a/test/files/run/names-defaults.check b/test/files/run/names-defaults.check index 5c2290acf9..e9381760ce 100644 --- a/test/files/run/names-defaults.check +++ b/test/files/run/names-defaults.check @@ -96,6 +96,7 @@ test5 4 test5 5 +10: 2 slkdfj1 1 lskfdjlk diff --git a/test/files/run/names-defaults.scala b/test/files/run/names-defaults.scala index 0e5a268e62..162c0bc43e 100644 --- a/test/files/run/names-defaults.scala +++ b/test/files/run/names-defaults.scala @@ -177,6 +177,7 @@ object Test extends Application { println(argName) // should be 4 test5 { argName = 5 } println(argName) // should be 5 + val a = test1(a = 10, b = "2") // local values a and b exist, but not ambiuous since they're val's // dependent types and copy method -- cgit v1.2.3