From 979180ca5f30752d94d64b083b6dbca57dab0c4b Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Wed, 14 Feb 2007 13:37:19 +0000 Subject: more changes to make tuples (...) --- src/compiler/scala/tools/nsc/ast/TreeGen.scala | 4 +- .../scala/tools/nsc/ast/parser/Parsers.scala | 22 +++++------ src/compiler/scala/tools/nsc/symtab/Symbols.scala | 2 +- .../scala/tools/nsc/typechecker/Infer.scala | 2 +- .../scala/tools/nsc/typechecker/Typers.scala | 44 ++++++++++++---------- 5 files changed, 39 insertions(+), 35 deletions(-) (limited to 'src/compiler') diff --git a/src/compiler/scala/tools/nsc/ast/TreeGen.scala b/src/compiler/scala/tools/nsc/ast/TreeGen.scala index f639fc3c44..28a7fd10b0 100644 --- a/src/compiler/scala/tools/nsc/ast/TreeGen.scala +++ b/src/compiler/scala/tools/nsc/ast/TreeGen.scala @@ -163,10 +163,10 @@ abstract class TreeGen { def mkNil: Tree = mkAttributedRef(definitions.NilModule) - /** Builds a pair */ + /** Builds a tuple */ def mkTuple(elems: List[Tree]): Tree = if (elems.isEmpty) Literal(()) - else New(TypeTree(definitions.TupleClass(elems.length).tpe), List(elems)) + else Apply(mkAttributedRef(definitions.TupleClass(elems.length).caseFactory), elems) def mkCached(cvar: Symbol, expr: Tree): Tree = { val cvarRef = if (cvar.owner.isClass) Select(This(cvar.owner), cvar) else Ident(cvar) diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala index dfbc330145..18980a9437 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala @@ -801,7 +801,7 @@ trait Parsers requires SyntaxAnalyzer { * | throw Expr * | return [Expr] * | [SimpleExpr `.'] Id `=' Expr - * | SimpleExpr ArgumentExprs `=' Expr + * | SimpleExpr1 ArgumentExprs `=' Expr * | `.' SimpleExpr * | PostfixExpr [`:' (CompoundType | `_' `*')] * | PostfixExpr match [`!'] `{' CaseClauses `}' @@ -1006,21 +1006,20 @@ trait Parsers requires SyntaxAnalyzer { } /* SimpleExpr ::= new SimpleType {`(' [Exprs] `)'} {`with' SimpleType} [TemplateBody] + * | BlockExpr * | SimpleExpr1 * SimpleExpr1 ::= literal * | xLiteral * | Path * | StableId `.' class * | `(' [Expr] `)' - * | BlockExpr - * | new Template * | SimpleExpr `.' Id * | SimpleExpr TypeArgs * | SimpleExpr1 ArgumentExprs */ def simpleExpr(): Tree = { var t: Tree = null - var isNew = false + var canApply = true in.token match { case CHARLIT | INTLIT | LONGLIT | FLOATLIT | DOUBLELIT | STRINGLIT | SYMBOLLIT | TRUE | FALSE | NULL => @@ -1036,6 +1035,7 @@ trait Parsers requires SyntaxAnalyzer { t = Parens(ts) case LBRACE => t = blockExpr() + canApply = false case NEW => t = atPos(in.skipToken()) { val parents = new ListBuffer[Tree] + simpleType(false) @@ -1050,7 +1050,7 @@ trait Parsers requires SyntaxAnalyzer { val stats = if (in.token == LBRACE) templateBody() else List() makeNew(parents.toList, stats, argss.toList) } - isNew = true + canApply = false case _ => if (settings.migrate.value) { if (in.token == MATCH) @@ -1061,21 +1061,21 @@ trait Parsers requires SyntaxAnalyzer { syntaxErrorOrIncomplete("illegal start of simple expression", true) t = errorTermTree } - simpleExprRest(t, isNew) + simpleExprRest(t, canApply) } - def simpleExprRest(t: Tree, isNew: boolean): Tree = in.token match { + def simpleExprRest(t: Tree, canApply: boolean): Tree = in.token match { case DOT => - simpleExprRest(atPos(in.skipToken()) { selector(stripParens(t)) }, false) + simpleExprRest(atPos(in.skipToken()) { selector(stripParens(t)) }, true) case LBRACKET => t match { case Ident(_) | Select(_, _) => - simpleExprRest(atPos(in.currentPos) { TypeApply(t, typeArgs(false)) }, false) + simpleExprRest(atPos(in.currentPos) { TypeApply(t, typeArgs(false)) }, true) case _ => t } - case LPAREN | LBRACE if (!isNew) => - simpleExprRest(atPos(in.currentPos) { Apply(stripParens(t), argumentExprs()) }, false) + case LPAREN | LBRACE if (canApply) => + simpleExprRest(atPos(in.currentPos) { Apply(stripParens(t), argumentExprs()) }, true) case _ => t } diff --git a/src/compiler/scala/tools/nsc/symtab/Symbols.scala b/src/compiler/scala/tools/nsc/symtab/Symbols.scala index 2db48eaa41..5d2e5220d4 100644 --- a/src/compiler/scala/tools/nsc/symtab/Symbols.scala +++ b/src/compiler/scala/tools/nsc/symtab/Symbols.scala @@ -825,7 +825,7 @@ trait Symbols requires SymbolTable { * @pre case class is a member of some other class or package */ final def caseFactory: Symbol = - owner.info.decl(name.toTermName).suchThat(.isCaseFactory) + initialize.owner.info.decl(name.toTermName).suchThat(.isCaseFactory) /** If this symbol is a skolem, its corresponding type parameter, otherwise this */ def deSkolemize: Symbol = this diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala index 91ff898450..52672ed014 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala @@ -56,7 +56,7 @@ trait Infer requires Analyzer { else actuals def actualArgs(pos: PositionType, actuals: List[Tree], nformals: int): List[Tree] = - if (nformals == 1 && actuals.length != 1) List(gen.mkTuple(actuals) setPos pos) else actuals + if (nformals == 1 && actuals.length != 1) List(atPos(pos)(gen.mkTuple(actuals))) else actuals /** A fresh type varable with given type parameter as origin. * diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 1e645f3baa..c05c17a0a2 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -545,13 +545,9 @@ trait Typers requires Analyzer { } else if (!meth.isConstructor && mt.paramTypes.isEmpty) { // (4.3) adapt(typed(Apply(tree, List()) setPos tree.pos), mode, pt) } else if (context.implicitsEnabled) { - if (settings.migrate.value && !meth.isConstructor && - isCompatible(tparamsToWildcards(mt, context.undetparams), pt)) - errorTree(tree, migrateMsg + " method can be converted to function only if an expected function type is given"); - else - errorTree(tree, "missing arguments for "+meth+meth.locationString+ - (if (meth.isConstructor) "" - else ";\nprefix this method with `&' if you want to treat it as a partially applied function")) + errorTree(tree, "missing arguments for "+meth+meth.locationString+ + (if (meth.isConstructor) "" + else ";\nprefix this method with `&' if you want to treat it as a partially applied function")) } else { setError(tree) } @@ -1382,8 +1378,14 @@ trait Typers requires Analyzer { case MethodType(formals0, restpe) => val formals = formalTypes(formals0, args.length) var args1 = actualArgs(tree.pos, args, formals.length) - if (formals.length != args1.length) { - Console.println(formals+" "+args1);//DEBUG + if (args1.length != args.length) { + try { + silentTypedApply(tree, fun, args1, mode, pt) + } catch { + case ex: TypeError => + errorTree(tree, "wrong number of arguments for "+treeSymTypeMsg(fun)) + } + } else if (formals.length != args1.length) { errorTree(tree, "wrong number of arguments for "+treeSymTypeMsg(fun)) } else { val tparams = context.undetparams @@ -1537,6 +1539,18 @@ trait Typers requires Analyzer { } } + def silentTypedApply(tree: Tree, fun: Tree, args: List[Tree], mode: int, pt: Type): Tree = + if (context.reportGeneralErrors) { + val context1 = context.makeSilent(context.reportAmbiguousErrors) + context1.undetparams = context.undetparams + val typer1 = newTyper(context1) + val result = typer1.typedApply(tree, fun, args, mode, pt) + context.undetparams = context1.undetparams + result + } else { + typedApply(tree, fun, args, mode, pt) + } + def typedAnnotation(constr: Tree, elements: List[Tree]): AttrInfo = { var attrError: Boolean = false; def error(pos: PositionType, msg: String): Null = { @@ -1643,17 +1657,7 @@ trait Typers requires Analyzer { * @return ... */ def tryTypedApply(fun: Tree, args: List[Tree]): Tree = try { - if (context.reportGeneralErrors) { - val context1 = context.makeSilent(context.reportAmbiguousErrors) - context1.undetparams = context.undetparams - val typer1 = newTyper(context1) - val result = - typer1.typedApply(tree, fun, args, mode, pt) - context.undetparams = context1.undetparams - result - } else { - typedApply(tree, fun, args, mode, pt) - } + silentTypedApply(tree, fun, args, mode, pt) } catch { case ex: CyclicReference => throw ex -- cgit v1.2.3