summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2006-10-04 16:15:04 +0000
committerMartin Odersky <odersky@gmail.com>2006-10-04 16:15:04 +0000
commit7233c24d3c54cdc4b68b39fb0a270a771d4449f5 (patch)
tree1164bbe016c84e459194f3b530333f243b67ea4e
parent93275f2d34ec534049baf529493dc6f2836a85ea (diff)
downloadscala-7233c24d3c54cdc4b68b39fb0a270a771d4449f5.tar.gz
scala-7233c24d3c54cdc4b68b39fb0a270a771d4449f5.tar.bz2
scala-7233c24d3c54cdc4b68b39fb0a270a771d4449f5.zip
Improved type inference for method signatures.
Added code for lifted expressions (but it is disabled)
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/Parsers.scala390
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala12
-rw-r--r--src/compiler/scala/tools/nsc/symtab/StdNames.scala1
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala77
4 files changed, 277 insertions, 203 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
index ba4bcfc3fb..91d66f4220 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
@@ -275,7 +275,7 @@ trait Parsers requires SyntaxAnalyzer {
def precedence(operator: Name): int =
if (operator eq nme.ERROR) -1
else {
- val firstCh = operator(0);
+ val firstCh = operator(0)
if (((firstCh >= 'A') && (firstCh <= 'Z')) ||
((firstCh >= 'a') && (firstCh <= 'z')))
1
@@ -294,14 +294,14 @@ trait Parsers requires SyntaxAnalyzer {
}
def reduceStack(isExpr: boolean, base: List[OpInfo], top0: Tree, prec: int, leftAssoc: boolean): Tree = {
- var top = top0;
+ var top = top0
if (opstack != base &&
precedence(opstack.head.operator) == prec &&
treeInfo.isLeftAssoc(opstack.head.operator) != leftAssoc) {
syntaxError(
opstack.head.pos,
"left- and right-associative operators with same precedence may not be mixed",
- false);
+ false)
}
while (opstack != base &&
(prec < precedence(opstack.head.operator) ||
@@ -309,7 +309,7 @@ trait Parsers requires SyntaxAnalyzer {
top = atPos(opstack.head.pos) {
makeBinop(isExpr, opstack.head.operand, opstack.head.operator, top)
}
- opstack = opstack.tail;
+ opstack = opstack.tail
}
top
}
@@ -334,8 +334,8 @@ trait Parsers requires SyntaxAnalyzer {
name
} else {
if (settings.migrate.value && in.token == MATCH || in.token == REQUIRES || in.token == IMPLICIT)
- syntaxErrorMigrate(""+in+" is now a reserved word; cannot be used as identifier");
- accept(IDENTIFIER);
+ syntaxErrorMigrate(""+in+" is now a reserved word; cannot be used as identifier")
+ accept(IDENTIFIER)
nme.ERROR
}
@@ -350,7 +350,7 @@ trait Parsers requires SyntaxAnalyzer {
* SimpleType ::= Path [`.' type]
*/
def path(thisOK: boolean, typeOK: boolean): Tree = {
- var t: Tree = null;
+ var t: Tree = null
if (in.token == THIS) {
t = atPos(in.skipToken()) { This(nme.EMPTY.toTypeName) }
if (!thisOK || in.token == DOT)
@@ -367,16 +367,16 @@ trait Parsers requires SyntaxAnalyzer {
if (in.token == BACKQUOTED_IDENT) new BackQuotedIdent(ident())
else Ident(ident())
}
- t = i;
+ t = i
if (in.token == DOT) {
- val pos = in.skipToken();
+ val pos = in.skipToken()
if (in.token == THIS) {
- in.nextToken();
+ in.nextToken()
t = atPos(i.pos) { This(i.name.toTypeName) }
if (!thisOK || in.token == DOT)
t = selectors(t, typeOK, accept(DOT))
} else if (in.token == SUPER) {
- in.nextToken();
+ in.nextToken()
t = atPos(i.pos) { Super(i.name.toTypeName, mixinQualifierOpt()) }
t = atPos(accept(DOT)) {selector(t)}
if (in.token == DOT)
@@ -391,7 +391,7 @@ trait Parsers requires SyntaxAnalyzer {
def selectors(t: Tree, typeOK: boolean, pos : Int): Tree =
if (typeOK && in.token == TYPE) {
- in.nextToken();
+ in.nextToken()
atPos(pos) { SingletonTypeTree(t) }
} else {
val t1 = atPos(pos) { selector(t); }
@@ -416,7 +416,7 @@ trait Parsers requires SyntaxAnalyzer {
* | [Id '.'] super [MixinQualifier] ` `.' Id
*/
def stableId(): Tree =
- path(false, false);
+ path(false, false)
/** QualId ::= Id {`.' Id}
*/
@@ -453,17 +453,17 @@ trait Parsers requires SyntaxAnalyzer {
case NULL =>
Constant(null)
case _ =>
- syntaxError("illegal literal", true);
+ syntaxError("illegal literal", true)
null
})
}
- val isSymLit = in.token == SYMBOLLIT;
- val t = litToTree();
- val pos = in.skipToken();
+ val isSymLit = in.token == SYMBOLLIT
+ val t = litToTree()
+ val pos = in.skipToken()
if (isSymLit) {
atPos(pos) {
- var symid = scalaDot(nme.Symbol);
+ var symid = scalaDot(nme.Symbol)
if (isPattern) { symid = convertToTypeId(symid) }
Apply(symid, List(t))
}
@@ -494,25 +494,25 @@ trait Parsers requires SyntaxAnalyzer {
*/
def typedOpt(): Tree =
if (in.token == COLON) { in.nextToken(); typ() }
- else TypeTree();
+ else TypeTree()
/** RequiresTypedOpt ::= [`:' SimpleType | requires SimpleType]
*/
def requiresTypeOpt(): Tree =
if (in.token == COLON | in.token == REQUIRES) {
if (in.token == COLON)
- warning("`:' has been deprecated; use `requires' instead");
+ warning("`:' has been deprecated; use `requires' instead")
in.nextToken(); simpleType()
}
- else TypeTree();
+ else TypeTree()
/** Types ::= Type {`,' Type}
*/
def types(): List[Tree] = {
- val ts = new ListBuffer[Tree] + typ();
+ val ts = new ListBuffer[Tree] + typ()
while (in.token == COMMA) {
- in.nextToken();
- ts += typ();
+ in.nextToken()
+ ts += typ()
}
ts.toList
}
@@ -525,9 +525,9 @@ trait Parsers requires SyntaxAnalyzer {
def typ(): Tree = {
val t =
if (in.token == LPAREN) {
- in.nextToken();
+ in.nextToken()
if (in.token == RPAREN) {
- in.nextToken();
+ in.nextToken()
atPos(accept(ARROW)) { makeFunctionTypeTree(List(), typ()) }
} else if (in.token == ARROW) {
in.nextToken()
@@ -535,11 +535,11 @@ trait Parsers requires SyntaxAnalyzer {
accept(RPAREN)
atPos(accept(ARROW)) { makeByNameFunctionTypeTree(t0, typ()) }
} else {
- val t0 = typ();
+ val t0 = typ()
if (in.token == COMMA) {
- in.nextToken();
- val ts = new ListBuffer[Tree] + t0 ++ types();
- accept(RPAREN);
+ in.nextToken()
+ val ts = new ListBuffer[Tree] + t0 ++ types()
+ accept(RPAREN)
atPos (accept(ARROW)) { makeFunctionTypeTree(ts.toList, typ()) }
} else {
accept(RPAREN); t0
@@ -556,8 +556,8 @@ trait Parsers requires SyntaxAnalyzer {
/** Type1 ::= SimpleType {with SimpleType} [Refinement]
*/
def type1(): Tree = {
- val pos = in.currentPos;
- var ts = new ListBuffer[Tree] + simpleType();
+ val pos = in.currentPos
+ var ts = new ListBuffer[Tree] + simpleType()
while (in.token == WITH) {
in.nextToken(); ts += simpleType()
}
@@ -574,26 +574,26 @@ trait Parsers requires SyntaxAnalyzer {
* | `(' Type `)'
*/
def simpleType(): Tree = {
- val pos = in.currentPos;
+ val pos = in.currentPos
var t: Tree =
if (in.token == LPAREN) {
- in.nextToken();
- val t = typ();
- accept(RPAREN);
+ in.nextToken()
+ val t = typ()
+ accept(RPAREN)
t
} else {
- val r = path(false, true);
+ val r = path(false, true)
val x = r match {
case SingletonTypeTree(_) => r
- case _ => convertToTypeId(r);
+ case _ => convertToTypeId(r)
}
- // System.err.println("SIMPLE_TYPE: " + r.pos + " " + r + " => " + x.pos + " " + x);
- x;
+ // System.err.println("SIMPLE_TYPE: " + r.pos + " " + r + " => " + x.pos + " " + x)
+ x
}
while (true) {
if (in.token == HASH)
t = atPos(in.skipToken()) {
- SelectFromTypeTree(t, ident().toTypeName);
+ SelectFromTypeTree(t, ident().toTypeName)
}
else if (in.token == LBRACKET)
t = atPos(pos) { AppliedTypeTree(t, typeArgs()) }
@@ -606,36 +606,41 @@ trait Parsers requires SyntaxAnalyzer {
/** TypeArgs ::= `[' Types `]'
*/
def typeArgs(): List[Tree] = {
- accept(LBRACKET);
- val ts = types();
- accept(RBRACKET);
+ accept(LBRACKET)
+ val ts = types()
+ accept(RBRACKET)
ts
}
//////// EXPRESSIONS ////////////////////////////////////////////////////////
- var liftedGenerators = new collection.mutable.ListBuffer[Enumerator]
+ // XX_LIFTED
+ var liftedGenerators = new collection.mutable.ListBuffer[ValFrom]
+ // XX_LIFTED
def wrapLiftedGenerators(t: Tree): Tree =
if (liftedGenerators.isEmpty) t
else {
- val t1 = makeForYield(liftedGenerators.toList, t)
+ val t1 = makeLifted(liftedGenerators.toList, t)
liftedGenerators.clear
t1
}
+ // XX_LIFTED
def noLifting(op: => Tree): Tree = {
- val savedLiftedGenerators = liftedGenerators;
+ val savedLiftedGenerators = liftedGenerators
if (!savedLiftedGenerators.isEmpty) // optimization to avoid buffer allocation
liftedGenerators = new collection.mutable.ListBuffer
val t = op
- if (!liftedGenerators.isEmpty) syntaxError(t.pos, "no lifted expression allowed here", false)
+ if (!liftedGenerators.isEmpty)
+ syntaxError(liftedGenerators.toList.head.pos, "no lifted expression allowed here", false)
liftedGenerators = savedLiftedGenerators
t
}
+ // XX_LIFTED
def liftingScope(op: => Tree): Tree = {
- val savedLiftedGenerators = liftedGenerators;
+ val savedLiftedGenerators = liftedGenerators
if (!savedLiftedGenerators.isEmpty) // optimization to avoid buffer allocation
liftedGenerators = new collection.mutable.ListBuffer
val t = wrapLiftedGenerators(op)
@@ -653,7 +658,7 @@ trait Parsers requires SyntaxAnalyzer {
/** Exprs ::= Expr {`,' Expr} [ `:' `_' `*' ]
*/
def argExprs(): List[Tree] = {
- val ts = new ListBuffer[Tree] + argExpr();
+ val ts = new ListBuffer[Tree] + argExpr()
while (in.token == COMMA) {
in.nextToken(); ts += argExpr()
}
@@ -705,24 +710,24 @@ trait Parsers requires SyntaxAnalyzer {
val thenp = expr()
val elsep =
if (in.token == ELSE) { in.nextToken(); expr() }
- else EmptyTree;
+ else EmptyTree
atPos(pos) { If(cond, thenp, elsep) }
case TRY =>
atPos(in.skipToken()) {
- accept(LBRACE);
- val body = block();
- accept(RBRACE);
+ accept(LBRACE)
+ val body = block()
+ accept(RBRACE)
val catches =
if (in.token == CATCH) {
- in.nextToken();
- accept(LBRACE);
- val cases = caseClauses();
- accept(RBRACE);
+ in.nextToken()
+ accept(LBRACE)
+ val cases = caseClauses()
+ accept(RBRACE)
cases
- } else List();
+ } else List()
val finalizer =
if (in.token == FINALLY) { in.nextToken(); expr() }
- else EmptyTree;
+ else EmptyTree
Try(body, catches, finalizer)
}
case WHILE =>
@@ -746,11 +751,11 @@ trait Parsers requires SyntaxAnalyzer {
atPos(pos) { makeDoWhile(lname, body, cond) }
case FOR =>
atPos(in.skipToken()) {
- val startToken = in.token;
- accept(if (startToken == LBRACE) LBRACE else LPAREN);
- val enums = enumerators();
- accept(if (startToken == LBRACE) RBRACE else RPAREN);
- newLineOpt();
+ val startToken = in.token
+ accept(if (startToken == LBRACE) LBRACE else LPAREN)
+ val enums = enumerators()
+ accept(if (startToken == LBRACE) RBRACE else RPAREN)
+ newLineOpt()
if (in.token == YIELD) {
in.nextToken(); makeForYield(enums, expr())
} else makeFor(enums, expr())
@@ -774,7 +779,7 @@ trait Parsers requires SyntaxAnalyzer {
}
}
case _ =>
- var t = postfixExpr();
+ var t = postfixExpr()
if (in.token == EQUALS) {
t match {
case Ident(_) | Select(_, _) | Apply(_, _) =>
@@ -782,11 +787,11 @@ trait Parsers requires SyntaxAnalyzer {
case _ =>
}
} else if (in.token == COLON) {
- val pos = in.skipToken();
+ val pos = in.skipToken()
if (isArgument && in.token == USCORE) {
- val pos1 = in.skipToken();
+ val pos1 = in.skipToken()
if (isIdent && in.name == nme.STAR) {
- in.nextToken();
+ in.nextToken()
t = atPos(pos) {
Typed(t, atPos(pos1) { Ident(nme.WILDCARD_STAR.toTypeName) })
}
@@ -796,9 +801,9 @@ trait Parsers requires SyntaxAnalyzer {
} else {
t = atPos(pos) { Typed(t, if (isInBlock) type1() else typ()) }
if (isInBlock && in.token == COMMA) {
- val vdefs = new ListBuffer[ValDef];
+ val vdefs = new ListBuffer[ValDef]
while (in.token == COMMA) {
- in.nextToken();
+ in.nextToken()
vdefs += ValDef(Modifiers(Flags.PARAM), ident(), typedOpt(), EmptyTree)
}
if (in.token == ARROW) {
@@ -833,18 +838,18 @@ trait Parsers requires SyntaxAnalyzer {
var top = prefixExpr()
while (isIdent) {
top = reduceStack(
- true, base, top, precedence(in.name), treeInfo.isLeftAssoc(in.name));
- opstack = OpInfo(top, in.name, in.currentPos) :: opstack;
- ident();
- newLineOptWhenFollowing(isExprIntroToken);
+ true, base, top, precedence(in.name), treeInfo.isLeftAssoc(in.name))
+ opstack = OpInfo(top, in.name, in.currentPos) :: opstack
+ ident()
+ newLineOptWhenFollowing(isExprIntroToken)
if (isExprIntro) {
- top = prefixExpr();
+ top = prefixExpr()
} else {
- val topinfo = opstack.head;
- opstack = opstack.tail;
+ val topinfo = opstack.head
+ opstack = opstack.tail
return Select(
reduceStack(true, base, topinfo.operand, 0, true),
- topinfo.operator.encode).setPos(topinfo.pos);
+ topinfo.operator.encode).setPos(topinfo.pos)
}
}
reduceStack(true, base, top, 0, true)
@@ -854,24 +859,26 @@ trait Parsers requires SyntaxAnalyzer {
*/
def prefixExpr(): Tree =
if (isIdent && in.name == MINUS) {
- val name = ident();
+ val name = ident()
in.token match {
case INTLIT | LONGLIT | FLOATLIT | DOUBLELIT => literal(false, true)
case _ => atPos(in.currentPos) { Select(simpleExpr(), name) }
}
} else if (isIdent && (in.name == PLUS || in.name == TILDE || in.name == BANG)) {
- val pos = in.currentPos;
- val name = ident();
+ val pos = in.currentPos
+ val name = ident()
atPos(pos) { Select(simpleExpr(), name) }
} else if (isIdent && in.name == AMP) {
- val pos = in.currentPos;
- val name = ident();
+ val pos = in.currentPos
+ val name = ident()
atPos(pos) { Typed(simpleExpr(), Function(List(), EmptyTree)) }
- } else if (isIdent && in.name == SLASH) {
+/* XX-LIFTING
+ } else if (settings.Xexperimental.value && isIdent && in.name == SLASH) {
val pos = in.skipToken()
val name = freshName()
- liftedGenerators += makeGenerator(pos, Ident(name), false, simpleExpr())
+ liftedGenerators += ValFrom(pos, Bind(name, Ident(nme.WILDCARD)), simpleExpr())
Ident(name) setPos pos
+*/
} else {
simpleExpr()
}
@@ -904,13 +911,13 @@ trait Parsers requires SyntaxAnalyzer {
val pos = in.skipToken()
if (in.token == RPAREN) {
in.nextToken()
- t = Literal(()).setPos(pos);
+ t = Literal(()).setPos(pos)
} else {
t = localExpr()
if (in.token == COMMA) {
val commapos = in.skipToken()
val ts = new ListBuffer[Tree] + t ++ argExprs()
- accept(RPAREN);
+ accept(RPAREN)
if (in.token == ARROW) {
t = atPos(pos) {
Function(ts.toList map convertToParam, TypeTree())
@@ -926,16 +933,16 @@ trait Parsers requires SyntaxAnalyzer {
t = blockExpr()
case NEW =>
t = atPos(in.skipToken()) {
- val parents = new ListBuffer[Tree] + simpleType();
- val argss = new ListBuffer[List[Tree]];
+ val parents = new ListBuffer[Tree] + simpleType()
+ val argss = new ListBuffer[List[Tree]]
if (in.token == LPAREN)
do { argss += argumentExprs() } while (in.token == LPAREN)
- else argss += List();
+ else argss += List()
while (in.token == WITH) {
- in.nextToken();
+ in.nextToken()
parents += simpleType()
}
- val stats = if (in.token == LBRACE) templateBody() else List();
+ val stats = if (in.token == LBRACE) templateBody() else List()
makeNew(parents.toList, stats, argss.toList)
}
isNew = true
@@ -944,9 +951,9 @@ trait Parsers requires SyntaxAnalyzer {
if (in.token == MATCH)
syntaxErrorMigrate("`match' must be preceded by a selector expression")
else if (in.token == REQUIRES || in.token == IMPLICIT)
- syntaxErrorMigrate(""+in+" is now a reserved word; cannot be used as identifier");
+ syntaxErrorMigrate(""+in+" is now a reserved word; cannot be used as identifier")
}
- syntaxError("illegal start of simple expression", true);
+ syntaxError("illegal start of simple expression", true)
t = errorTermTree
}
while (true) {
@@ -958,7 +965,7 @@ trait Parsers requires SyntaxAnalyzer {
case Ident(_) | Select(_, _) =>
t = atPos(in.currentPos) { TypeApply(t, typeArgs()) }
case _ =>
- return t;
+ return t
}
case LPAREN | LBRACE if (!isNew) =>
t = atPos(in.currentPos) { Apply(t, argumentExprs()) }
@@ -997,14 +1004,14 @@ trait Parsers requires SyntaxAnalyzer {
/** Block ::= BlockStatSeq
*/
- def block(): Tree = makeBlock(blockStatSeq(new ListBuffer[Tree]));
+ def block(): Tree = makeBlock(blockStatSeq(new ListBuffer[Tree]))
/** CaseClauses ::= CaseClause {CaseClause}
*/
def caseClauses(): List[CaseDef] = {
- val ts = new ListBuffer[CaseDef];
- do { ts += caseClause();
- } while (in.token == CASE);
+ val ts = new ListBuffer[CaseDef]
+ do { ts += caseClause()
+ } while (in.token == CASE)
ts.toList
}
@@ -1012,10 +1019,10 @@ trait Parsers requires SyntaxAnalyzer {
*/
def caseClause(): CaseDef =
atPos(accept(CASE)) {
- val pat = pattern();
+ val pat = pattern()
val guard =
if (in.token == IF) { in.nextToken(); noLifting(postfixExpr()) }
- else EmptyTree;
+ else EmptyTree
makeCaseDef(pat, guard, atPos(accept(ARROW))(block()))
}
@@ -1025,9 +1032,9 @@ trait Parsers requires SyntaxAnalyzer {
* | Expr
*/
def enumerators(): List[Enumerator] = {
- val enums = new ListBuffer[Enumerator] + generator(false);
+ val enums = new ListBuffer[Enumerator] + generator(false)
while (in.token == SEMI || in.token == NEWLINE) {
- in.nextToken();
+ in.nextToken()
enums += (if (in.token == VAL) generator(true) else Filter(expr()))
}
enums.toList
@@ -1048,10 +1055,10 @@ trait Parsers requires SyntaxAnalyzer {
/** Patterns ::= SeqPattern { , SeqPattern } */
def patterns(): List[Tree] = {
- val ts = new ListBuffer[Tree];
- ts += pattern(true);
+ val ts = new ListBuffer[Tree]
+ ts += pattern(true)
while (in.token == COMMA) {
- in.nextToken(); ts += pattern(true);
+ in.nextToken(); ts += pattern(true)
}
ts.toList
}
@@ -1084,7 +1091,7 @@ trait Parsers requires SyntaxAnalyzer {
//if (false && /*disabled, no regexp matching*/ seqOK && !isExprIntro) {
//atPos(in.currentPos) { Sequence(List()) }
//} else {
- val p = pattern2(seqOK);
+ val p = pattern2(seqOK)
p match {
case Ident(name) if (treeInfo.isVarPattern(p) && in.token == COLON) =>
atPos(in.skipToken()) { Typed(p, type1()) }
@@ -1100,7 +1107,7 @@ trait Parsers requires SyntaxAnalyzer {
* | SeqPattern3
*/
def pattern2(seqOK: boolean): Tree = {
- val p = pattern3(seqOK);
+ val p = pattern3(seqOK)
if (in.token == AT) {
p match {
case Ident(name) =>
@@ -1158,20 +1165,20 @@ trait Parsers requires SyntaxAnalyzer {
*/
def simplePattern(seqOK: boolean): Tree = in.token match {
case IDENTIFIER | BACKQUOTED_IDENT | THIS =>
- var t = stableId();
+ var t = stableId()
in.token match {
case INTLIT | LONGLIT | FLOATLIT | DOUBLELIT =>
t match {
case Ident(name) if name == nme.MINUS =>
- return literal(true, true);
+ return literal(true, true)
case _ =>
}
case _ =>
}
if (in.token == LPAREN) {
atPos(in.skipToken()) {
- val ps = if (in.token == RPAREN) List() else patterns();
- accept(RPAREN);
+ val ps = if (in.token == RPAREN) List() else patterns()
+ accept(RPAREN)
Apply(convertToTypeId(t), ps)
}
} else t
@@ -1195,7 +1202,7 @@ trait Parsers requires SyntaxAnalyzer {
case _ =>
if (settings.migrate.value &&
in.token == MATCH || in.token == REQUIRES || in.token == IMPLICIT)
- syntaxErrorMigrate(""+in+" is now a reserved word; cannot be used as identifier");
+ syntaxErrorMigrate(""+in+" is now a reserved word; cannot be used as identifier")
syntaxError("illegal start of simple pattern", true)
errorPatternTree
}
@@ -1208,7 +1215,7 @@ trait Parsers requires SyntaxAnalyzer {
* | (private | protected) [ "[" Id "]" ]
*/
def modifiers(): Modifiers = {
- var privateWithin: Name = nme.EMPTY.toTypeName;
+ var privateWithin: Name = nme.EMPTY.toTypeName
def qualifierOpt: unit =
if (in.token == LBRACKET) {
in.nextToken()
@@ -1240,9 +1247,9 @@ trait Parsers requires SyntaxAnalyzer {
case _ =>
mods
}
- var mods = loop(0);
+ var mods = loop(0)
if ((mods & (Flags.ABSTRACT | Flags.OVERRIDE)) == (Flags.ABSTRACT | Flags.OVERRIDE))
- mods = mods & ~(Flags.ABSTRACT | Flags.OVERRIDE) | Flags.ABSOVERRIDE;
+ mods = mods & ~(Flags.ABSTRACT | Flags.OVERRIDE) | Flags.ABSOVERRIDE
Modifiers(mods, privateWithin)
}
@@ -1267,8 +1274,8 @@ trait Parsers requires SyntaxAnalyzer {
private def addMod(mods: int, mod: int): int = {
if ((mods & mod) != 0)
- syntaxError(in.currentPos, "repeated modifier", false);
- in.nextToken();
+ syntaxError(in.currentPos, "repeated modifier", false)
+ in.nextToken()
mods | mod
}
@@ -1276,7 +1283,7 @@ trait Parsers requires SyntaxAnalyzer {
/** ParamClauses ::= {[NewLine] `(' [Param {`,' Param}] ')'}
* [[NewLine] `(' implicit Param {`,' Param} `)']
- * Param ::= Id `:' ParamType
+ * Param ::= Id [`:' ParamType]
* ClassParamClauses ::= {[NewLine] `(' [ClassParam {`' ClassParam}] ')'}
* [[NewLine] `(' implicit ClassParam {`,' ClassParam} `)']
* ClassParam ::= [[modifiers] (val | var)] Param
@@ -1296,23 +1303,29 @@ trait Parsers requires SyntaxAnalyzer {
mods = mods | Flags.MUTABLE
in.nextToken()
} else {
- if (mods.flags != Flags.PARAMACCESSOR) accept(VAL);
+ if (mods.flags != Flags.PARAMACCESSOR) accept(VAL)
if (!(caseParam)) mods = mods | Flags.PRIVATE | Flags.LOCAL
}
if (caseParam) mods = mods | Flags.CASEACCESSOR
}
val name = ident()
- accept(COLON)
- val bynamemod =
- if (in.token == ARROW) {
- if (owner.isTypeName && !mods.hasFlag(Flags.LOCAL))
- syntaxError(
- in.currentPos,
- (if (mods.hasFlag(Flags.MUTABLE)) "`var'" else "`val'") +
- " parameters may not be call-by-name", false)
- Flags.BYNAMEPARAM
- } else 0;
- ValDef((mods | implicitmod | bynamemod) setAttr attrs, name, paramType(), EmptyTree)
+ var bynamemod = 0
+ val tpt =
+ if (settings.Xexperimental.value && !owner.isTypeName && in.token != COLON) {
+ TypeTree()
+ } else { // XX-METHOD-INFER
+ accept(COLON)
+ if (in.token == ARROW) {
+ if (owner.isTypeName && !mods.hasFlag(Flags.LOCAL))
+ syntaxError(
+ in.currentPos,
+ (if (mods.hasFlag(Flags.MUTABLE)) "`var'" else "`val'") +
+ " parameters may not be call-by-name", false)
+ else bynamemod = Flags.BYNAMEPARAM
+ }
+ paramType()
+ }
+ ValDef((mods | implicitmod | bynamemod) setAttr attrs, name, tpt, EmptyTree)
}
}
def paramClause(): List[ValDef] = {
@@ -1320,11 +1333,11 @@ trait Parsers requires SyntaxAnalyzer {
if (in.token != RPAREN) {
if (in.token == IMPLICIT) {
if (!implicitViews.isEmpty)
- syntaxError("cannot have both view bounds `<%' and implicit parameters", false);
+ syntaxError("cannot have both view bounds `<%' and implicit parameters", false)
in.nextToken()
implicitmod = Flags.IMPLICIT
}
- params += param();
+ params += param()
while (in.token == COMMA) {
in.nextToken(); params += param()
}
@@ -1346,9 +1359,9 @@ trait Parsers requires SyntaxAnalyzer {
(result.isEmpty ||
(!result.head.isEmpty && result.head.head.mods.hasFlag(Flags.IMPLICIT))))
if (in.token == LBRACKET)
- syntaxError(pos, "no type parameters allowed here", false);
+ syntaxError(pos, "no type parameters allowed here", false)
else
- syntaxError(pos, "auxiliary constructor needs non-implicit parameter list", false);
+ syntaxError(pos, "auxiliary constructor needs non-implicit parameter list", false)
addImplicitViews(owner, result, implicitViews)
}
@@ -1363,7 +1376,7 @@ trait Parsers requires SyntaxAnalyzer {
else {
val t = typ()
if (isIdent && in.name == STAR) {
- in.nextToken();
+ in.nextToken()
atPos(t.pos) {
AppliedTypeTree(
scalaDot(nme.REPEATED_PARAM_CLASS_NAME.toTypeName), List(t))
@@ -1415,7 +1428,7 @@ trait Parsers requires SyntaxAnalyzer {
def typeBounds(mods: Modifiers, name: Name): AbsTypeDef = {
def bound(tok: int, default: Name): Tree =
if (in.token == tok) { in.nextToken(); typ() }
- else scalaDot(default.toTypeName);
+ else scalaDot(default.toTypeName)
AbsTypeDef(mods, name.toTypeName,
bound(SUPERTYPE, nme.All),
bound(SUBTYPE, nme.Any))
@@ -1444,15 +1457,15 @@ trait Parsers requires SyntaxAnalyzer {
if (in.token == THIS) {
t = atPos(in.currentPos) { This(nme.EMPTY.toTypeName) }
t = atPos(accept(DOT)) { selector(t) }
- pos = accept(DOT);
+ pos = accept(DOT)
} else {
val i = atPos(in.currentPos) { Ident(ident()) }
- pos = accept(DOT);
+ pos = accept(DOT)
if (in.token == THIS) {
- in.nextToken();
+ in.nextToken()
t = atPos(i.pos) { This(i.name.toTypeName) }
t = atPos(accept(DOT)) { selector(t) }
- pos = accept(DOT);
+ pos = accept(DOT)
} else {
t = i
}
@@ -1464,7 +1477,7 @@ trait Parsers requires SyntaxAnalyzer {
} else if (in.token == LBRACE) {
Import(t, importSelectors())
} else {
- val name = ident();
+ val name = ident()
if (in.token == DOT) {
t = atPos(pos) { Select(t, name) }
pos = accept(DOT)
@@ -1500,11 +1513,11 @@ trait Parsers requires SyntaxAnalyzer {
names += Pair(
name,
if (in.token == ARROW) {
- in.nextToken();
+ in.nextToken()
if (in.token == USCORE) { in.nextToken(); nme.WILDCARD } else ident()
} else {
name
- });
+ })
false
}
@@ -1541,14 +1554,14 @@ trait Parsers requires SyntaxAnalyzer {
var newmods = mods
var lhs = new ListBuffer[Tree]
do {
- in.nextToken();
+ in.nextToken()
lhs += pattern2(false)
- } while (in.token == COMMA);
+ } while (in.token == COMMA)
val tp = typedOpt()
val rhs =
if (tp.isEmpty || in.token == EQUALS) equalsExpr()
else {
- newmods = newmods | Flags.DEFERRED;
+ newmods = newmods | Flags.DEFERRED
EmptyTree
}
def mkDefs(p: Tree): List[Tree] = {
@@ -1559,11 +1572,11 @@ trait Parsers requires SyntaxAnalyzer {
p
else
Typed(p, tp),
- rhs.duplicate) map atPos(p.pos);
+ rhs.duplicate) map atPos(p.pos)
if (rhs == EmptyTree) {
trees match {
case List(ValDef(_, _, _, EmptyTree)) =>
- case _ => syntaxError(p.pos, "pattern definition may not be abstract", false);
+ case _ => syntaxError(p.pos, "pattern definition may not be abstract", false)
}
}
trees
@@ -1576,14 +1589,14 @@ trait Parsers requires SyntaxAnalyzer {
* VarDcl ::= Id {`,' Id} `:' Type
*/
def varDefOrDcl(mods: Modifiers): List[Tree] = {
- var newmods = mods | Flags.MUTABLE;
- val lhs = new ListBuffer[Pair[Int, Name]];
+ var newmods = mods | Flags.MUTABLE
+ val lhs = new ListBuffer[Pair[Int, Name]]
do {
lhs += Pair(in.skipToken(), ident())
- } while (in.token == COMMA);
+ } while (in.token == COMMA)
val tp = typedOpt()
val rhs = if (tp.isEmpty || in.token == EQUALS) {
- accept(EQUALS);
+ accept(EQUALS)
if (!tp.isEmpty && in.token == USCORE) {
in.nextToken()
EmptyTree
@@ -1626,7 +1639,7 @@ trait Parsers requires SyntaxAnalyzer {
EmptyTree
} else if (restype.isEmpty && in.token == LBRACE) {
restype = scalaUnitConstr
- block()
+ blockExpr()
} else equalsExpr()
DefDef(newmods, name, tparams, vparamss, restype, rhs)
}
@@ -1651,12 +1664,12 @@ trait Parsers requires SyntaxAnalyzer {
*/
def constrBlock(): Tree =
atPos(in.skipToken()) {
- val statlist = new ListBuffer[Tree];
- statlist += selfInvocation();
+ val statlist = new ListBuffer[Tree]
+ statlist += selfInvocation()
val stats =
if (in.token == SEMI || in.token == NEWLINE) {
in.nextToken(); blockStatSeq(statlist)
- } else statlist.toList;
+ } else statlist.toList
accept(RBRACE)
makeBlock(stats)
}
@@ -1669,7 +1682,7 @@ trait Parsers requires SyntaxAnalyzer {
val name = ident().toTypeName
in.token match {
case LBRACKET =>
- val tparams = typeParamClauseOpt(name, null);
+ val tparams = typeParamClauseOpt(name, null)
accept(EQUALS)
AliasTypeDef(mods, name, tparams, typ())
case EQUALS =>
@@ -1708,17 +1721,17 @@ trait Parsers requires SyntaxAnalyzer {
*/
def classDef(mods: Modifiers): ClassDef =
atPos(in.skipToken()) {
- val name = ident().toTypeName;
- val implicitViews = new ListBuffer[Tree];
- val tparams = typeParamClauseOpt(name, implicitViews);
- //if (mods.hasFlag(Flags.CASE) && in.token != LPAREN) accept(LPAREN);
+ val name = ident().toTypeName
+ val implicitViews = new ListBuffer[Tree]
+ val tparams = typeParamClauseOpt(name, implicitViews)
+ //if (mods.hasFlag(Flags.CASE) && in.token != LPAREN) accept(LPAREN)
val vparamss = if (mods.hasFlag(Flags.TRAIT)) List()
- else paramClauses(name, implicitViews.toList, mods.hasFlag(Flags.CASE));
- val thistpe = requiresTypeOpt();
- val template = classTemplate(mods, name, vparamss);
+ else paramClauses(name, implicitViews.toList, mods.hasFlag(Flags.CASE))
+ val thistpe = requiresTypeOpt()
+ val template = classTemplate(mods, name, vparamss)
val mods1 = if (mods.hasFlag(Flags.TRAIT) && (template.body forall treeInfo.isInterfaceMember))
mods | Flags.INTERFACE
- else mods;
+ else mods
ClassDef(mods1, name, tparams, thistpe, template)
}
@@ -1726,8 +1739,8 @@ trait Parsers requires SyntaxAnalyzer {
*/
def objectDef(mods: Modifiers): ModuleDef =
atPos(in.skipToken()) {
- val name = ident();
- val template = classTemplate(mods, name, List());
+ val name = ident()
+ val template = classTemplate(mods, name, List())
ModuleDef(mods, name, template)
}
@@ -1740,21 +1753,21 @@ trait Parsers requires SyntaxAnalyzer {
atPos(in.currentPos) {
def acceptEmptyTemplateBody(msg: String): unit = {
if (in.token == LPAREN && settings.migrate.value)
- syntaxErrorMigrate("traites may not have parameters");
+ syntaxErrorMigrate("traites may not have parameters")
if (!(in.token == SEMI || in.token == NEWLINE ||
in.token == COMMA || in.token == RBRACE || in.token == EOF))
- syntaxError(msg, true);
+ syntaxError(msg, true)
}
- val parents = new ListBuffer[Tree];
- val argss = new ListBuffer[List[Tree]];
+ val parents = new ListBuffer[Tree]
+ val argss = new ListBuffer[List[Tree]]
if (in.token == EXTENDS) {
- in.nextToken();
+ in.nextToken()
val parent = simpleType()
- // System.err.println("classTempl: " + parent);
+ // System.err.println("classTempl: " + parent)
parents += parent
if (in.token == LPAREN)
do { argss += argumentExprs() } while (in.token == LPAREN)
- else argss += List();
+ else argss += List()
while (in.token == WITH) {
in.nextToken()
parents += simpleType()
@@ -1762,14 +1775,14 @@ trait Parsers requires SyntaxAnalyzer {
} else {
if (in.token == WITH && settings.migrate.value)
syntaxErrorMigrate("`extends' needed before `with'")
- if (in.token != LBRACE) acceptEmptyTemplateBody("`extends' or `{' expected");
+ if (in.token != LBRACE) acceptEmptyTemplateBody("`extends' or `{' expected")
argss += List()
}
if (name != nme.ScalaObject.toTypeName)
- parents += scalaScalaObjectConstr;
- if (mods.hasFlag(Flags.CASE)) parents += caseClassConstr;
- val ps = parents.toList;
- newLineOptWhenFollowedBy(LBRACE);
+ parents += scalaScalaObjectConstr
+ if (mods.hasFlag(Flags.CASE)) parents += caseClassConstr
+ val ps = parents.toList
+ newLineOptWhenFollowedBy(LBRACE)
var body =
if (in.token == LBRACE) templateBody()
else { acceptEmptyTemplateBody("`{' expected"); List() }
@@ -1819,7 +1832,7 @@ trait Parsers requires SyntaxAnalyzer {
* |
*/
def topStatSeq(): List[Tree] = {
- val stats = new ListBuffer[Tree];
+ val stats = new ListBuffer[Tree]
while (in.token != RBRACE && in.token != EOF) {
if (in.token == PACKAGE) {
stats += packaging()
@@ -1900,8 +1913,8 @@ trait Parsers requires SyntaxAnalyzer {
val pos = in.currentPos
var t: Tree = convertToTypeId(stableId())
if (in.token == LBRACKET)
- t = atPos(in.currentPos)(AppliedTypeTree(t, typeArgs()));
- val args = if (in.token == LPAREN) argumentExprs() else List();
+ t = atPos(in.currentPos)(AppliedTypeTree(t, typeArgs()))
+ val args = if (in.token == LPAREN) argumentExprs() else List()
val nameValuePairs: List[Tree] = if (in.token == LBRACE) {
in.nextToken()
val nvps = new ListBuffer[Tree] + nameValuePair()
@@ -1909,7 +1922,7 @@ trait Parsers requires SyntaxAnalyzer {
in.nextToken()
nvps += nameValuePair()
}
- accept(RBRACE);
+ accept(RBRACE)
nvps.toList
} else List()
val constr = atPos(pos) { New(t, List(args)) }
@@ -1935,7 +1948,7 @@ trait Parsers requires SyntaxAnalyzer {
}
if (!attrs.isEmpty)
defs foreach setAttr
- defs;
+ defs
}
/** RefineStatSeq ::= RefineStat {StatementSeparator RefineStat}
@@ -1987,8 +2000,9 @@ trait Parsers requires SyntaxAnalyzer {
localDef(localModifiers())
} else if (in.token == SEMI || in.token == NEWLINE) {
in.nextToken()
- } else
+ } else {
syntaxError("illegal start of statement", true)
+ }
}
stats.toList
}
@@ -2006,7 +2020,7 @@ trait Parsers requires SyntaxAnalyzer {
in.nextToken()
makePackaging(pkg, topStatSeq())
} else {
- accept(LBRACE);
+ accept(LBRACE)
val t = makePackaging(pkg, topStatSeq())
accept(RBRACE)
if (in.token == SEMI || in.token == NEWLINE) in.nextToken()
diff --git a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala
index 329a65d5bb..ed51119904 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala
@@ -301,6 +301,18 @@ abstract class TreeBuilder {
def makeForYield(enums: List[Enumerator], body: Tree): Tree =
makeFor(nme.map, nme.flatMap, enums, body)
+ /** Create tree for a lifted expression XX-LIFTING
+ */
+ def makeLifted(gs: List[ValFrom], body: Tree): Tree = {
+ def combine(gs: List[ValFrom]): ValFrom = gs match {
+ case g :: Nil => g
+ case ValFrom(pos1, pat1, rhs1) :: gs2 =>
+ val ValFrom(pos2, pat2, rhs2) = combine(gs2)
+ ValFrom(pos1, makeTuple(List(pat1, pat2), true), Apply(Select(rhs1, nme.zip), List(rhs2)))
+ }
+ makeForYield(List(combine(gs)), body)
+ }
+
/** Create tree for a pattern alternative */
def makeAlternative(ts: List[Tree]): Tree = {
def alternatives(t: Tree): List[Tree] = t match {
diff --git a/src/compiler/scala/tools/nsc/symtab/StdNames.scala b/src/compiler/scala/tools/nsc/symtab/StdNames.scala
index 002ffb2ba3..72432c7fe8 100644
--- a/src/compiler/scala/tools/nsc/symtab/StdNames.scala
+++ b/src/compiler/scala/tools/nsc/symtab/StdNames.scala
@@ -289,6 +289,7 @@ trait StdNames requires SymbolTable {
val tag = newTermName("$tag")
val wait_ = newTermName("wait")
val xml = newTermName("xml")
+ val zip = newTermName("zip")
val ZNOT = encode("!")
val ZAND = encode("&&")
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
index 25b30c9c35..3210b3982f 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -407,24 +407,71 @@ trait Namers requires Analyzer {
private def methodSig(tparams: List[AbsTypeDef], vparamss: List[List[ValDef]],
tpt: Tree, rhs: Tree): Type = {
val meth = context.owner
+
val tparamSyms = typer.reenterTypeParams(tparams)
val vparamSymss = enterValueParams(meth, vparamss)
- val restype =
- if (tpt.isEmpty) {
- tpt.tpe = if (meth.name == nme.CONSTRUCTOR) context.enclClass.owner.tpe
- else deconstIfNotFinal(meth, typer.computeType(rhs));
- tpt.tpe
- } else typer.typedType(tpt).tpe;
- def mkMethodType(vparams: List[Symbol], restpe: Type) = {
- val formals = vparams map (.tpe);
- if (!vparams.isEmpty && vparams.head.hasFlag(IMPLICIT)) ImplicitMethodType(formals, restpe)
- else MethodType(formals, restpe);
+ if (tpt.isEmpty && meth.name == nme.CONSTRUCTOR) tpt.tpe = context.enclClass.owner.tpe
+
+ def makeMethodType(vparams: List[Symbol], restpe: Type) = {
+ val formals = vparams map (.tpe);
+ if (!vparams.isEmpty && vparams.head.hasFlag(IMPLICIT)) ImplicitMethodType(formals, restpe)
+ else MethodType(formals, restpe);
}
- makePolyType(
- tparamSyms,
- if (vparamSymss.isEmpty) PolyType(List(), restype)
- else (vparamSymss :\ restype)(mkMethodType))
- }
+
+ def thisMethodType(restype: Type) =
+ makePolyType(
+ tparamSyms,
+ if (vparamSymss.isEmpty) PolyType(List(), restype)
+ else (vparamSymss :\ restype)(makeMethodType))
+
+ if (meth.owner.isClass && (tpt.isEmpty || vparamss.exists(.exists(.tpt.isEmpty)))) {
+ // try to complete from matching definition in base type
+ for (val vparams <- vparamss; val vparam <- vparams)
+ if (vparam.tpt.isEmpty) vparam.symbol setInfo WildcardType
+ val schema = thisMethodType(if (tpt.isEmpty) WildcardType else typer.typedType(tpt).tpe)
+ val site = meth.owner.thisType
+ val overridden = intersectionType(meth.owner.info.parents).member(meth.name).filter(sym =>
+ sym != NoSymbol && (site.memberType(sym) matches schema))
+ if (overridden != NoSymbol && !(overridden hasFlag OVERLOADED)) {
+ var pt = site.memberType(overridden) match {
+ case PolyType(tparams, rt) => rt.substSym(tparamSyms, tparams)
+ case mt => mt
+ }
+ for (val vparams <- vparamss) {
+ var pfs = pt.paramTypes
+ for (val vparam <- vparams) {
+ if (vparam.tpt.isEmpty) {
+ vparam.tpt.tpe = pfs.head
+ vparam.symbol setInfo pfs.head
+ }
+ pfs = pfs.tail
+ }
+ pt = pt.resultType
+ }
+ if (tpt.isEmpty) {
+ // provisionally assign `meth' a method type with inherited result type
+ // that way, we can leave out the result type even if method is recursive.
+ meth setInfo thisMethodType(
+ pt match {
+ case PolyType(List(), rtpe) => rtpe
+ case MethodType(List(), rtpe) => rtpe
+ case _ => pt
+ })
+ }
+ }
+ }
+
+ for (val vparams <- vparamss; val vparam <- vparams; vparam.tpt.isEmpty) {
+ context.error(vparam.pos, "missing parameter type")
+ vparam.tpt.tpe = ErrorType
+ }
+
+ thisMethodType(
+ if (tpt.isEmpty) {
+ tpt.tpe = deconstIfNotFinal(meth, typer.computeType(rhs));
+ tpt.tpe
+ } else typer.typedType(tpt).tpe)
+ }
/** If `sym' is an implicit value, check that its type signature `tp' is contractive.
* This means: The type of every implicit parameter is properly contained