summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2005-02-21 17:19:28 +0000
committerMartin Odersky <odersky@gmail.com>2005-02-21 17:19:28 +0000
commita50c72311952db8e6273a4048deee806db36110a (patch)
tree203bdce52f0552f79c904a0203cc4875be3d94eb
parent1b7d5dbc1f4a36b3099b5cb376c1dd6f8f747295 (diff)
downloadscala-a50c72311952db8e6273a4048deee806db36110a.tar.gz
scala-a50c72311952db8e6273a4048deee806db36110a.tar.bz2
scala-a50c72311952db8e6273a4048deee806db36110a.zip
*** empty log message ***
-rw-r--r--sources/scala/List.scala14
-rwxr-xr-xsources/scala/tools/nsc/Global.scala19
-rw-r--r--sources/scala/tools/nsc/StdPhase.scala3
-rw-r--r--sources/scala/tools/nsc/ast/TreeInfo.scala6
-rw-r--r--sources/scala/tools/nsc/ast/TreePrinters.scala47
-rw-r--r--sources/scala/tools/nsc/ast/Trees.scala119
-rwxr-xr-xsources/scala/tools/nsc/ast/parser/Syntactic.scala315
-rwxr-xr-xsources/scala/tools/nsc/symtab/Definitions.scala26
-rwxr-xr-xsources/scala/tools/nsc/symtab/Names.scala4
-rwxr-xr-xsources/scala/tools/nsc/symtab/StdNames.scala2
-rwxr-xr-xsources/scala/tools/nsc/symtab/Symbols.scala32
-rwxr-xr-xsources/scala/tools/nsc/symtab/Types.scala111
-rwxr-xr-xsources/scala/tools/nsc/symtab/classfile/UnPickle.scala2
-rw-r--r--sources/scala/tools/nsc/typechecker/Analyzer.scala9
-rwxr-xr-xsources/scala/tools/nsc/typechecker/Contexts.scala19
-rwxr-xr-xsources/scala/tools/nsc/typechecker/TypeCheckers.scala355
-rwxr-xr-xsources/scala/tools/nsc/typechecker/Typers.scala17
-rw-r--r--sources/scala/tools/scalac/typechecker/Analyzer.scala2
18 files changed, 626 insertions, 476 deletions
diff --git a/sources/scala/List.scala b/sources/scala/List.scala
index 5ce118412f..3808cb40d0 100644
--- a/sources/scala/List.scala
+++ b/sources/scala/List.scala
@@ -204,12 +204,24 @@ object List {
* @param f function to apply to each pair of elements.
* @return <code>[f(a0,b0), ..., f(an,bn)]</code> if the lists are
* <code>[a0, ..., ak]</code>, <code>[b0, ..., bl]</code> and
- * <code>m = min(k,l)</code>
+ * <code>n = min(k,l)</code>
*/
def map2[a,b,c](xs: List[a], ys: List[b])(f: (a, b) => c): List[c] =
if (xs.isEmpty || ys.isEmpty) Nil
else f(xs.head, ys.head) :: map2(xs.tail, ys.tail)(f);
+ /** Returns the list resulting from applying the given function <code>f</code> to
+ * corresponding elements of the argument lists.
+ *
+ * @param f function to apply to each pair of elements.
+ * @return <code>[f(a0,b0,c0), ..., f(an,bn,cn)]</code> if the lists are
+ * <code>[a0, ..., ak]</code>, <code>[b0, ..., bl]</code>, <code>[c0, ..., cm]</code> and
+ * <code>n = min(k,l,m)</code>
+ */
+ def map3[a,b,c, d](xs: List[a], ys: List[b], zs: List[c])(f: (a, b, c) => d): List[d] =
+ if (xs.isEmpty || ys.isEmpty || zs.isEmpty) Nil
+ else f(xs.head, ys.head, zs.head) :: map3(xs.tail, ys.tail, zs.tail)(f);
+
/** Tests whether the given predicate <code>p</code> holds
* for all corresponding elements of the argument lists.
*
diff --git a/sources/scala/tools/nsc/Global.scala b/sources/scala/tools/nsc/Global.scala
index b87b9e26f9..a6c09fe855 100755
--- a/sources/scala/tools/nsc/Global.scala
+++ b/sources/scala/tools/nsc/Global.scala
@@ -17,10 +17,7 @@ import ast._;
import ast.parser._;
import typechecker._;
-class Global(val settings: Settings, val reporter: Reporter)
- extends SymbolTable
- with Trees
- with CompilationUnits {
+class Global(val settings: Settings, val reporter: Reporter) extends SymbolTable with Trees with TreeCheckers with CompilationUnits {
// sub-components --------------------------------------------------
@@ -48,6 +45,7 @@ class Global(val settings: Settings, val reporter: Reporter)
def warning(msg: String) = reporter.warning(null, msg);
def inform(msg: String) = reporter.info(null, msg, true);
+
def log(msg: String) =
if (settings.log contains phase.name) inform("[log " + phase + "] " + msg);
@@ -115,15 +113,10 @@ class Global(val settings: Settings, val reporter: Reporter)
definitions.init; // needs firstPhase to be defined, that's why it is placed here.
- object deSugarizePhase extends DeSugarizePhase(parserPhase) {
- val global: Global.this.type = Global.this
- }
-
object analyzer extends Analyzer {
val global: Global.this.type = Global.this;
}
-
- val namerPhase = new analyzer.NamerPhase(deSugarizePhase);
+ val namerPhase = new analyzer.NamerPhase(parserPhase);
val typeCheckPhase = new analyzer.TypeCheckPhase(namerPhase);
val terminalPhase = new StdPhase(typeCheckPhase) {
@@ -159,11 +152,13 @@ class Global(val settings: Settings, val reporter: Reporter)
reporter.resetCounters();
for (val source <- sources)
addUnit(new CompilationUnit(source));
+
phase = NoPhase.next;
while (phase != terminalPhase && reporter.errors() == 0) {
val startTime = System.currentTimeMillis();
if (!(settings.skip contains phase.name)) phase.run;
if (settings.print contains phase.name) treePrinter.printAll();
+ if (settings.check contains phase.name) checkTrees;
informTime(phase.description, startTime);
phase = if (settings.stop contains phase.name) terminalPhase else phase.next;
}
@@ -199,6 +194,10 @@ class Global(val settings: Settings, val reporter: Reporter)
case ex: IOException => error(ex.getMessage());
}
+ def checkTrees: unit =
+ for (val unit <- units; val tree <- unit.body)
+ treeChecker.traverse(tree);
+
def showDef(name: Name, module: boolean): unit = {
def getSym(name: Name, module: boolean): Symbol = {
var i = name.length - 1;
diff --git a/sources/scala/tools/nsc/StdPhase.scala b/sources/scala/tools/nsc/StdPhase.scala
index 36bfaebf2c..7db984f563 100644
--- a/sources/scala/tools/nsc/StdPhase.scala
+++ b/sources/scala/tools/nsc/StdPhase.scala
@@ -7,8 +7,7 @@ package scala.tools.nsc;
abstract class StdPhase(prev: Phase) extends Phase(prev) {
val global: Global;
- def run: unit =
- for (val unit <- global.units) apply(unit);
+ def run: unit = for (val unit <- global.units) apply(unit);
def apply(unit: global.CompilationUnit): unit;
}
diff --git a/sources/scala/tools/nsc/ast/TreeInfo.scala b/sources/scala/tools/nsc/ast/TreeInfo.scala
index 7e703fbaf4..92e5c00cd4 100644
--- a/sources/scala/tools/nsc/ast/TreeInfo.scala
+++ b/sources/scala/tools/nsc/ast/TreeInfo.scala
@@ -114,7 +114,11 @@ abstract class TreeInfo {
case _ => firstConstructor(stats.tail)
}
- /** Is name a variable name */
+ /** Is name a left-associative operator? */
+ def isLeftAssoc(operator: Name): boolean =
+ operator.length > 0 && operator(operator.length - 1) != ':';
+
+ /** Is name a variable name? */
def isVariableName(name: Name): boolean = {
val first = name(0);
(('a' <= first && first <= 'z') || first == '_')
diff --git a/sources/scala/tools/nsc/ast/TreePrinters.scala b/sources/scala/tools/nsc/ast/TreePrinters.scala
index ae61481f85..47c8af4cfb 100644
--- a/sources/scala/tools/nsc/ast/TreePrinters.scala
+++ b/sources/scala/tools/nsc/ast/TreePrinters.scala
@@ -70,12 +70,17 @@ abstract class TreePrinters {
printOpt(">: ", lo); printOpt("<: ", hi);
}
+ def printBlock(tree: Tree): unit = tree match {
+ case Block(_, _) | Visitor(_) => print(tree)
+ case _ => printColumn(List(tree), "{", ";", "}")
+ }
+
def symName(tree: Tree, name: Name): String =
if (tree.symbol != null && tree.symbol != NoSymbol) tree.symbol.nameString
else name.toString();
def printOpt(prefix: String, tree: Tree): unit =
- if (tree != EmptyTree) { print(prefix); print(tree) }
+ if (!tree.isEmpty) { print(prefix); print(tree) }
def printModifiers(flags: int): unit = {
val s = flagsToString(flags);
@@ -109,7 +114,7 @@ abstract class TreePrinters {
printOpt(": ", tp);
if ((mods & DEFERRED) == 0) {
print(" = ");
- if (rhs == EmptyTree) print("_") else print(rhs)
+ if (rhs.isEmpty) print("_") else print(rhs)
}
case DefDef(mods, name, tparams, vparams, tp, rhs) =>
@@ -126,22 +131,14 @@ abstract class TreePrinters {
printTypeParams(tparams); printOpt(" = ", rhs);
case LabelDef(name, params, rhs) =>
- print(symName(tree, name)); printRow(params, "(", ",", ")"); print(rhs);
+ print(symName(tree, name)); printRow(params, "(", ",", ")"); printBlock(rhs);
case Import(expr, selectors) =>
- def printSelectors(ss: List[Pair[Name, Name]]): unit = ss match {
- case List(Pair(nme.WILDCARD, _)) => print("_");
- case Pair(s1, s2) :: ss1 =>
- print(s1);
- if (s1 != s2) print("=>" + s2);
- if (!ss1.isEmpty) {
- print(", "); printSelectors(ss1);
- }
- }
- print("import "); print(expr); print(".{"); printSelectors(selectors); print("}");
-
- case PatDef(mods, pat, rhs) =>
- print(flagsToString(mods) + " val "); print(pat); printOpt(" = ", rhs);
+ def selectorToString(s: Pair[Name, Name]): String =
+ if (s._1 == nme.WILDCARD || s._1 == s._2) s._1.toString()
+ else s._1.toString() + "=>" + s._2.toString();
+ print("import "); print(expr);
+ print(selectors.map(selectorToString).mkString(".{", ", ", "}"))
case Attributed(attr, definition) =>
print("["); print(attr); print("]"); println; print(definition);
@@ -177,15 +174,10 @@ abstract class TreePrinters {
case Assign(lhs, rhs) =>
print(lhs); print(" = "); print(rhs)
- case For(enumerators, body, isForYield) =>
- printRow(enumerators, "for(", "; ", ") ");
- if (isForYield) print("yield ");
- print(body)
-
case If(cond, thenp, elsep) =>
print("if ("); print(cond); print(")"); indent; println;
print(thenp); undent;
- if (elsep != EmptyTree) {
+ if (!elsep.isEmpty) {
println; print("else"); indent; println; print(elsep); undent
}
@@ -199,8 +191,9 @@ abstract class TreePrinters {
print("return "); print(expr)
case Try(block, catcher, finalizer) =>
- print("try "); print(block); print(" catch "); print(catcher);
- print(" finally "); print(finalizer)
+ print("try "); printBlock(block);
+ printOpt(" catch ", catcher);
+ printOpt(" finally ", finalizer)
case Throw(expr) =>
print("throw "); print(expr)
@@ -239,6 +232,7 @@ abstract class TreePrinters {
print(obj match {
case null => "null"
case s: String => "\"" + s + "\""
+ case c: char => "\'" + c + "\'"
case _ => obj.toString()
})
@@ -251,9 +245,6 @@ abstract class TreePrinters {
case SelectFromTypeTree(qualifier, selector) =>
print(qualifier); print("#"); print(symName(tree, selector))
- case FunctionTypeTree(argtpes, restpe) =>
- printRow(argtpes, "(", ", ", ") => "); print(restpe)
-
case IntersectionTypeTree(parents) =>
printRow(parents, " with ")
@@ -263,7 +254,7 @@ abstract class TreePrinters {
case AppliedTypeTree(tp, args) =>
print(tp); printRow(args, "[", ", ", "]")
}
- if (global.settings.printtypes.value && tree.isTerm && tree != EmptyTree) {
+ if (global.settings.printtypes.value && tree.isTerm && !tree.isEmpty) {
print("{"); print(if (tree.tpe == null) "<null>" else tree.tpe.toString()); print("}")
}
}
diff --git a/sources/scala/tools/nsc/ast/Trees.scala b/sources/scala/tools/nsc/ast/Trees.scala
index 909c15d5b0..5178ad1dba 100644
--- a/sources/scala/tools/nsc/ast/Trees.scala
+++ b/sources/scala/tools/nsc/ast/Trees.scala
@@ -103,10 +103,6 @@ class Trees: Global {
case class Import(expr: Tree, selectors: List[Pair[Name, Name]])
extends SymTree;
- /** Pattern definition, eliminated by Analyzer */
- case class PatDef(mods: int, pat: Tree, rhs: Tree)
- extends Tree;
-
/** Attribuetd definition */
case class Attributed(attribute: Tree, definition: Tree)
extends Tree;
@@ -156,10 +152,6 @@ class Trees: Global {
case class If(cond: Tree, thenp: Tree, elsep: Tree)
extends TermTree;
- /** For comprehension */
- case class For(enumerators: List[Tree], body: Tree, isForYield: boolean)
- extends TermTree;
-
/** Switch, introduced by refcheck */
case class Switch(test: Tree, tags: List[int], bodies: List[Tree],
default: Tree)
@@ -179,7 +171,7 @@ class Trees: Global {
/** Object instantiation
* @param init either a constructor or a template
*/
- case class New(init: Tree)
+ case class New(typeOrTempl: Tree)
extends TermTree;
/** Type annotation, eliminated by explicit outer */
@@ -222,7 +214,7 @@ class Trees: Global {
/** General type term, introduced by RefCheck. */
case class EmptyTypeTree() extends TypeTree {
- override def isEmpty = true;
+ override def isEmpty = tpe == null;
}
/** Singleton type, eliminated by RefCheck */
@@ -233,10 +225,6 @@ class Trees: Global {
case class SelectFromTypeTree(qualifier: Tree, selector: Name)
extends TypeTree with SymTree;
- /** Function type, eliminated by RefCheck */
- case class FunctionTypeTree(argtpes: List[Tree], restpe: Tree)
- extends TypeTree;
-
/** Intersection type, eliminated by RefCheck */
case class IntersectionTypeTree(parents: List[Tree])
extends TypeTree;
@@ -253,33 +241,31 @@ class Trees: Global {
case EmptyTree =>
case ClassDef(mods, name, tparams, tp, impl) =>
case PackageDef(name, stats) =>
- case ModuleDef(mods, name, tp, impl) =>
+ case ModuleDef(mods, name, tp, impl) => (eliminated by refcheck)
case ValDef(mods, name, tp, rhs) =>
case DefDef(mods, name, tparams, vparams, tp, rhs) =>
- case AbsTypeDef(mods, name, lo, hi) =>
- case AliasTypeDef(mods, name, tparams, rhs) =>
+ case AbsTypeDef(mods, name, lo, hi) => (eliminated by erasure)
+ case AliasTypeDef(mods, name, tparams, rhs) => (eliminated by erasure)
case LabelDef(name, params, rhs) =>
- case Import(expr, selectors) =>
- case PatDef(mods, pat, rhs) =>
- case Attributed(attribute, definition) =>
- case DocDef(comment, definition) =>
+ case Import(expr, selectors) => (eliminated by typecheck)
+ case Attributed(attribute, definition) => (eliminated by typecheck)
+ case DocDef(comment, definition) => (eliminated by typecheck)
case Template(parents, body) =>
case Block(stats, expr) =>
- case Visitor(cases) =>
- case CaseDef(pat, guard, body) =>
- case Sequence(trees) =>
- case Alternative(trees) =>
- case Bind(name, rhs) =>
- case Function(vparams, body) =>
+ case Visitor(cases) => (eliminated by transmatch)
+ case CaseDef(pat, guard, body) => (eliminated by transmatch)
+ case Sequence(trees) => (eliminated by transmatch)
+ case Alternative(trees) => (eliminated by transmatch)
+ case Bind(name, rhs) => (eliminated by transmatch)
+ case Function(vparams, body) => (eliminated by typecheck)
case Assign(lhs, rhs) =>
- case For(enumerators, body, isForYield) =>
case If(cond, thenp, elsep) =>
- case Switch(test, tags, bodies, default) =>
+ case Switch(test, tags, bodies, default) => (introduced by refcheck, transmatch)
case Return(expr) =>
case Try(block, catcher, finalizer) =>
case Throw(expr) =>
- case New(init) =>
- case Typed(expr, tp) =>
+ case New(typeOrTempl) =>
+ case Typed(expr, tp) => (eliminated by erasure)
case TypeApply(fun, args) =>
case Apply(fun, args) =>
case Super(qual, mixin) =>
@@ -287,13 +273,12 @@ class Trees: Global {
case Select(qualifier, selector) =>
case Ident(name) =>
case Literal(value) =>
- case EmptyTypeTree() =>
- case SingletonTypeTree(ref) =>
- case SelectFromTypeTree(qualifier, selector) =>
- case FunctionTypeTree(argtpes, restpe) =>
- case IntersectionTypeTree(parents) =>
- case RefinementTypeTree(base, decls) =>
- case AppliedTypeTree(tp, args) =>
+ case EmptyTypeTree() => (eliminated by typecheck)
+ case SingletonTypeTree(ref) => (eliminated by typecheck)
+ case SelectFromTypeTree(qualifier, selector) => (eliminated by typecheck)
+ case IntersectionTypeTree(parents) => (eliminated by typecheck)
+ case RefinementTypeTree(base, decls) => (eliminated by typecheck)
+ case AppliedTypeTree(tp, args) => (eliminated by typecheck)
*/
trait TreeCopier {
@@ -306,7 +291,6 @@ class Trees: Global {
def AliasTypeDef(tree: Tree, mods: int, name: Name, tparams: List[AbsTypeDef], rhs: Tree): AliasTypeDef;
def LabelDef(tree: Tree, name: Name, params: List[Ident], rhs: Tree): LabelDef;
def Import(tree: Tree, expr: Tree, selectors: List[Pair[Name, Name]]): Import;
- def PatDef(tree: Tree, mods: int, pat: Tree, rhs: Tree): PatDef;
def Attributed(tree: Tree, attribute: Tree, definition: Tree): Attributed;
def DocDef(tree: Tree, comment: String, definition: Tree): DocDef;
def Template(tree: Tree, parents: List[Tree], body: List[Tree]): Template;
@@ -319,12 +303,11 @@ class Trees: Global {
def Function(tree: Tree, vparams: List[ValDef], body: Tree): Function;
def Assign(tree: Tree, lhs: Tree, rhs: Tree): Assign;
def If(tree: Tree, cond: Tree, thenp: Tree, elsep: Tree): If;
- def For(tree: Tree, enumerators: List[Tree], body: Tree, isForYield: boolean): For;
def Switch(tree: Tree, test: Tree, tags: List[int], bodies: List[Tree], default: Tree): Switch;
def Return(tree: Tree, expr: Tree): Return;
def Try(tree: Tree, block: Tree, catcher: Tree, finalizer: Tree): Try;
def Throw(tree: Tree, expr: Tree): Throw;
- def New(tree: Tree, init: Tree): New;
+ def New(tree: Tree, typeOrTempl: Tree): New;
def Typed(tree: Tree, expr: Tree, tp: Tree): Typed;
def TypeApply(tree: Tree, fun: Tree, args: List[Tree]): TypeApply;
def Apply(tree: Tree, fun: Tree, args: List[Tree]): Apply;
@@ -336,7 +319,6 @@ class Trees: Global {
def EmptyTypeTree(tree: Tree): EmptyTypeTree;
def SingletonTypeTree(tree: Tree, ref: Tree): SingletonTypeTree;
def SelectFromTypeTree(tree: Tree, qualifier: Tree, selector: Name): SelectFromTypeTree;
- def FunctionTypeTree(tree: Tree, argtpes: List[Tree], restpe: Tree): FunctionTypeTree;
def IntersectionTypeTree(tree: Tree, parents: List[Tree]): IntersectionTypeTree;
def RefinementTypeTree(tree: Tree, base: Tree, decls: List[Tree]): RefinementTypeTree;
def AppliedTypeTree(tree: Tree, tp: Tree, args: List[Tree]): AppliedTypeTree;
@@ -361,8 +343,6 @@ class Trees: Global {
{ val t = new LabelDef(name, params, rhs); t.setPos(tree.pos); t }
def Import(tree: Tree, expr: Tree, selectors: List[Pair[Name, Name]]) =
{ val t = new Import(expr, selectors); t.setPos(tree.pos); t }
- def PatDef(tree: Tree, mods: int, pat: Tree, rhs: Tree) =
- { val t = new PatDef(mods, pat, rhs); t.setPos(tree.pos); t }
def Attributed(tree: Tree, attribute: Tree, definition: Tree) =
{ val t = new Attributed(attribute, definition); t.setPos(tree.pos); t }
def DocDef(tree: Tree, comment: String, definition: Tree) =
@@ -387,8 +367,6 @@ class Trees: Global {
{ val t = new Assign(lhs, rhs); t.setPos(tree.pos); t }
def If(tree: Tree, cond: Tree, thenp: Tree, elsep: Tree) =
{ val t = new If(cond, thenp, elsep); t.setPos(tree.pos); t }
- def For(tree: Tree, enumerators: List[Tree], body: Tree, isForYield: boolean) =
- { val t = new For(enumerators, body, isForYield); t.setPos(tree.pos); t }
def Switch(tree: Tree, test: Tree, tags: List[int], bodies: List[Tree], default: Tree) =
{ val t = new Switch(test, tags, bodies, default); t.setPos(tree.pos); t }
def Return(tree: Tree, expr: Tree) =
@@ -397,8 +375,8 @@ class Trees: Global {
{ val t = new Try(block, catcher, finalizer); t.setPos(tree.pos); t }
def Throw(tree: Tree, expr: Tree) =
{ val t = new Throw(expr); t.setPos(tree.pos); t }
- def New(tree: Tree, init: Tree) =
- { val t = new New(init); t.setPos(tree.pos); t }
+ def New(tree: Tree, typeOrTempl: Tree) =
+ { val t = new New(typeOrTempl); t.setPos(tree.pos); t }
def Typed(tree: Tree, expr: Tree, tp: Tree) =
{ val t = new Typed(expr, tp); t.setPos(tree.pos); t }
def TypeApply(tree: Tree, fun: Tree, args: List[Tree]) =
@@ -421,8 +399,6 @@ class Trees: Global {
{ val t = new SingletonTypeTree(ref); t.setPos(tree.pos); t }
def SelectFromTypeTree(tree: Tree, qualifier: Tree, selector: Name) =
{ val t = new SelectFromTypeTree(qualifier, selector); t.setPos(tree.pos); t }
- def FunctionTypeTree(tree: Tree, argtpes: List[Tree], restpe: Tree) =
- { val t = new FunctionTypeTree(argtpes, restpe); t.setPos(tree.pos); t }
def IntersectionTypeTree(tree: Tree, parents: List[Tree]) =
{ val t = new IntersectionTypeTree(parents); t.setPos(tree.pos); t }
def RefinementTypeTree(tree: Tree, base: Tree, decls: List[Tree]) =
@@ -478,11 +454,6 @@ class Trees: Global {
if (expr0 == expr && selectors0 == selectors) => t
case _ => copy.Import(tree, expr, selectors)
}
- def PatDef(tree: Tree, mods: int, pat: Tree, rhs: Tree) = tree match {
- case t @ PatDef(mods0, pat0, rhs0)
- if (mods0 == mods && pat0 == pat && rhs0 == rhs) => t
- case _ => copy.PatDef(tree, mods, pat, rhs)
- }
def Attributed(tree: Tree, attribute: Tree, definition: Tree) = tree match {
case t @ Attributed(attribute0, definition0)
if (attribute0 == attribute && definition0 == definition) => t
@@ -543,11 +514,6 @@ class Trees: Global {
if (cond0 == cond && thenp0 == thenp && elsep0 == elsep) => t
case _ => copy.If(tree, cond, thenp, elsep)
}
- def For(tree: Tree, enumerators: List[Tree], body: Tree, isForYield: boolean) = tree match {
- case t @ For(enumerators0, body0, isForYield0)
- if (enumerators0 == enumerators && body0 == body && isForYield0 == isForYield) => t
- case _ => copy.For(tree, enumerators, body, isForYield)
- }
def Switch(tree: Tree, test: Tree, tags: List[int], bodies: List[Tree], default: Tree) = tree match {
case t @ Switch(test0, tags0, bodies0, default0)
if (test0 == test && tags0 == tags && bodies0 == bodies && default0 == default) => t
@@ -568,10 +534,10 @@ class Trees: Global {
if (expr0 == expr) => t
case _ => copy.Throw(tree, expr)
}
- def New(tree: Tree, init: Tree) = tree match {
- case t @ New(init0)
- if (init0 == init) => t
- case _ => copy.New(tree, init)
+ def New(tree: Tree, typeOrTempl: Tree) = tree match {
+ case t @ New(typeOrTempl0)
+ if (typeOrTempl0 == typeOrTempl) => t
+ case _ => copy.New(tree, typeOrTempl)
}
def Typed(tree: Tree, expr: Tree, tp: Tree) = tree match {
case t @ Typed(expr0, tp0)
@@ -627,11 +593,6 @@ class Trees: Global {
if (qualifier0 == qualifier && selector0 == selector) => t
case _ => copy.SelectFromTypeTree(tree, qualifier, selector)
}
- def FunctionTypeTree(tree: Tree, argtpes: List[Tree], restpe: Tree) = tree match {
- case t @ FunctionTypeTree(argtpes0, restpe0)
- if (argtpes0 == argtpes && restpe0 == restpe) => t
- case _ => copy.FunctionTypeTree(tree, argtpes, restpe)
- }
def IntersectionTypeTree(tree: Tree, parents: List[Tree]) = tree match {
case t @ IntersectionTypeTree(parents0)
if (parents0 == parents) => t
@@ -672,8 +633,6 @@ class Trees: Global {
copy.LabelDef(tree, name, transformIdents(params), transform(rhs))
case Import(expr, selectors) =>
copy.Import(tree, transform(expr), selectors)
- case PatDef(mods, pat, rhs) =>
- copy.PatDef(tree, mods, transform(pat), transform(rhs))
case Attributed(attribute, definition) =>
copy.Attributed(tree, transform(attribute), transform(definition))
case DocDef(comment, definition) =>
@@ -696,8 +655,6 @@ class Trees: Global {
copy.Function(tree, transformValDefs(vparams), transform(body))
case Assign(lhs, rhs) =>
copy.Assign(tree, transform(lhs), transform(rhs))
- case For(enumerators, body: Tree, isForYield) =>
- copy.For(tree, transformTrees(enumerators), transform(body), isForYield)
case If(cond, thenp, elsep) =>
copy.If(tree, transform(cond), transform(thenp), transform(elsep))
case Switch(test, tags, bodies, default) =>
@@ -708,8 +665,8 @@ class Trees: Global {
copy.Try(tree, transform(block), transform(catcher), transform(finalizer))
case Throw(expr) =>
copy.Throw(tree, transform(expr))
- case New(init) =>
- copy.New(tree, transform(init))
+ case New(typeOrTempl) =>
+ copy.New(tree, transform(typeOrTempl))
case Typed(expr, tp) =>
copy.Typed(tree, transform(expr), transform(tp))
case TypeApply(fun, args) =>
@@ -732,8 +689,6 @@ class Trees: Global {
copy.SingletonTypeTree(tree, transform(ref))
case SelectFromTypeTree(qualifier, selector) =>
copy.SelectFromTypeTree(tree, transform(qualifier), selector)
- case FunctionTypeTree(argtpes, restpe) =>
- copy.FunctionTypeTree(tree, transformTrees(argtpes), transform(restpe))
case IntersectionTypeTree(parents) =>
copy.IntersectionTypeTree(tree, transformTrees(parents))
case RefinementTypeTree(base, decls) =>
@@ -778,8 +733,6 @@ class Trees: Global {
traverseTrees(params); traverse(rhs)
case Import(expr, selectors) =>
traverse(expr)
- case PatDef(mods, pat, rhs) =>
- traverse(pat); traverse(rhs)
case Attributed(attribute, definition) =>
traverse(attribute); traverse(definition)
case DocDef(comment, definition) =>
@@ -802,8 +755,6 @@ class Trees: Global {
traverseTrees(vparams); traverse(body)
case Assign(lhs, rhs) =>
traverse(lhs); traverse(rhs)
- case For(enumerators, body: Tree, isForYield) =>
- traverseTrees(enumerators); traverse(body)
case If(cond, thenp, elsep) =>
traverse(cond); traverse(thenp); traverse(elsep)
case Switch(test, tags, bodies, default) =>
@@ -814,8 +765,8 @@ class Trees: Global {
traverse(block); traverse(catcher); traverse(finalizer)
case Throw(expr) =>
traverse(expr)
- case New(init) =>
- traverse(init)
+ case New(typeOrTempl) =>
+ traverse(typeOrTempl)
case Typed(expr, tp) =>
traverse(expr); traverse(tp)
case TypeApply(fun, args) =>
@@ -828,8 +779,6 @@ class Trees: Global {
traverse(ref)
case SelectFromTypeTree(qualifier, selector) =>
traverse(qualifier)
- case FunctionTypeTree(argtpes, restpe) =>
- traverseTrees(argtpes); traverse(restpe)
case IntersectionTypeTree(parents) =>
traverseTrees(parents)
case RefinementTypeTree(base, decls) =>
diff --git a/sources/scala/tools/nsc/ast/parser/Syntactic.scala b/sources/scala/tools/nsc/ast/parser/Syntactic.scala
index 7ba1574072..b819d0e6e6 100755
--- a/sources/scala/tools/nsc/ast/parser/Syntactic.scala
+++ b/sources/scala/tools/nsc/ast/parser/Syntactic.scala
@@ -10,6 +10,34 @@ import scala.collection.mutable.ListBuffer;
import symtab.Flags;
import Tokens._;
+/** Performs the following context-free rewritings:
+ * (1) Places all pattern variables in Bind nodes. In a pattern, for identifiers `x':
+ * x => x @ _
+ * x:T => x @ (_ : T)
+ *
+ * (2) Removes pattern definitions (PatDef's) as follows:
+ * If pattern is a simple (typed) identifier:
+ * val x = e ==> val x = e
+ * val x: T = e ==> val x: T = e
+ *
+ * if there are no variables in pattern
+ * val p = e ==> e.match (case p => ())
+ *
+ * if there is exactly one variable in pattern
+ * val x_1 = e.match (case p => (x_1))
+ *
+ * if there is more than one variable in pattern
+ * val p = e ==> private synthetic val t$ = e.match (case p => (x_1, ..., x_N))
+ * val x_1 = t$._1
+ * ...
+ * val x_N = t$._N
+ *
+ * (3) Removes function types as follows:
+ * (argtpes) => restpe ==> scala.Function_n[argtpes, restpe]
+ *
+ * (4) Wraps naked case definitions in a match as follows:
+ * { cases } ==> (x => x.match {cases}), except when already argument to match
+ */
abstract class Syntactic: ParserPhase {
import global._;
@@ -27,6 +55,12 @@ abstract class Syntactic: ParserPhase {
*/
var loopNestingDepth = 0;
+ object treeBuilder extends TreeBuilder {
+ val global: Syntactic.this.global.type = Syntactic.this.global;
+ def freshName(): Name = unit.fresh.newName("x$");
+ }
+ import treeBuilder._;
+
/** this is the general parse method
*/
def parse(): List[Tree] = {
@@ -134,85 +168,14 @@ abstract class Syntactic: ParserPhase {
/////// TREE CONSTRUCTION ////////////////////////////////////////////////////
- def fresh(): Name = unit.fresh.newName("x");
-
- /** Create a tree representing a packaging
- */
- def makePackaging(pkg: Tree, stats: List[Tree]): Tree =
- atPos(in.pos) {
- pkg match {
- case Ident(name) =>
- PackageDef(name, stats)
- case Select(qual, name) =>
- makePackaging(qual, List(PackageDef(name, stats)))
- }
- }
-
- /** Create tree representing binary operation expression or pattern.
- */
- def makeBinop(isExpr: boolean, left: Tree, op: Name, right: Tree): Tree = {
- if (isExpr) {
- if (isLeftAssoc(op)) {
- Apply(Select(left, op.encode), List(right))
- } else {
- val x: Name = fresh();
- Block(
- List(ValDef(0, x, EmptyTypeTree(), left)),
- Apply(Select(right, op.encode), List(Ident(x))))
- }
- } else {
- Apply(Ident(op.encode.toTypeName), List(left, right))
- }
- }
- def makeAlternative(ts: List[Tree]): Tree = {
- def alternatives(t: Tree): List[Tree] = t match {
- case Alternative(ts) => ts
- case _ => List(t)
- }
- Alternative(for (val t <- ts; val a <- alternatives(t)) yield a)
- }
-
- def makeSequence(ts: List[Tree]): Tree = {
- def elements(t: Tree): List[Tree] = t match {
- case Sequence(ts) => ts
- case _ => List(t)
- }
- Sequence(for (val t <- ts; val e <- elements(t)) yield e)
- }
-
def scalaDot(name: Name): Tree =
Select(Ident(nme.scala), name);
- def scalaRuntimeDot(name: Name): Tree =
- Select(scalaDot(nme.runtime), name);
- def ScalaRunTimeDot(name: Name): Tree =
- Select(scalaRuntimeDot(nme.ScalaRunTime), name);
- def scalaBooleanDot(name: Name): Tree =
- Select(scalaDot(nme.Boolean), name);
- def scalaAnyRefConstr(): Tree =
- Apply(scalaDot(nme.AnyRef.toTypeName), List());
- def scalaObjectConstr(): Tree =
- Apply(scalaDot(nme.ScalaObject.toTypeName), List());
- def caseClassConstr(): Tree =
- Apply(scalaDot(nme.CaseClass.toTypeName), List());
-
- def makeWhile(lname: Name, cond: Tree, body: Tree): Tree = {
- val continu = Apply(Ident(lname), List());
- val rhs = If(cond, Block(List(body), continu), Literal(()));
- LabelDef(lname, Nil, rhs)
- }
-
- def makeDoWhile(lname: Name, body: Tree, cond: Tree): Tree = {
- val continu = Apply(Ident(lname), List());
- val rhs = Block(List(body), If(cond, continu, Literal(())));
- LabelDef(lname, Nil, rhs)
- }
-
- def makeBlock(stats: List[Tree]): Tree = {
- if (stats.isEmpty) Literal(())
- else if (!stats.last.isTerm) Block(stats, Literal(()));
- else if (stats.length == 1) stats(0)
- else Block(stats.init, stats.last)
- }
+ def scalaAnyRefConstr: Tree =
+ scalaDot(nme.AnyRef.toTypeName);
+ def scalaScalaObjectConstr: Tree =
+ scalaDot(nme.ScalaObject.toTypeName);
+ def caseClassConstr: Tree =
+ scalaDot(nme.CaseClass.toTypeName);
/** Convert tree to formal parameter list
*/
@@ -265,7 +228,7 @@ abstract class Syntactic: ParserPhase {
/** make closure from tree */
def makeClosure(tree: Tree): Tree = {
- val pname = fresh();
+ val pname = freshName();
def insertParam(tree: Tree): Tree = tree match {
case Ident(name) =>
Select(Ident(pname), name)
@@ -310,14 +273,11 @@ abstract class Syntactic: ParserPhase {
}
}
- def isLeftAssoc(operator: Name): boolean =
- operator.length > 0 && operator(operator.length - 1) != ':';
-
def reduceStack(isExpr: boolean, base: List[OpInfo], top0: Tree, prec: int, leftAssoc: boolean): Tree = {
var top = top0;
if (opstack != base &&
precedence(opstack.head.operator) == prec &&
- isLeftAssoc(opstack.head.operator) != leftAssoc) {
+ treeInfo.isLeftAssoc(opstack.head.operator) != leftAssoc) {
syntaxError(
opstack.head.pos,
"left- and right-associative operators with same precedence may not be mixed",
@@ -514,14 +474,14 @@ abstract class Syntactic: ParserPhase {
in.nextToken();
if (in.token == RPAREN) {
in.nextToken();
- atPos(accept(ARROW)) { FunctionTypeTree(List(), typ()) }
+ atPos(accept(ARROW)) { makeFunctionTypeTree(List(), typ()) }
} else {
val t0 = typ();
if (in.token == COMMA) {
in.nextToken();
val ts = new ListBuffer[Tree] + t0 ++ types();
accept(RPAREN);
- atPos (accept(ARROW)) { FunctionTypeTree(ts.toList, typ()) }
+ atPos (accept(ARROW)) { makeFunctionTypeTree(ts.toList, typ()) }
} else {
accept(RPAREN); t0
}
@@ -530,7 +490,7 @@ abstract class Syntactic: ParserPhase {
type1()
}
if (in.token == ARROW) atPos(in.skipToken()) {
- FunctionTypeTree(List(t), typ()) }
+ makeFunctionTypeTree(List(t), typ()) }
else t
}
@@ -687,8 +647,8 @@ abstract class Syntactic: ParserPhase {
val enums = enumerators();
accept(RPAREN);
if (in.token == YIELD) {
- in.nextToken(); For(enums, expr(), true)
- } else For(enums, expr(), false)
+ in.nextToken(); makeForYield(enums, expr())
+ } else makeFor(enums, expr())
}
} else if (in.token == RETURN) {
atPos(in.skipToken()) {
@@ -745,7 +705,7 @@ abstract class Syntactic: ParserPhase {
var top = prefixExpr();
while (in.token == IDENTIFIER) {
top = reduceStack(
- true, base, top, precedence(in.name), isLeftAssoc(in.name));
+ true, base, top, precedence(in.name), treeInfo.isLeftAssoc(in.name));
opstack = OpInfo(top, in.name, in.pos) :: opstack;
ident();
if (isExprIntro) {
@@ -783,7 +743,7 @@ abstract class Syntactic: ParserPhase {
* | StableRef
* | `(' [Expr] `)'
* | BlockExpr
- * | new Template
+ * | new SimpleType [`(' [Exprs] `)'] {`with' SimpleType} [TemplateBody]
* | SimpleExpr `.' Id
* | SimpleExpr TypeArgs
* | SimpleExpr ArgumentExprs
@@ -822,9 +782,19 @@ abstract class Syntactic: ParserPhase {
t = blockExpr()
case NEW =>
t = atPos(in.skipToken()) {
- val templ = template();
- New(if (templ.parents.length == 1 && templ.body.isEmpty) templ.parents.head
- else templ)
+ val parents = new ListBuffer[Tree] + simpleType();
+ var args: List[Tree] = List();
+ if (in.token == LPAREN) args = argumentExprs();
+ while (in.token == WITH) {
+ in.nextToken();
+ parents += simpleType()
+ }
+ val stats = if (in.token == LBRACE) templateBody() else List();
+ val ps = parents.toList;
+ if (ps.length == 1 && stats.isEmpty)
+ Apply(Select(New(ps.head), nme.CONSTRUCTOR), args)
+ else
+ New(Template(ps, makeSuperCall(args) :: stats))
}
case _ =>
syntaxError("illegal start of simple expression", true);
@@ -896,7 +866,7 @@ abstract class Syntactic: ParserPhase {
val guard =
if (in.token == IF) { in.nextToken(); postfixExpr() }
else EmptyTree;
- CaseDef(pat, guard, atPos(accept(ARROW))(block()))
+ makeCaseDef(pat, guard, atPos(accept(ARROW))(block()))
}
/** Enumerators ::= Generator {`;' Enumerator}
@@ -916,7 +886,7 @@ abstract class Syntactic: ParserPhase {
*/
def generator(): Tree =
atPos(accept(VAL)) {
- PatDef(0, pattern1(false), { accept(LARROW); expr() })
+ makeGenerator(pattern1(false), { accept(LARROW); expr() })
}
//////// PATTERNS ////////////////////////////////////////////////////////////
@@ -960,9 +930,12 @@ abstract class Syntactic: ParserPhase {
atPos(in.pos) { Sequence(List()) }
} else {
val p = pattern2(seqOK);
- if (in.token == COLON && treeInfo.isVarPattern(p))
- atPos(in.skipToken()) { Typed(p, type1()) }
- else p
+ p match {
+ case Ident(name) if (treeInfo.isVariableName(name) && in.token == COLON) =>
+ atPos(in.skipToken()) { Typed(p, type1()) }
+ case _ =>
+ p
+ }
}
/* Pattern2 ::= varid [ @ Pattern3 ]
@@ -997,31 +970,16 @@ abstract class Syntactic: ParserPhase {
val base = opstack;
var top = simplePattern(seqOK);
if (seqOK && in.token == IDENTIFIER) {
- if (in.name == STAR) { /* p* becomes z@( |(p,z)) */
- return atPos(in.skipToken()) {
- val zname = fresh();
- Bind(
- zname,
- makeAlternative(List(
- Sequence(List()), makeSequence(List(top, Ident(zname))))))
- }
- } else if (in.name == PLUS) { /* p+ becomes z@(p,(z| )) */
- return atPos(in.skipToken()) {
- val zname = fresh();
- Bind(
- zname,
- makeSequence(List(
- top, makeAlternative(List(Ident(zname), Sequence(List()))))))
- }
- } else if (in.name == OPT) { /* p? becomes (p| ) */
- return atPos(in.skipToken()) {
- makeAlternative(List(top, Sequence(List())))
- }
- }
+ if (in.name == STAR)
+ return atPos(in.skipToken())(makeStar(top))
+ else if (in.name == PLUS)
+ return atPos(in.skipToken())(makePlus(top))
+ else if (in.name == OPT)
+ return atPos(in.skipToken())(makeOpt(top))
}
while (in.token == IDENTIFIER && in.name != BAR) {
top = reduceStack(
- false, base, top, precedence(in.name), isLeftAssoc(in.name));
+ false, base, top, precedence(in.name), treeInfo.isLeftAssoc(in.name));
opstack = OpInfo(top, in.name, in.pos) :: opstack;
ident();
top = simplePattern(seqOK)
@@ -1182,7 +1140,7 @@ abstract class Syntactic: ParserPhase {
*/
def paramType(): Tree =
if (in.token == ARROW)
- atPos(in.skipToken()) { FunctionTypeTree(List(), typ()) }
+ atPos(in.skipToken()) { makeFunctionTypeTree(List(), typ()) }
else {
val t = typ();
if (in.token == IDENTIFIER && in.name == STAR) {
@@ -1369,24 +1327,19 @@ abstract class Syntactic: ParserPhase {
newmods = newmods | Flags.DEFERRED;
EmptyTree
}
- for (val p <- lhs.toList) yield {
- atPos(p.pos) {
- p match {
- case Ident(name) =>
- ValDef(mods, name, tp.duplicate, rhs.duplicate)
- case _ =>
- if (rhs == EmptyTree) {
- syntaxError(p.pos, "cannot defer pattern definition", false);
- errorPatternTree
- } else {
- PatDef(
- mods,
- if (tp == EmptyTree) p else Typed(p, tp),
- rhs.duplicate)
- }
+ def mkDefs(p: Tree): List[Tree] = {
+ val trees =
+ makePatDef(newmods, if (tp == EmptyTree) p else Typed(p, tp), 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);
}
}
+ trees
}
+ for (val p <- lhs.toList; val d <- mkDefs(p)) yield d
}
/** VarDef ::= Id {`,' Id} [`:' Type] `=' Expr
@@ -1525,22 +1478,26 @@ abstract class Syntactic: ParserPhase {
lhs += Tuple4(in.skipToken(),
ident().toTypeName,
typeParamClauseOpt(true),
- paramClauses(true))
+ if ((mods & Flags.TRAIT) != 0) List() else paramClauses(true))
} while (in.token == COMMA);
val thistpe = simpleTypedOpt();
- val Template(parents, body) = classTemplate((mods & Flags.CASE) != 0);
+ val Template(parents, body) = classTemplate(mods);
for (val Tuple4(pos, name, tparams, vparamss) <- lhs.toList) yield
atPos(pos) {
- val vparamss1 = vparamss map (.map (vd =>
- ValDef(Flags.PARAM, vd.name, vd.tp.duplicate, EmptyTree)));
- val constr: Tree = DefDef(
- mods & Flags.CONSTRFLAGS | Flags.SYNTHETIC, nme.CONSTRUCTOR, List(),
- if (vparamss1.isEmpty) List(List()) else vparamss1,
- EmptyTypeTree(), EmptyTree);
- val vparams: List[Tree] =
- for (val vparams <- vparamss; val vparam <- vparams) yield vparam;
- ClassDef(mods, name, tparams, thistpe.duplicate,
- Template(parents, vparams ::: constr :: body))
+ val body1 =
+ if ((mods & Flags.TRAIT) != 0) body
+ else {
+ val vparamss1 = vparamss map (.map (vd =>
+ ValDef(Flags.PARAM, vd.name, vd.tp.duplicate, EmptyTree)));
+ val constr: Tree = DefDef(
+ mods & Flags.CONSTRFLAGS | Flags.SYNTHETIC, nme.CONSTRUCTOR, List(),
+ if (vparamss1.isEmpty) List(List()) else vparamss1,
+ EmptyTypeTree(), EmptyTree);
+ val vparams: List[Tree] =
+ for (val vparams <- vparamss; val vparam <- vparams) yield vparam;
+ vparams ::: constr :: body
+ }
+ ClassDef(mods, name, tparams, thistpe.duplicate, Template(parents, body1))
}
}
@@ -1552,7 +1509,7 @@ abstract class Syntactic: ParserPhase {
lhs += Pair(in.skipToken(), ident());
} while (in.token == COMMA);
val thistpe = simpleTypedOpt();
- val template = classTemplate((mods & Flags.CASE)!= 0);
+ val template = classTemplate(mods);
for (val Pair(pos, name) <- lhs.toList) yield
atPos(pos) {
ModuleDef(mods, name, thistpe.duplicate,
@@ -1560,46 +1517,36 @@ abstract class Syntactic: ParserPhase {
}
}
- /** ClassTemplate ::= [`extends' Constr] {`with' Constr} [TemplateBody]
+ /** ClassTemplate ::= [`extends' SimpleType [`(' [Exprs] `)']] {`with' SimpleType} [TemplateBody]
*/
- def classTemplate(isCaseClass:boolean): Template = {
+ def classTemplate(mods: int): Template =
atPos(in.pos) {
- val parents = new ListBuffer[Tree];
- if (in.token == EXTENDS) {
+ val parents = new ListBuffer[Tree];
+ var args: List[Tree] = List();
+ if (in.token == EXTENDS) {
in.nextToken();
- parents += constr()
- } else {
- parents += scalaAnyRefConstr()
- }
- parents += scalaObjectConstr();
- if (isCaseClass) parents += caseClassConstr();
- if (in.token == WITH) {
- in.nextToken();
- template(parents)
- } else if (in.token == LBRACE) {
- Template(parents.toList, templateBody())
- } else {
- if (!(in.token == SEMI || in.token == COMMA || in.token == RBRACE))
- syntaxError("`extends' or `{' expected", true);
- Template(parents.toList, List())
- }
+ parents += simpleType();
+ if (in.token == LPAREN) args = argumentExprs();
+ }
+ parents += scalaScalaObjectConstr;
+ if ((mods & Flags.CASE)!= 0) parents += caseClassConstr;
+ while (in.token == WITH) {
+ in.nextToken(); parents += simpleType();
+ }
+ val ps = parents.toList;
+ var body =
+ if (in.token == LBRACE) {
+ templateBody()
+ } else {
+ if (!(in.token == SEMI || in.token == COMMA || in.token == RBRACE))
+ syntaxError("`extends' or `{' expected", true);
+ List()
+ }
+ if ((mods & Flags.TRAIT) == 0) body = makeSuperCall(args) :: body;
+ Template(ps, body)
}
- }
////////// TEMPLATES ////////////////////////////////////////////////////////////
- /** Template ::= Constr {`with' Constr} [TemplateBody]
- */
- def template(): Template = template(new ListBuffer[Tree]);
-
- def template(parents: ListBuffer[Tree]): Template = {
- parents += constr();
- while (in.token == WITH) {
- in.nextToken();
- parents += constr()
- }
- val stats = if (in.token == LBRACE) templateBody() else List();
- Template(parents.toList, stats)
- }
/** Constr ::= StableId [TypeArgs] [`(' [Exprs] `)']
*/
@@ -1617,7 +1564,7 @@ abstract class Syntactic: ParserPhase {
def templateBody(): List[Tree] = {
accept(LBRACE);
var body = templateStatSeq();
- if (body.length == 0) body = List(EmptyTree);
+ if (body.isEmpty) body = List(EmptyTree);
accept(RBRACE);
body
}
@@ -1800,4 +1747,6 @@ abstract class Syntactic: ParserPhase {
}
}
+
+
// LocalWords: SOcos
diff --git a/sources/scala/tools/nsc/symtab/Definitions.scala b/sources/scala/tools/nsc/symtab/Definitions.scala
index 11e4a10684..ea570ae388 100755
--- a/sources/scala/tools/nsc/symtab/Definitions.scala
+++ b/sources/scala/tools/nsc/symtab/Definitions.scala
@@ -63,6 +63,16 @@ abstract class Definitions: SymbolTable {
def TupleClass(i: int): Symbol = getClass("scala.Tuple" + i);
def FunctionClass(i: int): Symbol = getClass("scala.Function" + i);
+ def tupleType(elems: List[Type]) = {
+ val sym = TupleClass(elems.length);
+ typeRef(sym.info.prefix, sym, elems)
+ }
+
+ def functionType(formals: List[Type], restpe: Type) = {
+ val sym = FunctionClass(formals.length);
+ typeRef(sym.info.prefix, sym, formals ::: List(restpe))
+ }
+
// members of class scala.Any
var Any_== : Symbol = _;
var Any_!= : Symbol = _;
@@ -95,8 +105,9 @@ abstract class Definitions: SymbolTable {
i = j + 1;
j = fullname.pos('.', i)
}
- val result = sym.info.nonPrivateMember(fullname.subName(i, j).toTypeName)
- .suchThat(.hasFlag(MODULE));
+ val result =
+ if (module) sym.info.nonPrivateMember(fullname.subName(i, j)).suchThat(.hasFlag(MODULE));
+ else sym.info.nonPrivateMember(fullname.subName(i, j).toTypeName);
if (result == NoSymbol)
throw new FatalError((if (module) "object " else "class ") + fullname + " not found.");
result
@@ -175,7 +186,16 @@ abstract class Definitions: SymbolTable {
MatchErrorModule = getModule("scala.MatchError");
NilModule = getModule("scala.Nil");
ConsClass = getClass("scala.$colon$colon");
- RepeatedParamClass = newClass(ScalaPackageClass, nme.REPEATED_PARAM_CLASS_NAME, List(SeqClass.tpe));
+ RepeatedParamClass = newClass(ScalaPackageClass, nme.REPEATED_PARAM_CLASS_NAME, List());
+ { val tparam = newTypeParam(RepeatedParamClass, 0);
+ RepeatedParamClass.setInfo(
+ PolyType(
+ List(tparam),
+ ClassInfoType(
+ List(typeRef(SeqClass.tpe.prefix, SeqClass, List(tparam.typeConstructor))),
+ new Scope(),
+ RepeatedParamClass)))
+ }
// members of class scala.Any
Any_== = newMethod(AnyClass, "==")
diff --git a/sources/scala/tools/nsc/symtab/Names.scala b/sources/scala/tools/nsc/symtab/Names.scala
index f381d46da8..190bacc12b 100755
--- a/sources/scala/tools/nsc/symtab/Names.scala
+++ b/sources/scala/tools/nsc/symtab/Names.scala
@@ -234,7 +234,9 @@ class Names {
}
/** Replace $op_name by corresponding operator symbol */
- def decode: String = NameTransformer.decode(toString())
+ def decode: String =
+ NameTransformer.decode(toString()) +
+ (if (isTypeName) "!" else "");//debug
}
private class TermName(index: int, len: int, hash: int) extends Name(index, len) {
diff --git a/sources/scala/tools/nsc/symtab/StdNames.scala b/sources/scala/tools/nsc/symtab/StdNames.scala
index f9897eac9d..5cbd8d0169 100755
--- a/sources/scala/tools/nsc/symtab/StdNames.scala
+++ b/sources/scala/tools/nsc/symtab/StdNames.scala
@@ -113,7 +113,7 @@ abstract class StdNames: SymbolTable {
val report = newTermName("report");
val false_ = newTermName("false");
val filter = newTermName("filter");
- val flatmap = newTermName("flatMap");
+ val flatMap = newTermName("flatMap");
val foreach = newTermName("foreach");
val getClass_ = newTermName("getClass");
val hasAsInstance = newTermName("hasAsInstance");
diff --git a/sources/scala/tools/nsc/symtab/Symbols.scala b/sources/scala/tools/nsc/symtab/Symbols.scala
index cc4cfbe72c..6f4f89f899 100755
--- a/sources/scala/tools/nsc/symtab/Symbols.scala
+++ b/sources/scala/tools/nsc/symtab/Symbols.scala
@@ -325,11 +325,23 @@ abstract class Symbols: SymbolTable {
if (hasFlag(OVERLOADED)) info.asInstanceOf[OverloadedType].alternatives
else List(this);
- def suchThat(cond: Symbol => boolean): Symbol =
- if (hasFlag(OVERLOADED)) uniqueSymbolIn(alternatives.elements, cond)
- else if (cond(this)) this
+ def filter(cond: Symbol => boolean): Symbol =
+ if (hasFlag(OVERLOADED)) {
+ val alts = alternatives;
+ val alts1 = alts filter cond;
+ if (alts1 eq alts) this
+ else if (alts1.isEmpty) NoSymbol
+ else if (alts1.tail.isEmpty) alts1.head
+ else owner.newOverloaded(info.prefix, alts1)
+ } else if (cond(this)) this
else NoSymbol;
+ def suchThat(cond: Symbol => boolean): Symbol = {
+ val result = filter(cond);
+ assert(!result.hasFlag(OVERLOADED));
+ result
+ }
+
// Cloneing -------------------------------------------------------------------
/** A clone of this symbol */
@@ -538,7 +550,7 @@ abstract class Symbols: SymbolTable {
/** String representation of symbol's definition */
final def defString: String =
- compose(List(flagsToString(flags & SOURCEFLAGS),
+ compose(List(flagsToString(rawflags & SOURCEFLAGS),
keyString,
varianceString + nameString,
infoString(rawInfo)));
@@ -647,16 +659,4 @@ abstract class Symbols: SymbolTable {
/** A class for type histories */
private class TypeHistory(val start: Phase, val info: Type, val prev: TypeHistory);
-
-
- /** Return unique element in list of symbols satisfying condition,
- * or NoSymbol if no element satisfies condition,
- * pre: at most one element satisfies condition.
- */
- def uniqueSymbolIn(syms: Iterator[Symbol], cond: Symbol => boolean): Symbol =
- if (syms.hasNext) {
- val sym = syms.next;
- if (cond(sym)) { assert(!syms.exists(cond)); sym }
- else uniqueSymbolIn(syms, cond)
- } else NoSymbol;
}
diff --git a/sources/scala/tools/nsc/symtab/Types.scala b/sources/scala/tools/nsc/symtab/Types.scala
index 7f8688f3bc..38b061a39e 100755
--- a/sources/scala/tools/nsc/symtab/Types.scala
+++ b/sources/scala/tools/nsc/symtab/Types.scala
@@ -8,6 +8,24 @@ package scala.tools.nsc.symtab;
import scala.tools.util.Position;
import Flags._;
+/* A standard type pattern match:
+ case ErrorType =>
+ case WildcardType =>
+ case NoType =>
+ case NoPrefix =>
+ case ThisType(_) =>
+ case SingleType(pre, sym) =>
+ case ConstantType(base, value) =>
+ case TypeRef(pre, sym, args) =>
+ case TypeBounds(lo, hi) =>
+ case RefinedType(parents, defs) =>
+ case ClassInfoType(parents, defs, clazz) =>
+ case MethodType(paramtypes, result) =>
+ case PolyType(tparams, result) =>
+ case OverloadedType(pre, tparams, alts) =>
+ case TypeVar(_, _) =>
+*/
+
abstract class Types: SymbolTable {
import definitions._;
@@ -32,10 +50,8 @@ abstract class Types: SymbolTable {
/** Map to a this type which is a subtype of this type.
*/
- def narrow: Type = {
- val reftpe = refinedType(List(this), commonOwner(this), EmptyScope);
- ThisType(reftpe.symbol);
- }
+ def narrow: Type =
+ refinedType(List(this), commonOwner(this), EmptyScope).narrow;
/** Map a constant type to its underlying base type,
* identity for all other types */
@@ -83,7 +99,7 @@ abstract class Types: SymbolTable {
def typeParams: List[Symbol] = List();
/** Is this type produced as a repair for an error? */
- def isError: boolean = this == ErrorType || symbol.isError;
+ def isError: boolean = symbol.isError;
/** Does this type denote a stable reference (i.e. singleton type)? */
def isStable: boolean = false;
@@ -212,8 +228,8 @@ abstract class Types: SymbolTable {
def baseClasses: List[Symbol] = List();
- /** The index of given class symbol in the closure of this type, -1
- * of no base type with gien class symbol exists */
+ /** The index of given class symbol in the closure of this type,
+ * or -1 if no base type with given class symbol exists */
def closurePos(sym: Symbol): int = {
val cl = closure;
var lo = 0;
@@ -249,13 +265,15 @@ abstract class Types: SymbolTable {
* by `owner'. Identity for all other types. */
def cloneInfo(owner: Symbol) = this;
- /** The representation of this type used as a prefix */
+ /** The string representation of this type used as a prefix */
def prefixString = toString() + ".";
- /** Get type of `this' symbol corresponding to this class typeref, extend
- * homomorphically to results of function types and poly types.
- * Identity for all other types. */
- def instanceType = this;
+ /** The string representation of this type, with singletypes explained */
+ def toLongString = {
+ val str = toString();
+ if (str.endsWith(".type")) str + " (with underlying type " + widen + ")";
+ else str
+ }
/** Is this type completed (i.e. not a lazy type)?
*/
@@ -267,7 +285,7 @@ abstract class Types: SymbolTable {
private def findDecl(name: Name, excludedFlags: int): Symbol = {
var alts: List[Symbol] = List();
var sym: Symbol = NoSymbol;
- var e = decls.lookupEntry(name);
+ var e: ScopeEntry = decls.lookupEntry(name);
while (e != null) {
if ((e.sym.rawflags & excludedFlags) == 0) {
if (sym == NoSymbol) sym = e.sym
@@ -283,6 +301,7 @@ abstract class Types: SymbolTable {
}
protected def findMember(name: Name, excludedFlags: int): Symbol = {
+ //System.out.println("find member " + name.decode + " in " + this.baseClasses);//DEBUG
var members: Scope = null;
var member: Symbol = NoSymbol;
var excluded = excludedFlags | DEFERRED;
@@ -357,6 +376,7 @@ abstract class Types: SymbolTable {
/** An object representing an erroneous type */
case object ErrorType extends Type {
// todo see whether we can do without
+ override def isError: boolean = true;
override def decls: Scope = new ErrorScope(NoSymbol);
override def findMember(name: Name, excludedFlags: int): Symbol = decls lookup name;
override def baseType(clazz: Symbol): Type = this;
@@ -432,17 +452,19 @@ abstract class Types: SymbolTable {
private var validBaseClasses: Phase = null;
override def closure: Array[Type] = {
- if (validClosure != phase) {
- validClosure = phase;
- closureCache = null;
+ def computeClosure: Array[Type] =
try {
- closureCache = addClosure(symbol.tpe, glbArray(parents map (.closure)));
+ addClosure(symbol.tpe, glbArray(parents map (.closure)));
} catch {
case ex: MalformedClosure =>
throw new MalformedType(
"the type intersection " + this + " is malformed" +
"\n --- because ---\n" + ex.getMessage())
}
+ if (validClosure != phase) {
+ validClosure = phase;
+ closureCache = null;
+ closureCache = computeClosure;
}
if (closureCache == null)
throw new TypeError("illegal cyclic reference involving " + symbol);
@@ -457,7 +479,7 @@ abstract class Types: SymbolTable {
val mixins = parents.tail;
def isNew(limit: List[Type])(clazz: Symbol): boolean = {
var ms = mixins;
- while (!(ms eq limit) && !(ms.head.symbol isSubClass clazz)) ms = ms.tail;
+ while (!(ms eq limit) && ms.head.closurePos(clazz) < 0) ms = ms.tail;
ms eq limit
}
var ms = mixins;
@@ -467,7 +489,6 @@ abstract class Types: SymbolTable {
}
symbol :: bcs
}
-
if (validBaseClasses != phase) {
validBaseClasses = phase;
baseClassCache = null;
@@ -509,8 +530,7 @@ abstract class Types: SymbolTable {
class PackageClassInfoType(decls: Scope, clazz: Symbol) extends ClassInfoType(List(), decls, clazz);
/** A class representing a constant type */
- case class ConstantType(base: Type, value: Any)
- extends SingletonType {
+ case class ConstantType(base: Type, value: Any) extends SingletonType {
override def symbol: Symbol = base.symbol;
override def singleDeref: Type = base;
override def deconst: Type = base;
@@ -523,10 +543,10 @@ abstract class Types: SymbolTable {
abstract case class TypeRef(pre: Type, sym: Symbol, args: List[Type]) extends Type {
assert(!sym.isAbstractType || pre.isStable || pre.isError);
- private def transform(tp: Type): Type =
+ def transform(tp: Type): Type =
tp.asSeenFrom(pre, sym.owner).subst(sym.typeParams, args);
- private def transform(cl: Array[Type]): Array[Type] = {
+ def transform(cl: Array[Type]): Array[Type] = {
val cl1 = new Array[Type](cl.length);
var i = 0;
while (i < cl.length) { cl1(i) = transform(cl(i)); i = i + 1 }
@@ -556,15 +576,11 @@ abstract class Types: SymbolTable {
else pre.memberInfo(sym).baseType(clazz);
override def closure: Array[Type] =
- if (sym.isAbstractType) addClosure(this, bounds.hi.closure)
+ if (sym.isAbstractType) addClosure(this, transform(bounds.hi).closure)
else transform(sym.info.closure);
override def baseClasses: List[Symbol] = sym.info.baseClasses;
- override def instanceType: Type =
- if (sym.thisSym != sym) transform(sym.typeOfThis)
- else this;
-
override def erasure: Type =
if (sym.isAbstractType || sym.isAliasType) sym.info.erasure
else if (sym == ObjectClass ||
@@ -587,11 +603,6 @@ abstract class Types: SymbolTable {
override def paramSectionCount: int = resultType.paramSectionCount + 1;
- override def instanceType: Type = {
- val res = resultType.instanceType;
- if (res eq resultType) this else MethodType(paramTypes, res)
- }
-
override def erasure = {
val pts = List.transform(paramTypes)(.erasure);
val res = resultType.erasure;
@@ -602,25 +613,22 @@ abstract class Types: SymbolTable {
override def toString(): String = paramTypes.mkString("(", ",", ")") + resultType;
}
+ class ImplicitMethodType(pts: List[Type], rt: Type) extends MethodType(pts, rt);
+
/** A class representing a polymorphic type or, if tparams.length == 0,
* a parameterless method type.
*/
- case class PolyType(override val typeParams: List[Symbol], override val resultType: Type) extends Type {
+ case class PolyType(override val typeParams: List[Symbol], override val resultType: Type)
+ extends Type {
override def paramSectionCount: int = resultType.paramSectionCount;
override def paramTypes: List[Type] = resultType.paramTypes;
- override def instanceType: Type = {
- val res = resultType.instanceType;
- if (res eq resultType) this else PolyType(typeParams, res)
- }
-
override def erasure = resultType.erasure;
override def toString(): String =
- (if (typeParams.isEmpty) "=> " else typeParams.mkString("[", ",", "]"))
- + resultType;
+ (if (typeParams.isEmpty) "=> " else typeParams.mkString("[", ",", "]")) + resultType;
override def cloneInfo(owner: Symbol) = {
val tparams = typeParams map (.cloneSymbol(owner));
@@ -642,7 +650,10 @@ abstract class Types: SymbolTable {
/** A class containing the alternatives and type prefix of an overloaded symbol
*/
- case class OverloadedType(pre: Type, val alternatives: List[Symbol]) extends Type;
+ case class OverloadedType(pre: Type, alternatives: List[Symbol]) extends Type {
+ override def prefix: Type = pre;
+ override def toString() = (alternatives map pre.memberType).mkString("", " <and> ", "")
+ }
/** A class representing an as-yet unevaluated type.
*/
@@ -718,8 +729,7 @@ abstract class Types: SymbolTable {
/** A creator for type applications */
def appliedType(tycon: Type, args: List[Type]): Type = tycon match {
case TypeRef(pre, sym, args1) =>
- if (args eq args1) tycon
- else typeRef(pre, sym, args)
+ if (args eq args1) tycon else typeRef(pre, sym, args)
case ErrorType => tycon
}
@@ -745,7 +755,7 @@ abstract class Types: SymbolTable {
/** Map this function over given type */
def mapOver(tp: Type): Type = tp match {
- case ErrorType | WildcardType | NoType | NoPrefix | TypeVar(_, _) | ThisType(_) =>
+ case ErrorType | WildcardType | NoType | NoPrefix | ThisType(_) =>
tp
case SingleType(pre, sym) =>
val pre1 = this(pre);
@@ -787,9 +797,16 @@ abstract class Types: SymbolTable {
else MethodType(paramtypes1, result1)
case PolyType(tparams, result) =>
val tparams1 = mapOver(tparams);
- val result1 = this(result);
+ var result1 = this(result);
if ((tparams1 eq tparams) && (result1 eq result)) tp
- else PolyType(tparams1, result1)
+ else PolyType(tparams1, result1.substSym(tparams, tparams1))
+ case OverloadedType(pre, alts) =>
+ val pre1 = this(pre);
+ if (pre1 eq pre) tp
+ else OverloadedType(pre1, alts)
+ case TypeVar(_, constr) =>
+ if (constr.inst != NoType) this(constr.inst)
+ else tp
case _ =>
throw new Error("mapOver inapplicable for " + tp);
}
diff --git a/sources/scala/tools/nsc/symtab/classfile/UnPickle.scala b/sources/scala/tools/nsc/symtab/classfile/UnPickle.scala
index 0a5ca5511c..e46b876b2f 100755
--- a/sources/scala/tools/nsc/symtab/classfile/UnPickle.scala
+++ b/sources/scala/tools/nsc/symtab/classfile/UnPickle.scala
@@ -24,7 +24,7 @@ abstract class UnPickle {
private var bytes: Array[byte] = _;
private var bp: int = _;
private var index: Array[int] = _;
- private var entries: Array[Any] = _;
+ private var entries: Array[AnyRef] = _;
def parse(bytes: Array[byte], clazz: Symbol, module: Symbol): unit = {
warning("cannot yet unpickle: " + clazz.fullNameString('.'));
diff --git a/sources/scala/tools/nsc/typechecker/Analyzer.scala b/sources/scala/tools/nsc/typechecker/Analyzer.scala
index fe01281247..5457b01ec4 100644
--- a/sources/scala/tools/nsc/typechecker/Analyzer.scala
+++ b/sources/scala/tools/nsc/typechecker/Analyzer.scala
@@ -9,9 +9,14 @@ import scala.tools.util.Position;
/** The main attribution phase.
*/
-abstract class Analyzer extends Contexts with Namers with Typers with TypeCheckers {
+abstract class Analyzer
+ extends Contexts
+ with Namers
+ with Typers
+ with TypeCheckers
+ with Infer
+ with Variances {
val global: Global;
-
import global._;
case class ImportType(tree: Import) extends Type;
diff --git a/sources/scala/tools/nsc/typechecker/Contexts.scala b/sources/scala/tools/nsc/typechecker/Contexts.scala
index 78112ad604..804b5ae29d 100755
--- a/sources/scala/tools/nsc/typechecker/Contexts.scala
+++ b/sources/scala/tools/nsc/typechecker/Contexts.scala
@@ -18,7 +18,7 @@ class Contexts: Analyzer {
def addImport(pkg: Symbol): unit = {
sc = sc.make(sc.tree, sc.owner, new Scope(sc.scope));
val impTree = Import(gen.mkGlobalRef(pkg), List(Pair(nme.WILDCARD, null)));
- impTree.setSymbol(NoSymbol.newImport(Position.NOPOS)).setType(ImportType(impTree));
+ impTree.setSymbol(NoSymbol.newImport(Position.NOPOS)).setType(this.ImportType(impTree));
sc.scope.enter(impTree.symbol)
}
if (!settings.noimports.value) {
@@ -32,14 +32,15 @@ class Contexts: Analyzer {
class Context {
var unit: CompilationUnit = _;
- var tree: Tree = _; // Tree associated with this context
- var owner: Symbol = _; // The current owner
- var scope: Scope = _; // The current scope
- var outer: Context = _; // The next outer context
- var enclClass: Context = this; // The next outer context whose tree
- // is a class template
- var variance: int = _; // Variance relative to enclosing class.
- var constructorClass: Symbol = _; // Class for auxiliary constructor
+ var tree: Tree = _; // Tree associated with this context
+ var owner: Symbol = _; // The current owner
+ var scope: Scope = _; // The current scope
+ var outer: Context = _; // The next outer context
+ var enclClass: Context = this; // The next outer context whose tree
+ // is a class template
+ var variance: int = _; // Variance relative to enclosing class.
+ var undetparams: List[Symbol] = List(); // Undetermined type parameters
+ var constructorClass: Symbol = _; // Class for auxiliary constructor
var depth: int = 0;
val imports: List[Tree] = List();
diff --git a/sources/scala/tools/nsc/typechecker/TypeCheckers.scala b/sources/scala/tools/nsc/typechecker/TypeCheckers.scala
index 01f0e26f03..43bd18ea60 100755
--- a/sources/scala/tools/nsc/typechecker/TypeCheckers.scala
+++ b/sources/scala/tools/nsc/typechecker/TypeCheckers.scala
@@ -21,10 +21,10 @@ trait TypeCheckers: Analyzer {
class TypeChecker(context: Context) extends Transformer {
- import global._;
import context.unit;
- def error(pos: int, msg: String) = unit.error(pos, msg);
+ val infer = new Inferencer(context);
+ import infer._;
def reportTypeError(pos: int, ex: TypeError): unit = {
if (settings.debug.value) ex.printStackTrace();
@@ -43,6 +43,33 @@ trait TypeCheckers: Analyzer {
}
}
+ /** Mode constants
+ */
+ val NOmode = 0x000;
+ val EXPRmode = 0x001; // these 3 modes are mutually exclusive.
+ val PATTERNmode = 0x002;
+ val TYPEmode = 0x004;
+
+ val FUNmode = 0x10; // orthogonal to above. When set
+ // we are looking for a method or constructor
+
+ val POLYmode = 0x020; // orthogonal to above. When set
+ // expression types can be polymorphic.
+
+ val QUALmode = 0x040; // orthogonal to above. When set
+ // expressions may be packages and
+ // Java statics modules.
+
+ val SUPERmode = 0x080; // Goes with CONSTRmode. When set
+ // we are checking a superclass
+ // constructor invocation.
+
+ val baseModes: int = EXPRmode | PATTERNmode;
+
+ val SEQUENCEmode = 0x1000; // only for PATTERNmode, otherwise orthogonal to above. When set
+ // we turn "x" into "x@_"
+ // and allow args to be of type Seq( a) instead of a
+
def reenterValueParams(tree: Tree): unit = tree match {
case DefDef(_, _, _, vparamss, _, _) =>
for (val vparams <- vparamss; val vparam <- vparams) context.scope enter vparam.symbol
@@ -54,23 +81,24 @@ trait TypeCheckers: Analyzer {
def transformConstr(tree: Tree): Tree = tree;
def transformExpr(tree: Tree): Tree = tree;
def transformType(tree: Tree): Tree = tree;
-
- abstract class ResolveError extends TermSymbol(NoSymbol, Position.NOPOS, nme.EMPTY) {
- setFlag(IS_ERROR);
- def msg(qual: Tree, name: Name): String;
- }
-
- object NotFoundError extends ResolveError {
- def msg(qual: Tree, name: Name) = name.decode + " is not a member of " + qual;
- }
-
- object NotAccessibleError extends TermSymbol(NoSymbol, Position.NOPOS, nme.EMPTY) {
- def msg(qual: Tree, name: Name) = name.decode + " is not accessible in " + qual;
- }
+ def transformSuperType(tree: Tree): Tree = tree;
def transform(tree: Tree, mode: int, pt: Type): Tree = {
- def stabilize(tree: Tree, pre: Type): Tree = tree;
+ /** Turn tree type into stable type if possible and required by context. */
+ def stabilize(tree: Tree, pre: Type): Tree = tree.tpe match {
+ case ConstantType(base, value) =>
+ Literal(value) setPos tree.pos setType tree.tpe
+ case PolyType(List(), restp @ ConstantType(base, value)) =>
+ Literal(value) setPos tree.pos setType restp
+ case _ =>
+ if (tree.symbol.hasFlag(OVERLOADED) && (mode & FUNmode) == 0)
+ inferExprAlternative(tree, pt);
+ if (tree.symbol.isStable && pre.isStable &&
+ (pt.isStable || (mode & QUALmode) != 0 || tree.symbol.isModule))
+ tree.tpe = singleType(pre, tree.symbol);
+ tree
+ }
/** Attribute an identifier consisting of a simple name or an outer reference.
* @param tree The tree representing the identifier.
@@ -166,81 +194,260 @@ trait TypeCheckers: Analyzer {
qual = importTree(impSym).expr.duplicate;
pre = qual.tpe;
} else {
- error(tree.pos, "not found: " + name.decode);
+ error(tree.pos, "not found: " + decode(name));
sym = context.owner.newErrorSymbol(name);
}
}
- val symtype = pre.memberType(sym);
- if (symtype == NoType) error(tree.pos, "not found: " + name.decode);
- if (qual == EmptyTree) stabilize(tree.setSymbol(sym).setType(symtype), pre)
- else transform(Select(qual, name) setPos tree.pos, mode, pt)
+ stabilize(checkAccessible(tree, sym, pre, qual), pre);
}
- tree//for now
- }
- }
-}
-/*
- def resolveSymbol(pos: int, qual: Tree, name: Name): Symbol = {
- def chekFeasible(sym: Symbol): Symbol = {
-
-
- var best: Symbol = notFoundError;
- var multiple = false;
- var alts = pre.lookupAll(name);
- while (alts.hasNext) {
- val alt = checkFeasible(alts.next);
- if (!improves(best, alt)) {
- multiple = !best.isError;
- best = alt;
- }
- }
- if (multiple) {
- alts = pre.lookupAll(name);
- while (alts.hasNext) {
- val alt = checkFeasible(alts.next);
- if (!improves(best, alt)) {
- error(pos,
- "ambiguous reference to overloaded definition,\n" +
- "both " + sym1 + ": " + pre.memberType(sym1) + "\n" +
- "and " + sym2 + ": " + pre.memberTyoe(sym2) + "\nmatch" +
- context.resolveContext);
- }
- }
- }
- best match {
- case err: ResolveError => error(pos, err.msg);
- case _ => best
- }
- }
+ def applyPoly(tree: Tree, tparams: List[Symbol], restpe: Type): Tree = {
+ val tparams1 = tparams map (.cloneSymbol);
+ val targs = context.undetparams map (tparam => EmptyTypeTree().setType(tparam.tpe));
+ context.undetparams = context.undetparams ::: tparams1;
+ (if (qual0.isType) AppliedTypeTree(tree, targs) else TypeApply(tree, targs))
+ .setType(restpe.subst(tparams, tparams1))
+ }
/** Attribute a selection where `tree' is `qual.name'.
* `qual' is already attributed.
*/
def transformSelect(tree: Tree, qual0: Tree, name: Name): Tree = {
- val qual = qual0;
- var uninst: List[Symbol] = List();
- qual.tpe match {
+ val qual = qual0.tpe match {
case PolyType(tparams, restpe) =>
- qual = mkTypeApply(qual, tparams, restype, tparams map (.tpe));
- uninst = tparams;
+ assert(context.undetparams.isEmpty);
+ applyPoly(qual, tparams, restpe);
case _ =>
+ qual0
}
- val sym = resolveSymbol(qual, name);
+ val sym = qual.tpe.member(name);
// if (sym == NoSymbol) try to insert view.
- if (!uninst.isEmpty) {
- def polymorphize(tp: Type): Type = tp match {
- case PolyType(tparams, restpe) => PolyType(tparams, polymorphize(restpe))
- case _ => PolyType(uninst, tp)
+ val pre = qual match {
+ case Super(_, _) => context.enclClass.owner.thisType
+ case _ => qual.tpe
+ }
+ val tree1 = tree match {
+ case Select(_, name) => copy.Select(tree, qual, name);
+ case SelectFromTypeTree(_, name) => copy.SelectFromTypeTree(tree, qual, name)
+ }
+ stabilize(checkAccessible(tree1, sym, pre, qual), pre);
+ }
+
+ /** Attribute an argument list.
+ * @param pos Position for error reporting
+ * @param meth The symbol of the called method, or `null' if none exists.
+ * @param tparams The type parameters that need to be instantiated
+ * @param methtype The method's type w/o type parameters
+ * @param argMode The argument mode (either EXPRmode or PATTERNmode)
+ * @param args The actual arguments
+ * @param pt The proto-resulttype.
+ * @return The vector of instantiated argument types, or null if error.
+ */
+ def transformArgs(pos: int, meth: Symbol, tparams: Array[Symbol], methtype: Type, argMode: int, args: Array[Tree], pt: Type): Array[Tree] = {
+ val argtypes = new Array[Type](args.length);
+ methtype match {
+ case Type$MethodType(params, restp) =>
+ val formals = infer.formalTypes(params, args.length);
+ if (formals.length != args.length) {
+ error(pos, "wrong number of arguments for " +
+ (if (meth == null) "<function>" else meth) +
+ ArrayApply.toString(formals.asInstanceOf[Array[Object]], "(", ",", ")"));
+ return null;
+ }
+ if (tparams.isEmpty) {
+ List.map2(args, formals) ((arg, formal) => transform(arg, argMode, formal))
+ } else {
+ val targs = protoTypeArgs(tparams, params, restp, pt);
+ val argpts = formals map (.subst(tparams, targs));
+ val args1 = List.map2(args, argpts)((arg, argpt) =>
+ transform(arg, argMode | POLYmode, argpt));
+ // targs1: same as targs except that every WildcardType is mapped to
+ // formal parameter type.
+ val targs1 = List.map2(targs, tparams)((targ, tparam) =>
+ if (targ == WildcardType) tparam.tpe else targ);
+
+
+ { var i = 0; while (i < args.length) {
+ argtypes(i) = args(i).getType().deconst();
+ argtypes(i) match {
+ case Type$PolyType(tparams1, restype1) =>
+ argtypes(i) = infer.argumentTypeInstance(
+ tparams1, restype1,
+ formals(i).subst(tparams, targs1),
+ argpts(i));
+ case _ =>
+ }
+ i = i + 1
+ }}
+ }
+ // desugarizing ident patterns
+ if (params.length > 0 && (params(params.length-1).flags & REPEATED) != 0) {
+ if ((mode & PATTERNmode) != 0) {
+ def desug_allIdentPatterns(trees: Array[Tree], currentOwner: Symbol): unit = {
+ var i = 0; while (i < trees.length) {
+ trees(i) match {
+ case Tree.Ident(name) =>
+ if (name != Names.PATTERN_WILDCARD) {
+ val vble: Symbol = context.scope.lookup(name);
+ trees(i) = desugarize.IdentPattern(trees(i)).setSymbol(vble)
+ .setType(vble.getType());
+ } else {
+ trees(i) = gen.Ident(trees(i).pos, definitions.PATTERN_WILDCARD);
+ }
+ case _ =>
+ }
+ i = i + 1
+ }
+ }
+ desug_allIdentPatterns(args, context.owner);
+ } else {
+ assert(args.length != params.length ||
+ !(args(params.length-1).isInstanceOf[Tree.Sequence]));
}
- symtype = polymorphize(symtype);
}
- //System.out.println(qual.getType() + ".member: " + sym + ":" + symtype);//DEBUG
- val tree1: Tree = tree match {
- case Select(_, _) => copy.Select(tree, sym, qua);
- case SelectFromType(_, _) => copy.SelectFromType(tree, sym, qual)
+ argtypes;
+
+ case Type$PolyType(tparams1, restp) =>
+ var tparams2: Array[Symbol] = tparams1;
+ if (tparams.length != 0) {
+ tparams2 = new Array[Symbol](tparams.length + tparams1.length);
+ System.arraycopy(tparams, 0, tparams2, 0, tparams.length);
+ System.arraycopy(tparams1, 0, tparams2, tparams.length, tparams1.length);
+ }
+ transformArgs(pos, meth, tparams2,
+ infer.skipViewParams(tparams2, restp), argMode, args, pt)
+
+ case Type.ErrorType =>
+ var i = 0; while (i < args.length) {
+ args(i) = transform(args(i), argMode, Type.ErrorType);
+ argtypes(i) = args(i).getType().deconst();
+ i = i + 1
+ }
+ argtypes
+
+ case Type.OverloadedType(alts, alttypes) if (alts.length == 1) =>
+ transformArgs(pos, alts(0), tparams, alttypes(0), argMode, args, pt)
+
+ case _ =>
+ var i = 0; while (i < args.length) {
+ args(i) = transform(args(i), argMode, Type.AnyType);
+ argtypes(i) = args(i).getType().deconst();
+ i = i + 1
+ }
+ argtypes
+ }
+ }
+
+
+
+/* tree
+ }
+ }
+}
+*/
+
+ def transformApply(tree: Tree, fn: Tree, args: List[Tree]): Tree = {
+ var fn1 =
+ if ((mode & PATTERNmode) != 0) transform(fn, mode | FUNmode & ~SEQUENCEmode, pt)
+ else transform(fn, mode | FUNmode, WildcardType);
+
+ // if function is overloaded filter all alternatives that match
+ // number of arguments and expected result type.
+ if (fn1.hasSymbol && fn1.symbol.hasFlag(OVERLOADED)) {
+ val sym1 = fn1.symbol filter (alt =>
+ isApplicable(fn1.symbol.info.prefix.memberType(alt), argtypes, pt));
+ fn1.setSymbol(sym1).setType(fn1.symbol.info.prefix.memberType(sym1));
+ }
+
+ // handle the case of application of match to a visitor specially
+ args match {
+ case List(Visitor(_)) if (treeInfo.methSymbol(fn1) == Any_match) =>
+ return transformMatch(fn1, args.head);
+ case _ =>
}
- mkStable(tree1.setType(symtype), qualtype)
}
+ def transformApply(fn: Tree, args: List[Tree]): Tree = {
+ fn.tpe match {
+ case OverloadedType(pre, alts) =>
+ val args1 = args map (arg => transform(arg, argMode, WildcardType));
+ inferMethodAlternative(fn, args1 map (.tpe.deconst), pt);
+ transformApply(fn, args1);
+ case PolyType(tparams, restpe) =>
+ transformApply(applyPoly(fn, tparams, restpe));
+ case MethodType(formals0, restpe) =>
+ val formals = formalTypes(formals, args.length);
+ if (formals.length != args.length) {
+ error(pos, "wrong number of arguments for " + treeSymTypeMsg(fn1));
+ setError(tree)
+ }
+ val tparams = context.undetparams;
+ if (tparams.isEmpty) {
+ val args1 = List.map2(args, formals) ((arg, formal) =>
+ transform(arg, argMode, formal));
+
+ } else {
+ val targs = protoTypeArgs(tparams, formals, restp, pt);
+ val argpts = formals map (.subst(tparams, targs));
+ val args1 = List.map2(args, argpts1)((arg, argpt) =>
+ transform(arg, argMode | POLYmode, argpt));
+ // targs1: same as targs except that every WildcardType is mapped to
+ // formal parameter type.
+ val targs1 = List.map2(targs, tparams)((targ, tparam) =>
+ if (targ == WildcardType) tparam.tpe else targ);
+ val argpts1 = formals map (.subst(tparams, targs1));
+ val argtpes = List.map3(args, argpts, argpts1)(inferArgumentTypeInstance);
+ inferMethodInstance(fn, argtpes, pt);
+ transformApply(fn, args1)
+ }
+
+
+
+ val tparams1 = tparams map (.cloneSymbol);
+ val restpe1 = restpe.substSym(tparams, tparams1);
+
+
+ copy.Apply(tree, fn1, args1).setType(???)
+ case MethodType(formals, restpe) =>
+ transformMonoApply(fn1, formals, restpe, args)
+
+
+
+ // type arguments with formals as prototypes if they exist.
+ val argtypes = transformArgs(tree.pos, fn1.symbol, fn1.tpe,
+ mode & (PATTERNmode | EXPRmode), args, pt);
+ if (argtypes == null || argtypes exists (.isError)) return setError(tree);
+
+ var args1 = null;
+ // resolve overloading
+
+
+
+ pt);
+ case _ =>
+ }
+
+ // infer method instance
+
+
+ val pattp: Type = matchQualType(fn1);
+ if (pattp.isError()) {
+ return setError(tree)
+ } else if (pattp != Type.NoType) {
+ if (infer.isFullyDefined(pattp) &&
+ !(fn1.getType().isInstanceOf[Type$PolyType] &&
+ pattp.containsSome(fn1.getType().typeParams()))) {
+ val fn2: Tree = desugarize.postMatch(fn1, context.enclClass.owner);
+ val arg1: Tree = transformVisitor(args(0), pattp, pt);
+ return copy.Apply(tree, fn2, NewArray.Tree(arg1))
+ .setType(arg1.getType());
+ } else {
+ error(tree.pos, "expected pattern type of cases could not be determined");
+ return errorTermTree(tree)
+ }
+ }
+ }
+
+
+
*/
diff --git a/sources/scala/tools/nsc/typechecker/Typers.scala b/sources/scala/tools/nsc/typechecker/Typers.scala
index e14628ab90..4c2f785af5 100755
--- a/sources/scala/tools/nsc/typechecker/Typers.scala
+++ b/sources/scala/tools/nsc/typechecker/Typers.scala
@@ -34,13 +34,6 @@ trait Typers: Analyzer {
sym.setInfo(typechecker.transformType(tree).tpe)
}
- private def constrType(constr: Tree): Type = constr match {
- case Apply(fn, args) =>
- val ctp = constrType(fn);
- if (ctp.typeParams.isEmpty) ctp else typechecker.transformConstr(constr).tpe
- case _ => typechecker.transformType(constr).tpe
- }
-
private def deconstIfNotFinal(sym: Symbol, tpe: Type): Type =
if (sym.isVariable || !sym.hasFlag(FINAL)) tpe.deconst else tpe;
@@ -71,7 +64,11 @@ trait Typers: Analyzer {
private def templateSig(clazz: Symbol, templ: Template): Type = {
// determine parent types
- val parents = templ.parents map constrType;
+ val parents =
+ if (templ.parents.isEmpty) List()
+ else
+ typechecker.transformSuperType(templ.parents.head).tpe ::
+ (templ.parents.tail map (p => typechecker.transformType(p).tpe));
if (!parents.isEmpty && parents.head.symbol.hasFlag(INTERFACE)
&& parents.head.symbol.hasFlag(JAVA))
unit.error(templ.parents.head.pos, "cannot extend a Java interface");
@@ -102,7 +99,6 @@ trait Typers: Analyzer {
typechecker.checkNoEscape(tpt.pos,
deconstIfNotFinal(meth,
if (meth.name == nme.CONSTRUCTOR) context.enclClass.owner.tpe
- else if (tpt.tpe != null) tpt.tpe
else if (tpt.isEmpty) { tpt.tpe = typechecker.transformExpr(rhs).tpe; tpt.tpe }
else typechecker.transformType(tpt).tpe));
def mkMethodType(vparams: List[Symbol], restpe: Type) =
@@ -135,8 +131,7 @@ trait Typers: Analyzer {
case ValDef(_, _, tpt, rhs) =>
deconstIfNotFinal(sym,
- if (tpt.tpe != null) tpt.tpe
- else if (tpt.isEmpty)
+ if (tpt.isEmpty)
if (rhs.isEmpty) {
unit.error(tpt.pos, "missing parameter type");
ErrorType
diff --git a/sources/scala/tools/scalac/typechecker/Analyzer.scala b/sources/scala/tools/scalac/typechecker/Analyzer.scala
index 405a8e6fac..cb351151b4 100644
--- a/sources/scala/tools/scalac/typechecker/Analyzer.scala
+++ b/sources/scala/tools/scalac/typechecker/Analyzer.scala
@@ -160,7 +160,7 @@ class Analyzer(global: scalac_Global, descr: AnalyzerPhase) extends Transformer(
val baseModes = EXPRmode | PATTERNmode | CONSTRmode;
- val SEQUENCEmode = 0x1000; // orthogonal to above. When set
+ val SEQUENCEmode = 0x1000; // only for PATTERNmode, otherwise orthogonal to above. When set
// we turn "x" into "x@_"
// and allow args to be of type Seq( a) instead of a