summaryrefslogtreecommitdiff
path: root/sources/scala/tools/nsc
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2005-03-02 14:56:32 +0000
committerMartin Odersky <odersky@gmail.com>2005-03-02 14:56:32 +0000
commit9acfa7693d146fc2ea6fdad61c74907354910ea8 (patch)
treee0832025736b165bd7e087b3bab41d4fb0046fe0 /sources/scala/tools/nsc
parentf8c47c369ed0254ea3bda3366b9902b1a3dd5ba2 (diff)
downloadscala-9acfa7693d146fc2ea6fdad61c74907354910ea8.tar.gz
scala-9acfa7693d146fc2ea6fdad61c74907354910ea8.tar.bz2
scala-9acfa7693d146fc2ea6fdad61c74907354910ea8.zip
*** empty log message ***
Diffstat (limited to 'sources/scala/tools/nsc')
-rwxr-xr-xsources/scala/tools/nsc/Global.scala11
-rw-r--r--sources/scala/tools/nsc/ast/TreeInfo.scala16
-rw-r--r--sources/scala/tools/nsc/ast/TreePrinters.scala30
-rw-r--r--sources/scala/tools/nsc/ast/Trees.scala435
-rw-r--r--sources/scala/tools/nsc/ast/parser/Lexical.scala1
-rwxr-xr-xsources/scala/tools/nsc/ast/parser/Syntactic.scala159
-rw-r--r--sources/scala/tools/nsc/ast/parser/Tokens.scala1
-rwxr-xr-xsources/scala/tools/nsc/symtab/Definitions.scala15
-rw-r--r--sources/scala/tools/nsc/symtab/Flags.scala14
-rwxr-xr-xsources/scala/tools/nsc/symtab/StdNames.scala1
-rwxr-xr-xsources/scala/tools/nsc/symtab/Symbols.scala30
-rwxr-xr-xsources/scala/tools/nsc/symtab/Types.scala18
-rwxr-xr-xsources/scala/tools/nsc/symtab/classfile/ClassfileParser.scala10
-rw-r--r--sources/scala/tools/nsc/typechecker/Analyzer.scala3
-rwxr-xr-xsources/scala/tools/nsc/typechecker/Contexts.scala2
-rwxr-xr-xsources/scala/tools/nsc/typechecker/Namers.scala50
-rwxr-xr-xsources/scala/tools/nsc/typechecker/TypeCheckers.scala1066
-rwxr-xr-xsources/scala/tools/nsc/typechecker/Typers.scala87
18 files changed, 1216 insertions, 733 deletions
diff --git a/sources/scala/tools/nsc/Global.scala b/sources/scala/tools/nsc/Global.scala
index a6c09fe855..061373b189 100755
--- a/sources/scala/tools/nsc/Global.scala
+++ b/sources/scala/tools/nsc/Global.scala
@@ -34,6 +34,15 @@ class Global(val settings: Settings, val reporter: Reporter) extends SymbolTable
val global: Global.this.type = Global.this
}
+ object constfold extends ConstantFolder {
+ val global: Global.this.type = Global.this
+ }
+
+ val copy = new LazyTreeCopier();
+
+ type AttrInfo = Pair[Type, List[Any]];
+ val attributes = new HashMap[Symbol, List[AttrInfo]];
+
// reporting -------------------------------------------------------
def informTime(msg: String, start: long) = {
@@ -213,6 +222,6 @@ class Global(val settings: Settings, val reporter: Reporter) extends SymbolTable
}
val sym = getSym(name, module);
System.err.println("" + sym.name + ":" +
- (if (module) sym.moduleClass.info else sym.info))
+ (if (module) sym.tpe.symbol.info else sym.info))
}
}
diff --git a/sources/scala/tools/nsc/ast/TreeInfo.scala b/sources/scala/tools/nsc/ast/TreeInfo.scala
index 92e5c00cd4..03cb490d28 100644
--- a/sources/scala/tools/nsc/ast/TreeInfo.scala
+++ b/sources/scala/tools/nsc/ast/TreeInfo.scala
@@ -18,7 +18,7 @@ abstract class TreeInfo {
def isOwnerDefinition(tree: Tree): boolean = tree match {
case PackageDef(_, _)
| ClassDef(_, _, _, _, _)
- | ModuleDef(_, _, _, _)
+ | ModuleDef(_, _, _)
| DefDef(_, _, _, _, _, _)
| Import(_, _) => true
case _ => false
@@ -39,7 +39,7 @@ abstract class TreeInfo {
def isPureDef(tree: Tree): boolean = tree match {
case EmptyTree
| ClassDef(_, _, _, _, _)
- | ModuleDef(_, _, _, _)
+ | ModuleDef(_, _, _)
| AbsTypeDef(_, _, _, _)
| AliasTypeDef(_, _, _, _)
| Import(_, _)
@@ -108,9 +108,9 @@ abstract class TreeInfo {
case _ => false
}
- /** The first constructor in a list of statements */
+ /** The longest statement suffix that starts with a constructor */
def firstConstructor(stats: List[Tree]): Tree = stats.head match {
- case DefDef(_, nme.CONSTRUCTOR, _, _, _, _) => stats.head
+ case constr @ DefDef(_, nme.CONSTRUCTOR, _, _, _, _) => constr
case _ => firstConstructor(stats.tail)
}
@@ -133,6 +133,14 @@ abstract class TreeInfo {
case _ => false
}
+ /** Is this pattern node a sequence-valued pattern? */
+ def isSequenceValued(tree: Tree): boolean = tree match {
+ case Bind(_, body) => isSequenceValued(body)
+ case Sequence(_) => true
+ case Alternative(ts) => ts exists isSequenceValued
+ case _ => false
+ }
+
/** The method symbol of an application node, or NoSymbol, if none exists.
*/
def methSymbol(tree: Tree): Symbol = {
diff --git a/sources/scala/tools/nsc/ast/TreePrinters.scala b/sources/scala/tools/nsc/ast/TreePrinters.scala
index 47c8af4cfb..64ff2f66f2 100644
--- a/sources/scala/tools/nsc/ast/TreePrinters.scala
+++ b/sources/scala/tools/nsc/ast/TreePrinters.scala
@@ -71,7 +71,7 @@ abstract class TreePrinters {
}
def printBlock(tree: Tree): unit = tree match {
- case Block(_, _) | Visitor(_) => print(tree)
+ case Block(_, _) => print(tree)
case _ => printColumn(List(tree), "{", ";", "}")
}
@@ -103,9 +103,9 @@ abstract class TreePrinters {
case PackageDef(packaged, stats) =>
print("package "); print(packaged); printColumn(stats, " {", ";", "}")
- case ModuleDef(mods, name, tpe, impl) =>
+ case ModuleDef(mods, name, impl) =>
printModifiers(mods); print("object " + symName(tree, name));
- printOpt(": ", tpe); print(" extends "); print(impl);
+ print(" extends "); print(impl);
case ValDef(mods, name, tp, rhs) =>
printModifiers(mods);
@@ -152,8 +152,8 @@ abstract class TreePrinters {
case Block(stats, expr) =>
printColumn(stats ::: List(expr), "{", ";", "}")
- case Visitor(cases) =>
- printColumn(cases, "{", "", "}");
+ case Match(selector, cases) =>
+ print(selector); printColumn(cases, " match {", "", "}")
case CaseDef(pat, guard, body) =>
print("case "); print(pat); printOpt(" if ", guard);
@@ -181,18 +181,12 @@ abstract class TreePrinters {
println; print("else"); indent; println; print(elsep); undent
}
- case Switch(expr, tags, bodies, defaultBody) =>
- print("<switch> ("); print(expr); print(") {"); indent;
- printSeq(tags zip bodies)
- {case Pair(tag, body) => print("case " + tag + " => "); print(body)} {println}
- print("<default> => "); print(defaultBody); print(" }"); undent
-
case Return(expr) =>
print("return "); print(expr)
- case Try(block, catcher, finalizer) =>
+ case Try(block, catches, finalizer) =>
print("try "); printBlock(block);
- printOpt(" catch ", catcher);
+ if (!catches.isEmpty) printColumn(catches, " catch {", "", "}");
printOpt(" finally ", finalizer)
case Throw(expr) =>
@@ -236,7 +230,7 @@ abstract class TreePrinters {
case _ => obj.toString()
})
- case EmptyTypeTree() =>
+ case TypeTree() =>
print(tree.tpe.toString());
case SingletonTypeTree(ref) =>
@@ -245,11 +239,9 @@ abstract class TreePrinters {
case SelectFromTypeTree(qualifier, selector) =>
print(qualifier); print("#"); print(symName(tree, selector))
- case IntersectionTypeTree(parents) =>
- printRow(parents, " with ")
-
- case RefinementTypeTree(base, decls) =>
- print(base); printColumn(decls, "{", ";", "}")
+ case CompoundTypeTree(parents, decls) =>
+ printRow(parents, " with ");
+ if (!decls.isEmpty) printColumn(decls, "{", ";", "}")
case AppliedTypeTree(tp, args) =>
print(tp); printRow(args, "[", ", ", "]")
diff --git a/sources/scala/tools/nsc/ast/Trees.scala b/sources/scala/tools/nsc/ast/Trees.scala
index 5178ad1dba..16be82347e 100644
--- a/sources/scala/tools/nsc/ast/Trees.scala
+++ b/sources/scala/tools/nsc/ast/Trees.scala
@@ -16,13 +16,13 @@ class Trees: Global {
var pos: int = Position.NOPOS;
var tpe: Type = _;
- def setPos(p: int): Tree = { pos = p; this }
- def setType(tp: Type): Tree = { tpe = tp; this }
+ def setPos(p: int): this.type = { pos = p; this }
+ def setType(tp: Type): this.type = { tpe = tp; this }
def symbol: Symbol = null;
def symbol_=(sym: Symbol): unit =
throw new Error("symbol_= inapplicable for " + this);
- def setSymbol(sym: Symbol): Tree = { symbol = sym; this }
+ def setSymbol(sym: Symbol): this.type = { symbol = sym; this }
def hasSymbol = false;
def isDef = false;
@@ -37,6 +37,11 @@ class Trees: Global {
buffer.toString()
}
+ override def equals(that: Any): boolean = that match {
+ case t: Tree => this eq t
+ case _ => false
+ }
+
def duplicate: Tree =
new Transformer(new StrictTreeCopier) transform this;
}
@@ -54,7 +59,7 @@ class Trees: Global {
override def isTerm = true;
}
- abstract class TypeTree extends Tree {
+ abstract class TypTree extends Tree {
override def isType = true;
}
@@ -64,25 +69,25 @@ class Trees: Global {
override def isEmpty = true;
}
- /** Class definition */
- case class ClassDef(mods: int, name: Name, tparams: List[AbsTypeDef], tp: Tree, impl: Template)
- extends DefTree;
-
/** Package clause */
case class PackageDef(name: Name, stats: List[Tree])
extends DefTree;
+ /** Class definition */
+ case class ClassDef(mods: int, name: Name, tparams: List[AbsTypeDef], tpt: Tree, impl: Template)
+ extends DefTree;
+
/** Singleton object definition */
- case class ModuleDef(mods: int, name: Name, tp: Tree, impl: Template)
+ case class ModuleDef(mods: int, name: Name, impl: Template)
extends DefTree;
/** Value definition */
- case class ValDef(mods: int, name: Name, tp: Tree, rhs: Tree)
+ case class ValDef(mods: int, name: Name, tpt: Tree, rhs: Tree)
extends DefTree;
/** Method definition */
case class DefDef(mods: int, name: Name, tparams: List[AbsTypeDef],
- vparams: List[List[ValDef]], tp: Tree, rhs: Tree)
+ vparamss: List[List[ValDef]], tpt: Tree, rhs: Tree)
extends DefTree;
/** Abstract type or type parameter */
@@ -119,10 +124,6 @@ class Trees: Global {
case class Block(stats: List[Tree], expr: Tree)
extends TermTree;
- /** Visitor (a sequence of cases), eliminated by TransMatch */
- case class Visitor(cases: List[CaseDef])
- extends TermTree;
-
/** Case clause in a pattern match, eliminated by TransMatch */
case class CaseDef(pat: Tree, guard: Tree, body: Tree)
extends Tree;
@@ -137,7 +138,7 @@ class Trees: Global {
extends TermTree;
/** Bind of a variable to a rhs pattern, eliminated by TransMatch */
- case class Bind(name: Name, rhs: Tree)
+ case class Bind(name: Name, body: Tree)
extends TermTree;
/** Anonymous function, eliminated by analyzer */
@@ -152,16 +153,14 @@ class Trees: Global {
case class If(cond: Tree, thenp: Tree, elsep: Tree)
extends TermTree;
- /** Switch, introduced by refcheck */
- case class Switch(test: Tree, tags: List[int], bodies: List[Tree],
- default: Tree)
- extends TermTree;
+ /** Pattern matching expression */
+ case class Match(selector: Tree, cases: List[CaseDef]) extends TermTree;
/** Return expression */
case class Return(expr: Tree)
- extends TermTree;
+ extends SymTree;
- case class Try(block: Tree, catcher: Tree, finalizer: Tree)
+ case class Try(block: Tree, catches: List[CaseDef], finalizer: Tree)
extends TermTree;
/** Throw expression */
@@ -175,7 +174,7 @@ class Trees: Global {
extends TermTree;
/** Type annotation, eliminated by explicit outer */
- case class Typed(expr: Tree, tp: Tree)
+ case class Typed(expr: Tree, tpt: Tree)
extends TermTree;
/** Type application */
@@ -213,37 +212,33 @@ class Trees: Global {
extends TermTree;
/** General type term, introduced by RefCheck. */
- case class EmptyTypeTree() extends TypeTree {
+ case class TypeTree() extends TypTree {
override def isEmpty = tpe == null;
}
/** Singleton type, eliminated by RefCheck */
case class SingletonTypeTree(ref: Tree)
- extends TypeTree;
+ extends TypTree;
/** Type selection, eliminated by RefCheck */
case class SelectFromTypeTree(qualifier: Tree, selector: Name)
- extends TypeTree with SymTree;
+ extends TypTree with SymTree;
/** Intersection type, eliminated by RefCheck */
- case class IntersectionTypeTree(parents: List[Tree])
- extends TypeTree;
-
- /** Refinement type, eliminated by RefCheck */
- case class RefinementTypeTree(base: Tree, decls: List[Tree])
- extends TypeTree;
+ case class CompoundTypeTree(parents: List[Tree], decls: List[Tree])
+ extends TypTree;
/** Applied type, eliminated by RefCheck */
- case class AppliedTypeTree(tp: Tree, args: List[Tree])
- extends TypeTree;
+ case class AppliedTypeTree(tpt: Tree, args: List[Tree])
+ extends TypTree;
/* A standard pattern match
case EmptyTree =>
- case ClassDef(mods, name, tparams, tp, impl) =>
case PackageDef(name, stats) =>
- case ModuleDef(mods, name, tp, impl) => (eliminated by refcheck)
- case ValDef(mods, name, tp, rhs) =>
- case DefDef(mods, name, tparams, vparams, tp, rhs) =>
+ case ClassDef(mods, name, tparams, tpt, impl) =>
+ case ModuleDef(mods, name, impl) => (eliminated by refcheck)
+ case ValDef(mods, name, tpt, rhs) =>
+ case DefDef(mods, name, tparams, vparamss, tpt, rhs) =>
case AbsTypeDef(mods, name, lo, hi) => (eliminated by erasure)
case AliasTypeDef(mods, name, tparams, rhs) => (eliminated by erasure)
case LabelDef(name, params, rhs) =>
@@ -252,20 +247,19 @@ class Trees: Global {
case DocDef(comment, definition) => (eliminated by typecheck)
case Template(parents, body) =>
case Block(stats, expr) =>
- 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 Bind(name, body) => (eliminated by transmatch)
case Function(vparams, body) => (eliminated by typecheck)
case Assign(lhs, rhs) =>
case If(cond, thenp, elsep) =>
- case Switch(test, tags, bodies, default) => (introduced by refcheck, transmatch)
+ case Match(selector, cases) =>
case Return(expr) =>
- case Try(block, catcher, finalizer) =>
+ case Try(block, catches, finalizer) =>
case Throw(expr) =>
- case New(typeOrTempl) =>
- case Typed(expr, tp) => (eliminated by erasure)
+ case New(tpt) =>
+ case Typed(expr, tpt) => (eliminated by erasure)
case TypeApply(fun, args) =>
case Apply(fun, args) =>
case Super(qual, mixin) =>
@@ -273,20 +267,19 @@ class Trees: Global {
case Select(qualifier, selector) =>
case Ident(name) =>
case Literal(value) =>
- case EmptyTypeTree() => (eliminated by typecheck)
+ case TypeTree() =>
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)
+ case CompoundTypeTree(parents, decls) => (eliminated by typecheck)
+ case AppliedTypeTree(tpt, args) => (eliminated by typecheck)
*/
trait TreeCopier {
- def ClassDef(tree: Tree, mods: int, name: Name, tparams: List[AbsTypeDef], tp: Tree, impl: Template): ClassDef;
+ def ClassDef(tree: Tree, mods: int, name: Name, tparams: List[AbsTypeDef], tpt: Tree, impl: Template): ClassDef;
def PackageDef(tree: Tree, name: Name, stats: List[Tree]): PackageDef;
- def ModuleDef(tree: Tree, mods: int, name: Name, tp: Tree, impl: Template): ModuleDef;
- def ValDef(tree: Tree, mods: int, name: Name, tp: Tree, rhs: Tree): ValDef;
- def DefDef(tree: Tree, mods: int, name: Name, tparams: List[AbsTypeDef], vparams: List[List[ValDef]], tp: Tree, rhs: Tree): DefDef;
+ def ModuleDef(tree: Tree, mods: int, name: Name, impl: Template): ModuleDef;
+ def ValDef(tree: Tree, mods: int, name: Name, tpt: Tree, rhs: Tree): ValDef;
+ def DefDef(tree: Tree, mods: int, name: Name, tparams: List[AbsTypeDef], vparamss: List[List[ValDef]], tpt: Tree, rhs: Tree): DefDef;
def AbsTypeDef(tree: Tree, mods: int, name: Name, lo: Tree, hi: Tree): AbsTypeDef;
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;
@@ -295,20 +288,19 @@ class Trees: Global {
def DocDef(tree: Tree, comment: String, definition: Tree): DocDef;
def Template(tree: Tree, parents: List[Tree], body: List[Tree]): Template;
def Block(tree: Tree, stats: List[Tree], expr: Tree): Block;
- def Visitor(tree: Tree, cases: List[CaseDef]): Visitor;
def CaseDef(tree: Tree, pat: Tree, guard: Tree, body: Tree): CaseDef;
def Sequence(tree: Tree, trees: List[Tree]): Sequence;
def Alternative(tree: Tree, trees: List[Tree]): Alternative;
- def Bind(tree: Tree, name: Name, rhs: Tree): Bind;
+ def Bind(tree: Tree, name: Name, body: Tree): Bind;
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 Switch(tree: Tree, test: Tree, tags: List[int], bodies: List[Tree], default: Tree): Switch;
+ def Match(tree: Tree, selector: Tree, cases: List[CaseDef]): Match;
def Return(tree: Tree, expr: Tree): Return;
- def Try(tree: Tree, block: Tree, catcher: Tree, finalizer: Tree): Try;
+ def Try(tree: Tree, block: Tree, catches: List[CaseDef], finalizer: Tree): Try;
def Throw(tree: Tree, expr: Tree): Throw;
- def New(tree: Tree, typeOrTempl: Tree): New;
- def Typed(tree: Tree, expr: Tree, tp: Tree): Typed;
+ def New(tree: Tree, tpt: Tree): New;
+ def Typed(tree: Tree, expr: Tree, tpt: Tree): Typed;
def TypeApply(tree: Tree, fun: Tree, args: List[Tree]): TypeApply;
def Apply(tree: Tree, fun: Tree, args: List[Tree]): Apply;
def Super(tree: Tree, qual: Name, mixin: Name): Super;
@@ -316,25 +308,24 @@ class Trees: Global {
def Select(tree: Tree, qualifier: Tree, selector: Name): Select;
def Ident(tree: Tree, name: Name): Ident;
def Literal(tree: Tree, value: Any): Literal;
- def EmptyTypeTree(tree: Tree): EmptyTypeTree;
+ def TypeTree(tree: Tree): TypeTree;
def SingletonTypeTree(tree: Tree, ref: Tree): SingletonTypeTree;
def SelectFromTypeTree(tree: Tree, qualifier: Tree, selector: Name): SelectFromTypeTree;
- 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;
+ def CompoundTypeTree(tree: Tree, parents: List[Tree], decls: List[Tree]): CompoundTypeTree;
+ def AppliedTypeTree(tree: Tree, tpt: Tree, args: List[Tree]): AppliedTypeTree;
}
class StrictTreeCopier extends TreeCopier {
- def ClassDef(tree: Tree, mods: int, name: Name, tparams: List[AbsTypeDef], tp: Tree, impl: Template) =
- { val t = new ClassDef(mods, name, tparams, tp, impl); t.setPos(tree.pos); t }
+ def ClassDef(tree: Tree, mods: int, name: Name, tparams: List[AbsTypeDef], tpt: Tree, impl: Template) =
+ { new ClassDef(mods, name, tparams, tpt, impl).setPos(tree.pos) }
def PackageDef(tree: Tree, name: Name, stats: List[Tree]) =
{ val t = new PackageDef(name, stats); t.setPos(tree.pos); t }
- def ModuleDef(tree: Tree, mods: int, name: Name, tp: Tree, impl: Template) =
- { val t = new ModuleDef(mods, name, tp, impl); t.setPos(tree.pos); t }
- def ValDef(tree: Tree, mods: int, name: Name, tp: Tree, rhs: Tree) =
- { val t = new ValDef(mods, name, tp, rhs); t.setPos(tree.pos); t }
- def DefDef(tree: Tree, mods: int, name: Name, tparams: List[AbsTypeDef], vparams: List[List[ValDef]], tp: Tree, rhs: Tree) =
- { val t = new DefDef(mods, name, tparams, vparams, tp, rhs); t.setPos(tree.pos); t }
+ def ModuleDef(tree: Tree, mods: int, name: Name, impl: Template) =
+ { val t = new ModuleDef(mods, name, impl); t.setPos(tree.pos); t }
+ def ValDef(tree: Tree, mods: int, name: Name, tpt: Tree, rhs: Tree) =
+ { val t = new ValDef(mods, name, tpt, rhs); t.setPos(tree.pos); t }
+ def DefDef(tree: Tree, mods: int, name: Name, tparams: List[AbsTypeDef], vparamss: List[List[ValDef]], tpt: Tree, rhs: Tree) =
+ { val t = new DefDef(mods, name, tparams, vparamss, tpt, rhs); t.setPos(tree.pos); t }
def AbsTypeDef(tree: Tree, mods: int, name: Name, lo: Tree, hi: Tree) =
{ val t = new AbsTypeDef(mods, name, lo, hi); t.setPos(tree.pos); t }
def AliasTypeDef(tree: Tree, mods: int, name: Name, tparams: List[AbsTypeDef], rhs: Tree) =
@@ -351,34 +342,32 @@ class Trees: Global {
{ val t = new Template(parents, body); t.setPos(tree.pos); t }
def Block(tree: Tree, stats: List[Tree], expr: Tree) =
{ val t = new Block(stats, expr); t.setPos(tree.pos); t }
- def Visitor(tree: Tree, cases: List[CaseDef]) =
- { val t = new Visitor(cases); t.setPos(tree.pos); t }
def CaseDef(tree: Tree, pat: Tree, guard: Tree, body: Tree) =
{ val t = new CaseDef(pat, guard, body); t.setPos(tree.pos); t }
def Sequence(tree: Tree, trees: List[Tree]) =
{ val t = new Sequence(trees); t.setPos(tree.pos); t }
def Alternative(tree: Tree, trees: List[Tree]) =
{ val t = new Alternative(trees); t.setPos(tree.pos); t }
- def Bind(tree: Tree, name: Name, rhs: Tree) =
- { val t = new Bind(name, rhs); t.setPos(tree.pos); t }
+ def Bind(tree: Tree, name: Name, body: Tree) =
+ { val t = new Bind(name, body); t.setPos(tree.pos); t }
def Function(tree: Tree, vparams: List[ValDef], body: Tree) =
{ val t = new Function(vparams, body); t.setPos(tree.pos); t }
def Assign(tree: Tree, lhs: Tree, rhs: Tree) =
{ 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 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 Match(tree: Tree, selector: Tree, cases: List[CaseDef]) =
+ { val t = new Match(selector, cases); t.setPos(tree.pos); t }
def Return(tree: Tree, expr: Tree) =
{ val t = new Return(expr); t.setPos(tree.pos); t }
- def Try(tree: Tree, block: Tree, catcher: Tree, finalizer: Tree) =
- { val t = new Try(block, catcher, finalizer); t.setPos(tree.pos); t }
+ def Try(tree: Tree, block: Tree, catches: List[CaseDef], finalizer: Tree) =
+ { val t = new Try(block, catches, 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, 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 New(tree: Tree, tpt: Tree) =
+ { val t = new New(tpt); t.setPos(tree.pos); t }
+ def Typed(tree: Tree, expr: Tree, tpt: Tree) =
+ { val t = new Typed(expr, tpt); t.setPos(tree.pos); t }
def TypeApply(tree: Tree, fun: Tree, args: List[Tree]) =
{ val t = new TypeApply(fun, args); t.setPos(tree.pos); t }
def Apply(tree: Tree, fun: Tree, args: List[Tree]) =
@@ -393,185 +382,178 @@ class Trees: Global {
{ val t = new Ident(name); t.setPos(tree.pos); t }
def Literal(tree: Tree, value: Any) =
{ val t = new Literal(value); t.setPos(tree.pos); t }
- def EmptyTypeTree(tree: Tree) =
- { val t = new EmptyTypeTree(); t.setPos(tree.pos); t }
+ def TypeTree(tree: Tree) =
+ { val t = new TypeTree(); t.setPos(tree.pos); t }
def SingletonTypeTree(tree: Tree, ref: Tree) =
{ 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 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]) =
- { val t = new RefinementTypeTree(base, decls); t.setPos(tree.pos); t }
- def AppliedTypeTree(tree: Tree, tp: Tree, args: List[Tree]) =
- { val t = new AppliedTypeTree(tp, args); t.setPos(tree.pos); t }
+ def CompoundTypeTree(tree: Tree, parents: List[Tree], decls: List[Tree]) =
+ { val t = new CompoundTypeTree(parents, decls); t.setPos(tree.pos); t }
+ def AppliedTypeTree(tree: Tree, tpt: Tree, args: List[Tree]) =
+ { val t = new AppliedTypeTree(tpt, args); t.setPos(tree.pos); t }
}
class LazyTreeCopier(copy: TreeCopier) extends TreeCopier {
def this() = this(new StrictTreeCopier);
- def ClassDef(tree: Tree, mods: int, name: Name, tparams: List[AbsTypeDef], tp: Tree, impl: Template) = tree match {
- case t @ ClassDef(mods0, name0, tparams0, tp0, impl0)
- if (mods0 == mods && name0 == name && tparams0 == tparams && tp0 == tp && impl0 == impl) => t
- case _ => copy.ClassDef(tree, mods, name, tparams, tp, impl)
+ def ClassDef(tree: Tree, mods: int, name: Name, tparams: List[AbsTypeDef], tpt: Tree, impl: Template) = tree match {
+ case t @ ClassDef(mods0, name0, tparams0, tpt0, impl0)
+ if (mods0 == mods && (name0 == name) && (tparams0 == tparams) && (tpt0 == tpt) && (impl0 == impl)) => t
+ case _ => copy.ClassDef(tree, mods, name, tparams, tpt, impl)
}
def PackageDef(tree: Tree, name: Name, stats: List[Tree]) = tree match {
case t @ PackageDef(name0, stats0)
- if (name0 == name && stats0 == stats) => t
+ if ((name0 == name) && (stats0 == stats)) => t
case _ => copy.PackageDef(tree, name, stats)
}
- def ModuleDef(tree: Tree, mods: int, name: Name, tp: Tree, impl: Template) = tree match {
- case t @ ModuleDef(mods0, name0, tp0, impl0)
- if (mods0 == mods && name0 == name && tp0 == tp && impl0 == impl) => t
- case _ => copy.ModuleDef(tree, mods, name, tp, impl)
+ def ModuleDef(tree: Tree, mods: int, name: Name, impl: Template) = tree match {
+ case t @ ModuleDef(mods0, name0, impl0)
+ if (mods0 == mods && (name0 == name) && (impl0 == impl)) => t
+ case _ => copy.ModuleDef(tree, mods, name, impl)
}
- def ValDef(tree: Tree, mods: int, name: Name, tp: Tree, rhs: Tree) = tree match {
- case t @ ValDef(mods0, name0, tp0, rhs0)
- if (mods0 == mods && name0 == name && tp0 == tp && rhs0 == rhs) => t
- case _ => copy.ValDef(tree, mods, name, tp, rhs)
+ def ValDef(tree: Tree, mods: int, name: Name, tpt: Tree, rhs: Tree) = tree match {
+ case t @ ValDef(mods0, name0, tpt0, rhs0)
+ if (mods0 == mods && (name0 == name) && (tpt0 == tpt) && (rhs0 == rhs)) => t
+ case _ => copy.ValDef(tree, mods, name, tpt, rhs)
}
- def DefDef(tree: Tree, mods: int, name: Name, tparams: List[AbsTypeDef], vparams: List[List[ValDef]], tp: Tree, rhs: Tree) = tree match {
- case t @ DefDef(mods0, name0, tparams0, vparams0, tp0, rhs0)
- if (mods0 == mods && name0 == name && tparams0 == tparams && vparams0 == vparams && tp0 == tp && rhs == rhs0) => t
- case _ => copy.DefDef(tree, mods, name, tparams, vparams, tp, rhs)
+ def DefDef(tree: Tree, mods: int, name: Name, tparams: List[AbsTypeDef], vparamss: List[List[ValDef]], tpt: Tree, rhs: Tree) = tree match {
+ case t @ DefDef(mods0, name0, tparams0, vparamss0, tpt0, rhs0)
+ if (mods0 == mods && (name0 == name) && (tparams0 == tparams) && (vparamss0 == vparamss) && (tpt0 == tpt) && (rhs == rhs0)) => t
+ case _ => copy.DefDef(tree, mods, name, tparams, vparamss, tpt, rhs)
}
def AbsTypeDef(tree: Tree, mods: int, name: Name, lo: Tree, hi: Tree) = tree match {
case t @ AbsTypeDef(mods0, name0, lo0, hi0)
- if (mods0 == mods && name0 == name && lo0 == lo && hi0 == hi) => t
+ if (mods0 == mods && (name0 == name) && (lo0 == lo) && (hi0 == hi)) => t
case _ => copy.AbsTypeDef(tree, mods, name, lo, hi)
}
def AliasTypeDef(tree: Tree, mods: int, name: Name, tparams: List[AbsTypeDef], rhs: Tree) = tree match {
case t @ AliasTypeDef(mods0, name0, tparams0, rhs0)
- if (mods0 == mods && name0 == name && tparams0 == tparams && rhs0 == rhs) => t
+ if (mods0 == mods && (name0 == name) && (tparams0 == tparams) && (rhs0 == rhs)) => t
case _ => copy.AliasTypeDef(tree, mods, name, tparams, rhs)
}
def LabelDef(tree: Tree, name: Name, params: List[Ident], rhs: Tree) = tree match {
case t @ LabelDef(name0, params0, rhs0)
- if (name0 == name && params0 == params && rhs0 == rhs) => t
+ if ((name0 == name) && (params0 == params) && (rhs0 == rhs)) => t
case _ => copy.LabelDef(tree, name, params, rhs)
}
def Import(tree: Tree, expr: Tree, selectors: List[Pair[Name, Name]]) = tree match {
case t @ Import(expr0, selectors0)
- if (expr0 == expr && selectors0 == selectors) => t
+ if ((expr0 == expr) && (selectors0 == selectors)) => t
case _ => copy.Import(tree, expr, selectors)
}
def Attributed(tree: Tree, attribute: Tree, definition: Tree) = tree match {
case t @ Attributed(attribute0, definition0)
- if (attribute0 == attribute && definition0 == definition) => t
+ if ((attribute0 == attribute) && (definition0 == definition)) => t
case _ => copy.Attributed(tree, attribute, definition)
}
def DocDef(tree: Tree, comment: String, definition: Tree) = tree match {
case t @ DocDef(comment0, definition0)
- if (comment0 == comment && definition0 == definition) => t
+ if ((comment0 == comment) && (definition0 == definition)) => t
case _ => copy.DocDef(tree, comment, definition)
}
def Template(tree: Tree, parents: List[Tree], body: List[Tree]) = tree match {
case t @ Template(parents0, body0)
- if (parents0 == parents && body0 == body) => t
+ if ((parents0 == parents) && (body0 == body)) => t
case _ => copy.Template(tree, parents, body)
}
def Block(tree: Tree, stats: List[Tree], expr: Tree) = tree match {
case t @ Block(stats0, expr0)
- if (stats0 == stats && expr0 == expr) => t
+ if ((stats0 == stats) && (expr0 == expr)) => t
case _ => copy.Block(tree, stats, expr)
}
- def Visitor(tree: Tree, cases: List[CaseDef]) = tree match {
- case t @ Visitor(cases0)
- if (cases == cases0) => t
- case _ => copy.Visitor(tree, cases)
- }
def CaseDef(tree: Tree, pat: Tree, guard: Tree, body: Tree) = tree match {
case t @ CaseDef(pat0, guard0, body0)
- if (pat0 == pat && guard0 == guard && body0 == body) => t
+ if ((pat0 == pat) && (guard0 == guard) && (body0 == body)) => t
case _ => copy.CaseDef(tree, pat, guard, body)
}
def Sequence(tree: Tree, trees: List[Tree]) = tree match {
case t @ Sequence(trees0)
- if (trees0 == trees) => t
+ if ((trees0 == trees)) => t
case _ => copy.Sequence(tree, trees)
}
def Alternative(tree: Tree, trees: List[Tree]) = tree match {
case t @ Alternative(trees0)
- if (trees0 == trees) => t
+ if ((trees0 == trees)) => t
case _ => copy.Alternative(tree, trees)
}
- def Bind(tree: Tree, name: Name, rhs: Tree) = tree match {
- case t @ Bind(name0, rhs0)
- if (name0 == name && rhs0 == rhs) => t
- case _ => copy.Bind(tree, name, rhs)
+ def Bind(tree: Tree, name: Name, body: Tree) = tree match {
+ case t @ Bind(name0, body0)
+ if ((name0 == name) && (body0 == body)) => t
+ case _ => copy.Bind(tree, name, body)
}
def Function(tree: Tree, vparams: List[ValDef], body: Tree) = tree match {
case t @ Function(vparams0, body0)
- if (vparams0 == vparams && body0 == body) => t
+ if ((vparams0 == vparams) && (body0 == body)) => t
case _ => copy.Function(tree, vparams, body)
}
def Assign(tree: Tree, lhs: Tree, rhs: Tree) = tree match {
case t @ Assign(lhs0, rhs0)
- if (lhs0 == lhs && rhs0 == rhs) => t
+ if ((lhs0 == lhs) && (rhs0 == rhs)) => t
case _ => copy.Assign(tree, lhs, rhs)
}
def If(tree: Tree, cond: Tree, thenp: Tree, elsep: Tree) = tree match {
case t @ If(cond0, thenp0, elsep0)
- if (cond0 == cond && thenp0 == thenp && elsep0 == elsep) => t
+ if ((cond0 == cond) && (thenp0 == thenp) && (elsep0 == elsep)) => t
case _ => copy.If(tree, cond, thenp, elsep)
}
- 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
- case _ => copy.Switch(tree, test, tags, bodies, default)
+ def Match(tree: Tree, selector: Tree, cases: List[CaseDef]) = tree match {
+ case t @ Match(selector0, cases0)
+ if ((selector0 == selector) && (cases0 == cases)) => t
+ case _ => copy.Match(tree, selector, cases)
}
def Return(tree: Tree, expr: Tree) = tree match {
case t @ Return(expr0)
- if (expr0 == expr) => t
+ if ((expr0 == expr)) => t
case _ => copy.Return(tree, expr)
}
- def Try(tree: Tree, block: Tree, catcher: Tree, finalizer: Tree) = tree match {
- case t @ Try(block0, catcher0, finalizer0)
- if (block0 == block && catcher0 == catcher && finalizer0 == finalizer) => t
- case _ => copy.Try(tree, block, catcher, finalizer)
+ def Try(tree: Tree, block: Tree, catches: List[CaseDef], finalizer: Tree) = tree match {
+ case t @ Try(block0, catches0, finalizer0)
+ if ((block0 == block) && (catches0 == catches) && (finalizer0 == finalizer)) => t
+ case _ => copy.Try(tree, block, catches, finalizer)
}
def Throw(tree: Tree, expr: Tree) = tree match {
case t @ Throw(expr0)
- if (expr0 == expr) => t
+ if ((expr0 == expr)) => t
case _ => copy.Throw(tree, expr)
}
- def New(tree: Tree, typeOrTempl: Tree) = tree match {
- case t @ New(typeOrTempl0)
- if (typeOrTempl0 == typeOrTempl) => t
- case _ => copy.New(tree, typeOrTempl)
+ def New(tree: Tree, tpt: Tree) = tree match {
+ case t @ New(tpt0)
+ if ((tpt0 == tpt)) => t
+ case _ => copy.New(tree, tpt)
}
- def Typed(tree: Tree, expr: Tree, tp: Tree) = tree match {
- case t @ Typed(expr0, tp0)
- if (expr0 == expr && tp0 == tp) => t
- case _ => copy.Typed(tree, expr, tp)
+ def Typed(tree: Tree, expr: Tree, tpt: Tree) = tree match {
+ case t @ Typed(expr0, tpt0)
+ if ((expr0 == expr) && (tpt0 == tpt)) => t
+ case _ => copy.Typed(tree, expr, tpt)
}
def TypeApply(tree: Tree, fun: Tree, args: List[Tree]) = tree match {
case t @ TypeApply(fun0, args0)
- if (fun0 == fun && args0 == args) => t
+ if ((fun0 == fun) && (args0 == args)) => t
case _ => copy.TypeApply(tree, fun, args)
}
def Apply(tree: Tree, fun: Tree, args: List[Tree]) = tree match {
case t @ Apply(fun0, args0)
- if (fun0 == fun && args0 == args) => t
+ if ((fun0 == fun) && (args0 == args)) => t
case _ => copy.Apply(tree, fun, args)
}
def Super(tree: Tree, qual: Name, mixin: Name) = tree match {
case t @ Super(qual0, mixin0)
- if (qual0 == qual && mixin0 == mixin) => t
+ if ((qual0 == qual) && (mixin0 == mixin)) => t
case _ => copy.Super(tree, qual, mixin)
}
def This(tree: Tree, qual: Name) = tree match {
case t @ This(qual0)
- if (qual0 == qual) => t
+ if ((qual0 == qual)) => t
case _ => copy.This(tree, qual)
}
def Select(tree: Tree, qualifier: Tree, selector: Name) = tree match {
case t @ Select(qualifier0, selector0)
- if (qualifier0 == qualifier && selector0 == selector) => t
+ if ((qualifier0 == qualifier) && (selector0 == selector)) => t
case _ => copy.Select(tree, qualifier, selector)
}
def Ident(tree: Tree, name: Name) = tree match {
case t @ Ident(name0)
- if (name0 == name) => t
+ if ((name0 == name)) => t
case _ => copy.Ident(tree, name)
}
def Literal(tree: Tree, value: Any) = tree match {
@@ -579,34 +561,29 @@ class Trees: Global {
if (value0 == value) => t
case _ => copy.Literal(tree, value)
}
- def EmptyTypeTree(tree: Tree) = tree match {
- case t @ EmptyTypeTree() => t
- case _ => copy.EmptyTypeTree(tree)
+ def TypeTree(tree: Tree) = tree match {
+ case t @ TypeTree() => t
+ case _ => copy.TypeTree(tree)
}
def SingletonTypeTree(tree: Tree, ref: Tree) = tree match {
case t @ SingletonTypeTree(ref0)
- if (ref0 == ref) => t
+ if ((ref0 == ref)) => t
case _ => copy.SingletonTypeTree(tree, ref)
}
def SelectFromTypeTree(tree: Tree, qualifier: Tree, selector: Name) = tree match {
case t @ SelectFromTypeTree(qualifier0, selector0)
- if (qualifier0 == qualifier && selector0 == selector) => t
+ if ((qualifier0 == qualifier) && (selector0 == selector)) => t
case _ => copy.SelectFromTypeTree(tree, qualifier, selector)
}
- def IntersectionTypeTree(tree: Tree, parents: List[Tree]) = tree match {
- case t @ IntersectionTypeTree(parents0)
- if (parents0 == parents) => t
- case _ => copy.IntersectionTypeTree(tree, parents)
- }
- def RefinementTypeTree(tree: Tree, base: Tree, decls: List[Tree]) = tree match {
- case t @ RefinementTypeTree(base0, decls0)
- if (base0 == base && decls0 == decls) => t
- case _ => copy.RefinementTypeTree(tree, base, decls)
+ def CompoundTypeTree(tree: Tree, parents: List[Tree], decls: List[Tree]) = tree match {
+ case t @ CompoundTypeTree(parents0, decls0)
+ if ((parents0 == parents) && (decls0 == decls)) => t
+ case _ => copy.CompoundTypeTree(tree, parents, decls)
}
- def AppliedTypeTree(tree: Tree, tp: Tree, args: List[Tree]) = tree match {
- case t @ AppliedTypeTree(tp0, args0)
- if (tp0 == tp && args0 == args) => t
- case _ => copy.AppliedTypeTree(tree, tp, args)
+ def AppliedTypeTree(tree: Tree, tpt: Tree, args: List[Tree]) = tree match {
+ case t @ AppliedTypeTree(tpt0, args0)
+ if ((tpt0 == tpt) && (args0 == args)) => t
+ case _ => copy.AppliedTypeTree(tree, tpt, args)
}
}
@@ -615,16 +592,16 @@ class Trees: Global {
def transform(tree: Tree): Tree = tree match {
case EmptyTree =>
tree
- case ClassDef(mods, name, tparams, tp, impl) =>
- copy.ClassDef(tree, mods, name, transformAbsTypeDefs(tparams), transform(tp), transformTemplate(impl))
+ case ClassDef(mods, name, tparams, tpt, impl) =>
+ copy.ClassDef(tree, mods, name, transformAbsTypeDefs(tparams), transform(tpt), transformTemplate(impl))
case PackageDef(name, stats) =>
copy.PackageDef(tree, name, transformTrees(stats))
- case ModuleDef(mods, name, tp, impl) =>
- copy.ModuleDef(tree, mods, name, transform(tp), transformTemplate(impl))
- case ValDef(mods, name, tp, rhs) =>
- copy.ValDef(tree, mods, name, transform(tp), transform(rhs))
- case DefDef(mods, name, tparams, vparams, tp, rhs) =>
- copy.DefDef(tree, mods, name, transformAbsTypeDefs(tparams), transformValDefss(vparams), transform(tp), transform(rhs))
+ case ModuleDef(mods, name, impl) =>
+ copy.ModuleDef(tree, mods, name, transformTemplate(impl))
+ case ValDef(mods, name, tpt, rhs) =>
+ copy.ValDef(tree, mods, name, transform(tpt), transform(rhs))
+ case DefDef(mods, name, tparams, vparamss, tpt, rhs) =>
+ copy.DefDef(tree, mods, name, transformAbsTypeDefs(tparams), transformValDefss(vparamss), transform(tpt), transform(rhs))
case AbsTypeDef(mods, name, lo, hi) =>
copy.AbsTypeDef(tree, mods, name, transform(lo), transform(hi))
case AliasTypeDef(mods, name, tparams, rhs) =>
@@ -641,34 +618,32 @@ class Trees: Global {
copy.Template(tree, transformTrees(parents), transformTrees(body))
case Block(stats, expr) =>
copy.Block(tree, transformTrees(stats), transform(expr))
- case Visitor(cases) =>
- copy.Visitor(tree, transformCaseDefs(cases))
case CaseDef(pat, guard, body) =>
copy.CaseDef(tree, transform(pat), transform(guard), transform(body))
case Sequence(trees) =>
copy.Sequence(tree, transformTrees(trees))
case Alternative(trees) =>
copy.Alternative(tree, transformTrees(trees))
- case Bind(name, rhs) =>
- copy.Bind(tree, name, transform(rhs))
+ case Bind(name, body) =>
+ copy.Bind(tree, name, transform(body))
case Function(vparams, body) =>
copy.Function(tree, transformValDefs(vparams), transform(body))
case Assign(lhs, rhs) =>
copy.Assign(tree, transform(lhs), transform(rhs))
case If(cond, thenp, elsep) =>
copy.If(tree, transform(cond), transform(thenp), transform(elsep))
- case Switch(test, tags, bodies, default) =>
- copy.Switch(tree, transform(test), tags, transformTrees(bodies), transform(default))
+ case Match(selector, cases) =>
+ copy.Match(tree, transform(selector), transformCaseDefs(cases))
case Return(expr) =>
copy.Return(tree, transform(expr))
- case Try(block, catcher, finalizer) =>
- copy.Try(tree, transform(block), transform(catcher), transform(finalizer))
+ case Try(block, catches, finalizer) =>
+ copy.Try(tree, transform(block), transformCaseDefs(catches), transform(finalizer))
case Throw(expr) =>
copy.Throw(tree, transform(expr))
- case New(typeOrTempl) =>
- copy.New(tree, transform(typeOrTempl))
- case Typed(expr, tp) =>
- copy.Typed(tree, transform(expr), transform(tp))
+ case New(tpt) =>
+ copy.New(tree, transform(tpt))
+ case Typed(expr, tpt) =>
+ copy.Typed(tree, transform(expr), transform(tpt))
case TypeApply(fun, args) =>
copy.TypeApply(tree, transform(fun), transformTrees(args))
case Apply(fun, args) =>
@@ -683,48 +658,46 @@ class Trees: Global {
copy.Ident(tree, name)
case Literal(value) =>
copy.Literal(tree, value)
- case EmptyTypeTree() =>
- copy.EmptyTypeTree(tree)
+ case TypeTree() =>
+ copy.TypeTree(tree)
case SingletonTypeTree(ref) =>
copy.SingletonTypeTree(tree, transform(ref))
case SelectFromTypeTree(qualifier, selector) =>
copy.SelectFromTypeTree(tree, transform(qualifier), selector)
- case IntersectionTypeTree(parents) =>
- copy.IntersectionTypeTree(tree, transformTrees(parents))
- case RefinementTypeTree(base, decls) =>
- copy.RefinementTypeTree(tree, transform(base), transformTrees(decls))
- case AppliedTypeTree(tp, args) =>
- copy.AppliedTypeTree(tree, transform(tp), transformTrees(args))
+ case CompoundTypeTree(parents, decls) =>
+ copy.CompoundTypeTree(tree, transformTrees(parents), transformTrees(decls))
+ case AppliedTypeTree(tpt, args) =>
+ copy.AppliedTypeTree(tree, transform(tpt), transformTrees(args))
}
def transformTrees(trees: List[Tree]): List[Tree] =
- List.transform(trees)(tree => transform(tree));
+ trees mapConserve (tree => transform(tree));
def transformTemplate(tree: Template): Template =
transform(tree: Tree).asInstanceOf[Template];
def transformAbsTypeDefs(trees: List[AbsTypeDef]): List[AbsTypeDef] =
- List.transform(trees)(tree => transform(tree).asInstanceOf[AbsTypeDef]);
+ trees mapConserve (tree => transform(tree).asInstanceOf[AbsTypeDef]);
def transformValDefs(trees: List[ValDef]): List[ValDef] =
- List.transform(trees)(tree => transform(tree).asInstanceOf[ValDef]);
+ trees mapConserve (tree => transform(tree).asInstanceOf[ValDef]);
def transformValDefss(treess: List[List[ValDef]]): List[List[ValDef]] =
- List.transform(treess)(tree => transformValDefs(tree));
+ treess mapConserve (tree => transformValDefs(tree));
def transformCaseDefs(trees: List[CaseDef]): List[CaseDef] =
- List.transform(trees)(tree => transform(tree).asInstanceOf[CaseDef]);
+ trees mapConserve (tree => transform(tree).asInstanceOf[CaseDef]);
def transformIdents(trees: List[Ident]): List[Ident] =
- List.transform(trees)(tree => transform(tree).asInstanceOf[Ident]);
+ trees mapConserve (tree => transform(tree).asInstanceOf[Ident]);
}
class Traverser {
def traverse(tree: Tree): unit = tree match {
- case ClassDef(mods, name, tparams, tp, impl) =>
- traverseTrees(tparams); traverse(tp); traverse(impl)
+ case ClassDef(mods, name, tparams, tpt, impl) =>
+ traverseTrees(tparams); traverse(tpt); traverse(impl)
case PackageDef(name, stats) =>
traverseTrees(stats)
- case ModuleDef(mods, name, tp, impl) =>
- traverse(tp); traverse(impl)
- case ValDef(mods, name, tp, rhs) =>
- traverse(tp); traverse(rhs)
- case DefDef(mods, name, tparams, vparams, tp, rhs) =>
- traverseTrees(tparams); traverseTreess(vparams); traverse(tp); traverse(rhs)
+ case ModuleDef(mods, name, impl) =>
+ traverse(impl)
+ case ValDef(mods, name, tpt, rhs) =>
+ traverse(tpt); traverse(rhs)
+ case DefDef(mods, name, tparams, vparamss, tpt, rhs) =>
+ traverseTrees(tparams); traverseTreess(vparamss); traverse(tpt); traverse(rhs)
case AbsTypeDef(mods, name, lo, hi) =>
traverse(lo); traverse(hi);
case AliasTypeDef(mods, name, tparams, rhs) =>
@@ -741,34 +714,32 @@ class Trees: Global {
traverseTrees(parents); traverseTrees(body)
case Block(stats, expr) =>
traverseTrees(stats); traverse(expr)
- case Visitor(cases) =>
- traverseTrees(cases)
case CaseDef(pat, guard, body) =>
traverse(pat); traverse(guard); traverse(body)
case Sequence(trees) =>
traverseTrees(trees)
case Alternative(trees) =>
traverseTrees(trees)
- case Bind(name, rhs) =>
- traverse(rhs)
+ case Bind(name, body) =>
+ traverse(body)
case Function(vparams, body) =>
traverseTrees(vparams); traverse(body)
case Assign(lhs, rhs) =>
traverse(lhs); traverse(rhs)
case If(cond, thenp, elsep) =>
traverse(cond); traverse(thenp); traverse(elsep)
- case Switch(test, tags, bodies, default) =>
- traverse(test); traverseTrees(bodies); traverse(default)
+ case Match(selector, cases) =>
+ traverse(selector); traverseTrees(cases)
case Return(expr) =>
traverse(expr)
- case Try(block, catcher, finalizer) =>
- traverse(block); traverse(catcher); traverse(finalizer)
+ case Try(block, catches, finalizer) =>
+ traverse(block); traverseTrees(catches); traverse(finalizer)
case Throw(expr) =>
traverse(expr)
- case New(typeOrTempl) =>
- traverse(typeOrTempl)
- case Typed(expr, tp) =>
- traverse(expr); traverse(tp)
+ case New(tpt) =>
+ traverse(tpt)
+ case Typed(expr, tpt) =>
+ traverse(expr); traverse(tpt)
case TypeApply(fun, args) =>
traverse(fun); traverseTrees(args)
case Apply(fun, args) =>
@@ -779,13 +750,11 @@ class Trees: Global {
traverse(ref)
case SelectFromTypeTree(qualifier, selector) =>
traverse(qualifier)
- case IntersectionTypeTree(parents) =>
- traverseTrees(parents)
- case RefinementTypeTree(base, decls) =>
- traverse(base); traverseTrees(decls)
- case AppliedTypeTree(tp, args) =>
- traverse(tp); traverseTrees(args)
- case EmptyTree | Super(_, _) | This(_) | Ident(_) | Literal(_) | EmptyTypeTree() =>
+ case CompoundTypeTree(parents, decls) =>
+ traverseTrees(parents); traverseTrees(decls)
+ case AppliedTypeTree(tpt, args) =>
+ traverse(tpt); traverseTrees(args)
+ case EmptyTree | Super(_, _) | This(_) | Ident(_) | Literal(_) | TypeTree() =>
{}
}
diff --git a/sources/scala/tools/nsc/ast/parser/Lexical.scala b/sources/scala/tools/nsc/ast/parser/Lexical.scala
index d7ab47f91a..318ae77395 100644
--- a/sources/scala/tools/nsc/ast/parser/Lexical.scala
+++ b/sources/scala/tools/nsc/ast/parser/Lexical.scala
@@ -729,6 +729,7 @@ abstract class Lexical: ParserPhase {
enterKeyword("for", FOR);
enterKeyword("if", IF);
enterKeyword("import", IMPORT);
+ enterKeyword("match", MATCH);
enterKeyword("new", NEW);
enterKeyword("null", NULL);
enterKeyword("object", OBJECT);
diff --git a/sources/scala/tools/nsc/ast/parser/Syntactic.scala b/sources/scala/tools/nsc/ast/parser/Syntactic.scala
index b819d0e6e6..9f9e34d48e 100755
--- a/sources/scala/tools/nsc/ast/parser/Syntactic.scala
+++ b/sources/scala/tools/nsc/ast/parser/Syntactic.scala
@@ -57,10 +57,12 @@ abstract class Syntactic: ParserPhase {
object treeBuilder extends TreeBuilder {
val global: Syntactic.this.global.type = Syntactic.this.global;
- def freshName(): Name = unit.fresh.newName("x$");
+ def freshName(prefix: String): Name = unit.fresh.newName(prefix);
}
import treeBuilder._;
+
+
/** this is the general parse method
*/
def parse(): List[Tree] = {
@@ -119,7 +121,7 @@ abstract class Syntactic: ParserPhase {
pos
}
- def errorTypeTree = EmptyTypeTree().setType(ErrorType).setPos(in.pos);
+ def errorTypeTree = TypeTree().setType(ErrorType).setPos(in.pos);
def errorTermTree = Literal(null).setPos(in.pos);
def errorPatternTree = Ident(nme.WILDCARD).setPos(in.pos);
@@ -180,7 +182,7 @@ abstract class Syntactic: ParserPhase {
/** Convert tree to formal parameter list
*/
def convertToParams(t: Tree): List[ValDef] = t match {
- case Function(params, EmptyTypeTree()) =>
+ case Function(params, TypeTree()) =>
params
case Ident(_) | Typed(Ident(_), _) =>
List(convertToParam(t));
@@ -197,7 +199,7 @@ abstract class Syntactic: ParserPhase {
atPos(tree.pos) {
tree match {
case Ident(name) =>
- ValDef(Flags.PARAM, name, EmptyTypeTree(), EmptyTree)
+ ValDef(Flags.PARAM, name, TypeTree(), EmptyTree)
case Typed(Ident(name), tpe) =>
ValDef(Flags.PARAM, name, tpe, EmptyTree)
case _ =>
@@ -219,16 +221,9 @@ abstract class Syntactic: ParserPhase {
errorTypeTree
}
- /** Complete unapplied constructor with `()' arguments
- */
- def applyConstr(t: Tree): Tree = t match {
- case Apply(_, _) => t
- case _ => Apply(t, List()) setPos t.pos
- }
-
/** make closure from tree */
def makeClosure(tree: Tree): Tree = {
- val pname = freshName();
+ val pname: Name = unit.fresh.newName("x$");
def insertParam(tree: Tree): Tree = tree match {
case Ident(name) =>
Select(Ident(pname), name)
@@ -243,7 +238,7 @@ abstract class Syntactic: ParserPhase {
errorTermTree
}
Function(
- List(ValDef(Flags.PARAM, pname, EmptyTypeTree(), EmptyTree)),
+ List(ValDef(Flags.PARAM, pname, TypeTree(), EmptyTree)),
insertParam(tree))
}
@@ -445,13 +440,13 @@ abstract class Syntactic: ParserPhase {
*/
def typedOpt(): Tree =
if (in.token == COLON) { in.nextToken(); typ() }
- else EmptyTypeTree();
+ else TypeTree();
/** SimpleTypedOpt ::= [`:' SimpleType]
*/
def simpleTypedOpt(): Tree =
if (in.token == COLON) { in.nextToken(); simpleType() }
- else EmptyTypeTree();
+ else TypeTree();
/** Types ::= Type {`,' Type}
*/
@@ -498,17 +493,14 @@ abstract class Syntactic: ParserPhase {
*/
def type1(): Tree = {
val pos = in.pos;
- var t = simpleType();
- if (in.token == WITH) {
- val ts = new ListBuffer[Tree] + t;
- while (in.token == WITH) {
- in.nextToken(); ts += simpleType()
- }
- t = atPos(pos) { IntersectionTypeTree(ts.toList) }
+ var ts = new ListBuffer[Tree] + simpleType();
+ while (in.token == WITH) {
+ in.nextToken(); ts += simpleType()
+ }
+ atPos(pos) {
+ if (in.token == LBRACE) CompoundTypeTree(ts.toList, refinement())
+ else makeIntersectionTypeTree(ts.toList)
}
- if (in.token == LBRACE)
- t = atPos(pos) { RefinementTypeTree(t, refinement()) }
- t
}
/** SimpleType ::= SimpleType TypeArgs
@@ -578,7 +570,7 @@ abstract class Syntactic: ParserPhase {
* ResultExpr ::= Bindings `=>' Block
* | Expr1
* Expr1 ::= (' Expr `)' Expr [[`;'] else Expr]
- * | try `{' block `}' [catch Expr] [finally Expr]
+ * | try `{' block `}' [catch `{' caseClauses `}'] [finally Expr]
* | while `(' Expr `)' Expr
* | do Expr [`;'] while `(' Expr `)'
* | for `(' Enumerators `)' (do | yield) Expr
@@ -588,6 +580,7 @@ abstract class Syntactic: ParserPhase {
* | SimpleExpr ArgumentExprs `=' Expr
* | `.' SimpleExpr
* | PostfixExpr [`:' Type1]
+ * | PostfixExpr match `{' caseClauses `}'
* Bindings ::= Id [`:' Type1]
* | `(' [Binding {`,' Binding}] `)'
* Binding ::= Id [`:' Type]
@@ -611,13 +604,18 @@ abstract class Syntactic: ParserPhase {
accept(LBRACE);
val body = block();
accept(RBRACE);
- val catcher =
- if (in.token == CATCH) { in.nextToken(); expr() }
- else EmptyTree;
+ val catches =
+ if (in.token == CATCH) {
+ in.nextToken();
+ accept(LBRACE);
+ val cases = caseClauses();
+ accept(RBRACE);
+ cases
+ } else List();
val finalizer =
if (in.token == FINALLY) { in.nextToken(); expr() }
else EmptyTree;
- Try(body, catcher, finalizer)
+ Try(body, catches, finalizer)
}
} else if (in.token == WHILE) {
val lname: Name = "label$" + loopNestingDepth;
@@ -668,7 +666,7 @@ abstract class Syntactic: ParserPhase {
if (in.token == EQUALS) {
t match {
case Ident(_) | Select(_, _) | Apply(_, _) =>
- t = atPos(in.skipToken()) { Assign(t, expr()) }
+ t = atPos(in.skipToken()) { makeAssign(t, expr()) }
case _ =>
}
} else if (in.token == COLON) {
@@ -686,7 +684,14 @@ abstract class Syntactic: ParserPhase {
} else {
t = atPos(pos) { Typed(t, type1()) }
}
- }
+ } else if (in.token == MATCH) {
+ t = atPos(in.skipToken()) {
+ accept(LBRACE);
+ val cases = caseClauses();
+ accept(RBRACE);
+ Match(t, cases): Tree
+ }
+ }
if (in.token == ARROW) {
t = atPos(in.skipToken()) {
Function(convertToParams(t), if (isInBlock) block() else expr())
@@ -769,7 +774,7 @@ abstract class Syntactic: ParserPhase {
accept(RPAREN);
if (in.token == ARROW) {
t = atPos(pos) {
- Function(ts.toList map convertToParam, EmptyTypeTree())
+ Function(ts.toList map convertToParam, TypeTree())
}
} else {
syntaxError(commapos, "`)' expected", false);
@@ -790,11 +795,7 @@ abstract class Syntactic: ParserPhase {
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))
+ makeNew(parents.toList, stats, args)
}
case _ =>
syntaxError("illegal start of simple expression", true);
@@ -834,22 +835,13 @@ abstract class Syntactic: ParserPhase {
}
}
- /** BlockExpr ::= `{' CaseClause {CaseClause} `}'
- * | `{' Block `}'
+ /** BlockExpr ::= `{' CaseClauses | Block `}'
*/
def blockExpr(): Tree = {
- val res =
- atPos(accept(LBRACE)) {
- if (in.token == CASE) {
- var stats: List[CaseDef] = List();
- do {
- stats = caseClause() :: stats;
- } while (in.token == CASE);
- Visitor(stats.reverse)
- } else {
- block()
- }
- }
+ val res = atPos(accept(LBRACE)) {
+ if (in.token == CASE) makeVisitor(caseClauses())
+ else block()
+ }
accept(RBRACE);
res
}
@@ -858,6 +850,15 @@ abstract class Syntactic: ParserPhase {
*/
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);
+ ts.toList
+ }
+
/** caseClause : =>= case Pattern [if PostfixExpr] `=>' Block
*/
def caseClause(): CaseDef =
@@ -1381,7 +1382,7 @@ abstract class Syntactic: ParserPhase {
val vparams = List(paramClause(false));
accept(EQUALS);
DefDef(
- mods, nme.CONSTRUCTOR, List(), vparams, EmptyTypeTree(), constrExpr())
+ mods, nme.CONSTRUCTOR, List(), vparams, TypeTree(), constrExpr())
})
else {
var newmods = mods;
@@ -1481,39 +1482,27 @@ abstract class Syntactic: ParserPhase {
if ((mods & Flags.TRAIT) != 0) List() else paramClauses(true))
} while (in.token == COMMA);
val thistpe = simpleTypedOpt();
- val Template(parents, body) = classTemplate(mods);
+ val template = classTemplate(mods);
for (val Tuple4(pos, name, tparams, vparamss) <- lhs.toList) yield
atPos(pos) {
- 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))
+ val template1 = if ((mods & Flags.TRAIT) != 0) template
+ else addConstructor(mods, vparamss, template);
+ ClassDef(mods, name, tparams, thistpe.duplicate, template1.duplicate.asInstanceOf[Template])
}
}
- /** ObjectDef ::= Id { , Id } [`:' SimpleType] ClassTemplate
+ /** ObjectDef ::= Id { , Id } ClassTemplate
*/
def objectDef(mods: int): List[Tree] = {
val lhs = new ListBuffer[Pair[Int, Name]];
do {
lhs += Pair(in.skipToken(), ident());
} while (in.token == COMMA);
- val thistpe = simpleTypedOpt();
val template = classTemplate(mods);
for (val Pair(pos, name) <- lhs.toList) yield
atPos(pos) {
- ModuleDef(mods, name, thistpe.duplicate,
- template.duplicate.asInstanceOf[Template])
+ val template1 = addConstructor(mods, List(), template);
+ ModuleDef(mods, name, template1.duplicate.asInstanceOf[Template])
}
}
@@ -1548,17 +1537,6 @@ abstract class Syntactic: ParserPhase {
////////// TEMPLATES ////////////////////////////////////////////////////////////
- /** Constr ::= StableId [TypeArgs] [`(' [Exprs] `)']
- */
- def constr(): Tree = {
- var t: Tree = convertToTypeId(stableId());
- if (in.token == LBRACKET)
- t = AppliedTypeTree(t, typeArgs()) setPos in.pos;
- if (in.token == LPAREN)
- t = Apply(t, argumentExprs()) setPos in.pos;
- applyConstr(t)
- }
-
/** TemplateBody ::= `{' [TemplateStat {`;' TemplateStat}] `}'
*/
def templateBody(): List[Tree] = {
@@ -1649,22 +1627,31 @@ abstract class Syntactic: ParserPhase {
/** AttributeClauses ::= {AttributeClause}
* AttributeClause ::= `[' Attribute {`,' Attribute} `]'
- * Attribute ::= Constr
*/
def attributeClauses(): List[Tree] = {
var attrs = new ListBuffer[Tree];
while (in.token == LBRACKET) {
in.nextToken();
- attrs += constr();
+ attrs += attribute();
while (in.token == COMMA) {
in.nextToken();
- attrs += constr()
+ attrs += attribute()
}
accept(RBRACKET);
}
attrs.toList
}
+ /** Attribute ::= StableId [TypeArgs] [`(' [Exprs] `)']
+ */
+ def attribute(): Tree = {
+ var t: Tree = convertToTypeId(stableId());
+ if (in.token == LBRACKET)
+ t = atPos(in.pos)(AppliedTypeTree(t, typeArgs()));
+ val args = if (in.token == LPAREN) argumentExprs() else List();
+ makeNew(List(t), List(), args)
+ }
+
def joinAttributes(attrs: List[Tree], defs: List[Tree]): List[Tree] =
defs map (defn =>
(attrs :\ defn) ((attr, tree) => Attributed(attr, tree) setPos attr.pos));
diff --git a/sources/scala/tools/nsc/ast/parser/Tokens.scala b/sources/scala/tools/nsc/ast/parser/Tokens.scala
index 8b26a259ca..1908ee70f1 100644
--- a/sources/scala/tools/nsc/ast/parser/Tokens.scala
+++ b/sources/scala/tools/nsc/ast/parser/Tokens.scala
@@ -64,6 +64,7 @@ object Tokens {
val FINALLY = 55;
val WHILE = 56;
val RETURN = 57;
+ val MATCH = 58;
/** special symbols */
val COMMA = 61;
diff --git a/sources/scala/tools/nsc/symtab/Definitions.scala b/sources/scala/tools/nsc/symtab/Definitions.scala
index ea570ae388..ae927fd6c1 100755
--- a/sources/scala/tools/nsc/symtab/Definitions.scala
+++ b/sources/scala/tools/nsc/symtab/Definitions.scala
@@ -73,6 +73,9 @@ abstract class Definitions: SymbolTable {
typeRef(sym.info.prefix, sym, formals ::: List(restpe))
}
+ def seqType(arg: Type) =
+ typeRef(SeqClass.info.prefix, SeqClass, List(arg));
+
// members of class scala.Any
var Any_== : Symbol = _;
var Any_!= : Symbol = _;
@@ -81,7 +84,6 @@ abstract class Definitions: SymbolTable {
var Any_toString : Symbol = _;
var Any_isInstanceOf: Symbol = _;
var Any_asInstanceOf: Symbol = _;
- var Any_match : Symbol = _;
// members of class java.lang.{Object, String}
var Object_eq : Symbol = _;
@@ -145,7 +147,7 @@ abstract class Definitions: SymbolTable {
JavaPackage = getModule("java");
JavaLangPackage = getModule("java.lang");
ScalaPackage = getModule("scala");
- ScalaPackageClass = ScalaPackage.moduleClass;
+ ScalaPackageClass = ScalaPackage.tpe.symbol;
AnyClass = newClass(ScalaPackageClass, "Any", List());
AnyValClass = getClass("scala.AnyVal");
@@ -220,15 +222,6 @@ abstract class Definitions: SymbolTable {
{ val tparam = newTypeParam(Any_asInstanceOf, 0);
Any_asInstanceOf.setInfo(PolyType(List(tparam), tparam.typeConstructor));
}
- Any_match = newMethod(AnyClass, "match")
- .setFlag(FINAL);
- { val tparam0 = newTypeParam(Any_match, 0);
- val tparam1 = newTypeParam(Any_match, 1);
- Any_match.setInfo(
- PolyType(
- List(tparam0, tparam1),
- MethodType(List(tparam0.typeConstructor), tparam1.typeConstructor)));
- }
// members of class java.lang.{Object, String}
Object_eq = newMethod(ObjectClass, "eq")
diff --git a/sources/scala/tools/nsc/symtab/Flags.scala b/sources/scala/tools/nsc/symtab/Flags.scala
index cfa93b8709..1df4f985f3 100644
--- a/sources/scala/tools/nsc/symtab/Flags.scala
+++ b/sources/scala/tools/nsc/symtab/Flags.scala
@@ -39,14 +39,14 @@ object Flags {
val SYNTHETIC = 0x00100000; // symbol is compiler-generated
val STABLE = 0x00200000; // functions that are assumed to be stable
// (typically, access methods for valdefs)
- val INITIALIZED = 0x00300000; // symbol's definition is complete
- val LOCKED = 0x00400000; // temporary flag to catch cyclic dependencies
+ val INITIALIZED = 0x00400000; // symbol's definition is complete
+ val LOCKED = 0x00800000; // temporary flag to catch cyclic dependencies
val ACCESSED = 0x01000000; // symbol was accessed at least once
val SELECTOR = 0x02000000; // symbol was used as selector in Select
- val CAPTURED = 0x04000000; // variables is accessed from nested function. Set by LambdaLift
- val ACCESSOR = 0x08000000; // function is an access function for a value or variable
+ val CAPTURED = 0x04000000; // variable is accessed from nested function. Set by LambdaLift
+ val ACCESSOR = 0x08000000; // a value or variable accessor
val ACCESS_METHOD = 0x10000000; // function is an access function for a method in some
// outer class; set by ExplicitOuter
@@ -60,9 +60,9 @@ object Flags {
val IS_ERROR = 0x200000000l; // symbol is an error symbol
val OVERLOADED = 0x400000000l; // symbol is overloaded
- val TRANS_FLAG = 0x1000000000l; // transient flag guaranteed to be reset after each phase.
- val LIFTED = TRANS_FLAG; // transient flag for lambdalift
- val INCONSTRUCTOR = TRANS_FLAG; // transient flag for analyzer
+ val TRANS_FLAG = 0x1000000000l; // transient flag guaranteed to be reset after each phase.
+ val LIFTED = TRANS_FLAG; // transient flag for lambdalift
+ val INCONSTRUCTOR = TRANS_FLAG; // transient flag for analyzer
// masks
val SOURCEFLAGS = 0x00077777; // these modifiers can be set in source programs.
diff --git a/sources/scala/tools/nsc/symtab/StdNames.scala b/sources/scala/tools/nsc/symtab/StdNames.scala
index 5cbd8d0169..1da9ebc888 100755
--- a/sources/scala/tools/nsc/symtab/StdNames.scala
+++ b/sources/scala/tools/nsc/symtab/StdNames.scala
@@ -126,7 +126,6 @@ abstract class StdNames: SymbolTable {
val java = newTermName("java");
val lang = newTermName("lang");
val length = newTermName("length");
- val _match = newTermName("match");
val map = newTermName("map");
val n = newTermName("n");
val nobinding = newTermName("nobinding");
diff --git a/sources/scala/tools/nsc/symtab/Symbols.scala b/sources/scala/tools/nsc/symtab/Symbols.scala
index 6f4f89f899..80137e3f91 100755
--- a/sources/scala/tools/nsc/symtab/Symbols.scala
+++ b/sources/scala/tools/nsc/symtab/Symbols.scala
@@ -90,9 +90,11 @@ abstract class Symbols: SymbolTable {
final def isValue = isTerm && !(isModule && ((rawflags & (PACKAGE | JAVA)) != 0));
final def isVariable = isTerm && (rawflags & MUTABLE) != 0;
+ final def isGetter = isTerm && (rawflags & ACCESSOR) != 0 && !name.endsWith(nme._EQ);
+ final def isSetter = isTerm && (rawflags & ACCESSOR) != 0 && name.endsWith(nme._EQ);
final def isValueParameter = isTerm && (rawflags & PARAM) != 0;
final def isLocalDummy = isTerm && (name startsWith nme.LOCAL_PREFIX);
- final def isMethod = isTerm && (rawflags & METHOD) != 0;
+ final def isMethod = isTerm && (rawflags & (METHOD | STABLE)) == METHOD;
final def isLabel = isTerm && (rawflags & LABEL) != 0;
final def isConstructor = isTerm && name == nme.CONSTRUCTOR;
final def isModule = isTerm && (rawflags & MODULE) != 0;
@@ -130,6 +132,9 @@ abstract class Symbols: SymbolTable {
isTerm && (
hasFlag(PRIVATE) || isLocal || owner.isClass && owner.hasFlag(FINAL | MODULE));
+ /** Is this symbol a sealed class?*/
+ final def isSealed: boolean =
+ isClass && (hasFlag(SEALED) || isSubClass(AnyValClass) || isSubClass(ArrayClass));
/** Is this symbol locally defined? I.e. not a member of a class or module */
final def isLocal: boolean = owner.isTerm || hasFlag(LOCAL);
@@ -158,18 +163,13 @@ abstract class Symbols: SymbolTable {
final def flags = {
initialize; rawflags & phase.flagMask
}
- final def setFlag(mask: long): Symbol = {
- rawflags = rawflags | mask; this
- }
- final def resetFlag(mask: long): Symbol = {
- rawflags = rawflags & ~mask; this
- }
+ final def setFlag(mask: long): this.type = { rawflags = rawflags | mask; this }
+ final def resetFlag(mask: long): this.type = { rawflags = rawflags & ~mask; this }
final def getFlag(mask: long): long =
(if ((mask & ~CREATIONFLAGS) == 0) rawflags else flags) & mask;
final def hasFlag(mask: long): boolean =
((if ((mask & ~CREATIONFLAGS) == 0) rawflags else flags) & mask) != 0;
- final def resetFlags =
- rawflags = rawflags & SOURCEFLAGS;
+ final def resetFlags: unit = { rawflags = rawflags & SOURCEFLAGS }
// Info and Type -------------------------------------------------------------------
@@ -210,7 +210,7 @@ abstract class Symbols: SymbolTable {
}
/** Set initial info. */
- def setInfo(info: Type): Symbol = {
+ def setInfo(info: Type): this.type = {
infos = new TypeHistory(phase, info, null);
limit = phase;
assert(info != null, "setInfo(null) for " + name + " at phase " + phase);//debug
@@ -383,7 +383,7 @@ abstract class Symbols: SymbolTable {
/** Return every accessor of a primary constructor parameter in this case class */
final def caseFieldAccessors: List[Symbol] = {
assert(isClass && hasFlag(CASE));
- info.decls.toList.filter(sym => sym.isMethod && sym.hasFlag(PARAMACCESSOR))
+ info.decls.toList.filter(sym => !sym.hasFlag(PARAM) && sym.hasFlag(PARAMACCESSOR))
}
/** The symbol accessed by this accessor function.
@@ -416,7 +416,7 @@ abstract class Symbols: SymbolTable {
/** The module corresponding to this module class (note that this
* is not updated when a module is cloned).
*/
- def sourceModule: Symbol = NoSymbol;
+ //def sourceModule: Symbol = NoSymbol;
/** The module class corresponding to this module.
*/
@@ -506,7 +506,7 @@ abstract class Symbols: SymbolTable {
final def locationString: String =
if (owner.isClass &&
(!owner.isAnonymousClass && !owner.isRefinementClass || settings.debug.value))
- " in " + (if (owner.isModuleClass) owner.sourceModule else owner)
+ " in " + (if (owner.isModuleClass) "object " + owner.nameString else owner)
else "";
/** String representation of symbol's definition following its name */
@@ -639,13 +639,13 @@ abstract class Symbols: SymbolTable {
class ModuleClassSymbol(module: ModuleSymbol)
extends ClassSymbol(module.owner, module.pos, module.name.toTypeName) {
setFlag(module.getFlag(MODULE2CLASSFLAGS) | MODULE | FINAL);
- override def sourceModule = module;
+ //override def sourceModule = module;
}
/** An object repreesenting a missing symbol */
object NoSymbol extends Symbol(null, Position.NOPOS, nme.NOSYMBOL) {
super.setInfo(NoType);
- override def setInfo(info: Type): Symbol = { assert(info == NoType); this }
+ override def setInfo(info: Type): this.type = { assert(info == NoType); this }
override def enclClass: Symbol = this;
override def enclMethod: Symbol = this;
override def owner: Symbol = throw new Error();
diff --git a/sources/scala/tools/nsc/symtab/Types.scala b/sources/scala/tools/nsc/symtab/Types.scala
index 38b061a39e..9d8c8f90f0 100755
--- a/sources/scala/tools/nsc/symtab/Types.scala
+++ b/sources/scala/tools/nsc/symtab/Types.scala
@@ -48,6 +48,10 @@ abstract class Types: SymbolTable {
* identity for all other types */
def widen: Type = this;
+ /** The type of `this' of a class type or reference type
+ */
+ def typeOfThis = symbol.typeOfThis;
+
/** Map to a this type which is a subtype of this type.
*/
def narrow: Type =
@@ -561,6 +565,8 @@ abstract class Types: SymbolTable {
override def parents: List[Type] = sym.info.parents map transform;
+ override def typeOfThis = transform(sym.typeOfThis);
+
override def prefix: Type = pre;
override def typeArgs: List[Type] = args;
@@ -604,7 +610,7 @@ abstract class Types: SymbolTable {
override def paramSectionCount: int = resultType.paramSectionCount + 1;
override def erasure = {
- val pts = List.transform(paramTypes)(.erasure);
+ val pts = paramTypes mapConserve (.erasure);
val res = resultType.erasure;
if ((pts eq paramTypes) && (res eq resultType)) this
else MethodType(pts, res)
@@ -767,7 +773,7 @@ abstract class Types: SymbolTable {
else ConstantType(base1, value)
case TypeRef(pre, sym, args) =>
val pre1 = this(pre);
- val args1 = List.transform(args)(this);
+ val args1 = args mapConserve this;
if ((pre1 eq pre) && (args1 eq args)) tp
else typeRef(pre1, sym, args1)
case TypeBounds(lo, hi) =>
@@ -776,7 +782,7 @@ abstract class Types: SymbolTable {
if ((lo1 eq lo) && (hi1 eq hi)) tp
else TypeBounds(lo1, hi1)
case RefinedType(parents, refinement) =>
- val parents1 = List.transform(parents)(this);
+ val parents1 = parents mapConserve this;
val refinement1 = mapOver(refinement);
if ((parents1 eq parents) && (refinement1 eq refinement)) tp
else {
@@ -791,7 +797,7 @@ abstract class Types: SymbolTable {
result
}
case MethodType(paramtypes, result) =>
- val paramtypes1 = List.transform(paramtypes)(this);
+ val paramtypes1 = paramtypes mapConserve this;
val result1 = this(result);
if ((paramtypes1 eq paramtypes) && (result1 eq result)) tp
else MethodType(paramtypes1, result1)
@@ -822,7 +828,7 @@ abstract class Types: SymbolTable {
/** Map this function over given list of symbols */
private def mapOver(syms: List[Symbol]): List[Symbol] = {
val infos = syms map (.info);
- val infos1 = List.transform(infos)(this);
+ val infos1 = infos mapConserve this;
if (infos1 eq infos) syms
else {
val syms1 = syms map (.cloneSymbol);
@@ -1414,7 +1420,7 @@ abstract class Types: SymbolTable {
* of thistype or prefixless typerefs/singletype occurrences in given list of types */
private def commonOwner(tps: List[Type]): Symbol = {
commonOwnerMap.init;
- List.transform(tps)(commonOwnerMap);
+ tps mapConserve commonOwnerMap;
commonOwnerMap.result
}
diff --git a/sources/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/sources/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
index 3531115583..2379d09400 100755
--- a/sources/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
+++ b/sources/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
@@ -18,7 +18,7 @@ abstract class ClassfileParser {
private var in: AbstractFileReader = _; // the class file
private var clazz: Symbol = _; // the class symbol containing dynamic members
- private var statics: Symbol = _; // the module class symbol containing static members
+ private var staticModule: Symbol = _; // the module symbol containing static members
private var instanceDefs: Scope = _; // the scope of all instance definitions
private var staticDefs: Scope = _; // the scope of all static definitions
private var pool: ConstantPool = _; // the classfile's constant pool
@@ -40,10 +40,10 @@ abstract class ClassfileParser {
this.in = new AbstractFileReader(file);
if (root.isModule) {
this.clazz = root.linkedClass;
- this.statics = root.moduleClass
+ this.staticModule = root
} else {
this.clazz = root;
- this.statics = root.linkedModule.moduleClass;
+ this.staticModule = root.linkedModule
}
this.isScala = false;
this.hasMeta = false;
@@ -59,6 +59,8 @@ abstract class ClassfileParser {
busy = false
}
+ private def statics: Symbol = staticModule.moduleClass;
+
private def parseHeader: unit = {
val magic = in.nextInt();
if (magic != JAVA_MAGIC)
@@ -239,7 +241,7 @@ abstract class ClassfileParser {
clazz.setInfo(classInfo);
statics.setInfo(staticInfo);
}
- statics.sourceModule.setInfo(statics.tpe);
+ staticModule.setInfo(statics.tpe);
in.bp = curbp;
val fieldCount = in.nextChar();
for (val i <- Iterator.range(0, fieldCount)) parseField();
diff --git a/sources/scala/tools/nsc/typechecker/Analyzer.scala b/sources/scala/tools/nsc/typechecker/Analyzer.scala
index 5457b01ec4..1e5e2c17c8 100644
--- a/sources/scala/tools/nsc/typechecker/Analyzer.scala
+++ b/sources/scala/tools/nsc/typechecker/Analyzer.scala
@@ -15,7 +15,8 @@ abstract class Analyzer
with Typers
with TypeCheckers
with Infer
- with Variances {
+ with Variances
+ with EtaExpansion {
val global: Global;
import global._;
diff --git a/sources/scala/tools/nsc/typechecker/Contexts.scala b/sources/scala/tools/nsc/typechecker/Contexts.scala
index 804b5ae29d..bbc965c468 100755
--- a/sources/scala/tools/nsc/typechecker/Contexts.scala
+++ b/sources/scala/tools/nsc/typechecker/Contexts.scala
@@ -51,7 +51,7 @@ class Contexts: Analyzer {
c.owner = owner;
c.scope = scope;
c.enclClass = if ((tree.isInstanceOf[Template] ||
- tree.isInstanceOf[IntersectionTypeTree]) &&
+ tree.isInstanceOf[CompoundTypeTree]) &&
tree != this.tree) c
else this.enclClass;
c.variance = this.variance;
diff --git a/sources/scala/tools/nsc/typechecker/Namers.scala b/sources/scala/tools/nsc/typechecker/Namers.scala
index 1215c5ddfb..1ed2f26947 100755
--- a/sources/scala/tools/nsc/typechecker/Namers.scala
+++ b/sources/scala/tools/nsc/typechecker/Namers.scala
@@ -40,11 +40,11 @@ trait Namers: Analyzer {
sym1
}
- private def enterInScope(pos: int, sym: Symbol): Symbol = {
+ def enterInScope(sym: Symbol): Symbol = {
if (!(sym.isMethod && sym.owner.isClass)) {
val prev = context.scope.lookupEntry(sym.name);
if (prev != null && prev.owner == context.scope && !prev.sym.isMethod)
- doubleDefError(pos, prev.sym);
+ doubleDefError(sym.pos, prev.sym);
}
context.scope enter sym;
sym
@@ -55,7 +55,7 @@ trait Namers: Analyzer {
if (p.isPackage && context.scope == p.owner.info.decls) {
p.pos = pos; p.moduleClass.pos = pos; p
} else {
- enterInScope(pos, context.owner.newPackage(pos, name))
+ enterInScope(context.owner.newPackage(pos, name))
}
}
@@ -64,7 +64,7 @@ trait Namers: Analyzer {
if (c.isType && context.scope == c.owner.info.decls) {
updatePosFlags(c, pos, mods)
} else {
- enterInScope(pos, context.owner.newClass(pos, name).setFlag(mods))
+ enterInScope(context.owner.newClass(pos, name).setFlag(mods))
}
}
@@ -76,7 +76,7 @@ trait Namers: Analyzer {
val newm = context.owner.newModule(pos, name);
newm.setFlag(mods);
newm.moduleClass.setFlag(mods);
- enterInScope(pos, newm)
+ enterInScope(newm)
}
}
@@ -85,7 +85,7 @@ trait Namers: Analyzer {
if (m.isModule && context.scope == m.owner.info.decls) {
updatePosFlags(m, pos, mods)
} else {
- enterInScope(pos, context.owner.newMethod(pos, name).setFlag(mods))
+ enterInScope(context.owner.newMethod(pos, name).setFlag(mods))
}
}
@@ -113,7 +113,7 @@ trait Namers: Analyzer {
val namer = new Namer(
context.make(tree, tree.symbol.moduleClass, tree.symbol.info.decls));
stats map namer.enterSym;
- tree.symbol
+ tree.symbol
case ClassDef(mods, name, tparams, _, _) =>
if ((mods & (CASE | ABSTRACT)) == CASE) { // enter case factory method.
tree.symbol = enterCaseFactorySymbol(
@@ -126,28 +126,48 @@ trait Namers: Analyzer {
.setInfo(typer.typeCompleter(tree));
tree.symbol.info.decls enter constr;
finishWith(tparams)
- case ModuleDef(mods, name, _, _) =>
+ case ModuleDef(mods, name, _) =>
tree.symbol = enterModuleSymbol(tree.pos, mods, name);
tree.symbol.moduleClass.setInfo(typer.typeCompleter(tree));
finish
case ValDef(mods, name, tp, rhs) =>
- tree.symbol = enterInScope(tree.pos, owner.newValue(tree.pos, name).setFlag(mods));
- finish
+ if (context.owner.isClass & (mods & PRIVATE) == 0) {
+ val accmods = ACCESSOR | (if ((mods & MUTABLE) != 0) mods & ~MUTABLE
+ else mods | STABLE);
+ val getter = owner.newMethod(tree.pos, name)
+ .setFlag(accmods).setInfo(typer.getterTypeCompleter(tree));
+ enterInScope(getter);
+ if ((mods & MUTABLE) != 0) {
+ val setter = owner.newMethod(tree.pos, name)
+ .setFlag(accmods).setInfo(typer.setterTypeCompleter(tree));
+ enterInScope(setter)
+ }
+ tree.symbol =
+ if ((mods & DEFERRED) == 0)
+ owner.newValue(tree.pos, name)
+ .setFlag(mods | PRIVATE | LOCAL).setInfo(typer.typeCompleter(tree))
+ else getter;
+ tree.symbol
+ } else {
+ tree.symbol =
+ enterInScope(owner.newValue(tree.pos, name).setFlag(mods));
+ finish
+ }
case DefDef(mods, nme.CONSTRUCTOR, tparams, vparams, tp, rhs) =>
if (!(owner.isClass && context.scope == owner.info.decls) ||
owner.isModuleClass || owner.isAnonymousClass || owner.isRefinementClass)
context.unit.error(tree.pos, "constructor definition not allowed here");
- tree.symbol = enterInScope(tree.pos, owner.newConstructor(tree.pos))
+ tree.symbol = enterInScope(owner.newConstructor(tree.pos))
.setFlag(mods | owner.rawflags & CONSTRFLAGS);
finishWith(tparams)
case DefDef(mods, name, tparams, _, _, _) =>
- tree.symbol = enterInScope(tree.pos, owner.newMethod(tree.pos, name)).setFlag(mods);
+ tree.symbol = enterInScope(owner.newMethod(tree.pos, name)).setFlag(mods);
finishWith(tparams)
case AbsTypeDef(mods, name, _, _) =>
- tree.symbol = enterInScope(tree.pos, owner.newAbstractType(tree.pos, name));
+ tree.symbol = enterInScope(owner.newAbstractType(tree.pos, name));
finish
case AliasTypeDef(mods, name, tparams, _) =>
- tree.symbol = enterInScope(tree.pos, owner.newAliasType(tree.pos, name));
+ tree.symbol = enterInScope(owner.newAliasType(tree.pos, name));
finishWith(tparams)
case Attributed(_, defn) =>
enterSym(defn)
@@ -157,7 +177,7 @@ trait Namers: Analyzer {
tree.symbol = NoSymbol.newImport(tree.pos);
finish
case _ =>
- NoSymbol
+ tree.symbol
}
}
}
diff --git a/sources/scala/tools/nsc/typechecker/TypeCheckers.scala b/sources/scala/tools/nsc/typechecker/TypeCheckers.scala
index 43bd18ea60..6a31477d2b 100755
--- a/sources/scala/tools/nsc/typechecker/TypeCheckers.scala
+++ b/sources/scala/tools/nsc/typechecker/TypeCheckers.scala
@@ -5,35 +5,65 @@
// $Id$
package scala.tools.nsc.typechecker;
+import collection.mutable.ListBuffer;
+import symtab.Flags._;
import scala.tools.util.Position;
/** Methods to create symbols and to enter them into scopes. */
trait TypeCheckers: Analyzer {
- import symtab.Flags._;
import global._;
+ import definitions._;
+ import posAssigner.atPos;
class TypeCheckPhase(prev: Phase) extends StdPhase(prev) {
def name = "typechecker";
val global: TypeCheckers.this.global.type = TypeCheckers.this.global;
def apply(unit: CompilationUnit): unit =
- unit.body = new TypeChecker(startContext.make(unit)).transformTrees(unit.body);
+ new TypeChecker(startContext.make(unit)).transformStats(unit.body, NoSymbol)
}
- class TypeChecker(context: Context) extends Transformer {
+ class TypeChecker(context: Context) {
import context.unit;
val infer = new Inferencer(context);
import infer._;
+ object namer extends Namer(context);
+
+ /** Mode constants
+ */
+ private val NOmode = 0x000;
+ private val EXPRmode = 0x001; // these 3 modes are mutually exclusive.
+ private val PATTERNmode = 0x002;
+ private val TYPEmode = 0x004;
+
+ private val INCONSTRmode = 0x008; // orthogonal to above. When set we are
+ // in the body of a constructor
+
+ private val FUNmode = 0x10; // orthogonal to above. When set
+ // we are looking for a method or constructor
+
+ private val POLYmode = 0x020; // orthogonal to above. When set
+ // expression types can be polymorphic.
+
+ private val QUALmode = 0x040; // orthogonal to above. When set
+ // expressions may be packages and
+ // Java statics modules.
+
+ private val stickyModes: int = EXPRmode | PATTERNmode | TYPEmode | INCONSTRmode;
+
+ /** Report a type error.
+ * @param pos The position where to report the error
+ * @param ex The exception that caused the error */
def reportTypeError(pos: int, ex: TypeError): unit = {
if (settings.debug.value) ex.printStackTrace();
ex match {
case CyclicReference(sym, info: TypeCompleter) =>
info.tree match {
- case ValDef(_, _, EmptyTypeTree(), _) =>
+ case ValDef(_, _, tpt, _) if (tpt.tpe == null) =>
error(pos, "recursive " + sym + " needs type")
- case DefDef(_, _, _, _, EmptyTypeTree(), _) =>
+ case DefDef(_, _, _, _, tpt, _) if (tpt.tpe == null) =>
error(pos, "recursive " + sym + " needs result type")
case _ =>
error(pos, ex.getMessage())
@@ -43,61 +73,495 @@ trait TypeCheckers: Analyzer {
}
}
- /** Mode constants
- */
- val NOmode = 0x000;
- val EXPRmode = 0x001; // these 3 modes are mutually exclusive.
- val PATTERNmode = 0x002;
- val TYPEmode = 0x004;
+ /** Check that tree is a stable expression.
+ */
+ def checkStable(tree: Tree): Tree =
+ if (treeInfo.isPureExpr(tree) || tree.tpe.isError) tree;
+ else errorTree(tree, "stable identifier required, but " + tree + " found.");
+
+ /** Check that type of given tree does not contain local or private components
+ */
+ private object checkNoEscape extends TypeMap {
+ private var owner: Symbol = _;
+ private var badSymbol: Symbol = _;
+ def apply[T <: Tree](owner: Symbol, tree: T): T = {
+ this.owner = owner;
+ badSymbol = NoSymbol;
+ apply(tree.tpe);
+ if (badSymbol == NoSymbol) tree
+ else {
+ error(tree.pos,
+ (if (badSymbol.hasFlag(PRIVATE)) "private " else "") + badSymbol +
+ " escapes its defining scope as part of type " + tree.tpe);
+ setError(tree)
+ }
+ }
+ override def apply(t: Type): Type = {
+ def checkNoEscape(sym: Symbol): unit = {
+ val e = context.scope.lookupEntry(sym.name);
+ if (e.sym == sym && e.owner == context.scope && !e.sym.isTypeParameter) {
+ badSymbol = e.sym
+ } else if (sym.hasFlag(PRIVATE)) {
+ var o = owner;
+ while (o != NoSymbol && o != sym.owner && !o.isLocal && !o.hasFlag(PRIVATE))
+ o = o.owner;
+ if (o == sym.owner) badSymbol = sym
+ }
+ }
+ if (badSymbol == NoSymbol)
+ t match {
+ case TypeRef(NoPrefix, sym, args) => checkNoEscape(sym)
+ case SingleType(NoPrefix, sym) => checkNoEscape(sym)
+ case _ =>
+ }
+ mapOver(t)
+ }
+ }
+
+ def reenterValueParams(vparamss: List[List[ValDef]]): unit =
+ for (val vparams <- vparamss; val vparam <- vparams) context.scope enter vparam.symbol;
- val FUNmode = 0x10; // orthogonal to above. When set
- // we are looking for a method or constructor
+ def reenterTypeParams(tparams: List[AbsTypeDef]): unit =
+ for (val tparam <- tparams) context.scope enter tparam.symbol;
- val POLYmode = 0x020; // orthogonal to above. When set
- // expression types can be polymorphic.
+ def attrInfo(attr: Tree): AttrInfo = attr match {
+ case Apply(Select(New(tpt), nme.CONSTRUCTOR), args) =>
+ Pair(tpt.tpe, args map {
+ case Literal(value) =>
+ value
+ case arg =>
+ error(arg.pos, "attribute argument needs to be a constant; found: " + arg);
+ })
+ }
+
+ private def literalType(value: Any): Type =
+ if (value.isInstanceOf[unit]) UnitClass.tpe
+ else if (value.isInstanceOf[boolean]) BooleanClass.tpe
+ else if (value.isInstanceOf[char]) CharClass.tpe
+ else if (value.isInstanceOf[int]) IntClass.tpe
+ else if (value.isInstanceOf[long]) LongClass.tpe
+ else if (value.isInstanceOf[float]) FloatClass.tpe
+ else if (value.isInstanceOf[double]) DoubleClass.tpe
+ else if (value.isInstanceOf[String]) StringClass.tpe
+ else if (value == null) AllRefClass.tpe
+ else throw new FatalError("unexpected literal value: " + value);
+
+ /** Perform the following adaptations of expression, pattern or type `tree' wrt to
+ * given mode `mode' and given prototype `pt':
+ * (1) Resolve overloading, unless mode contains FUNmode
+ * (2) Apply parameterless functions
+ * (3) Apply polymorphic types to fresh instances of their type parameters and
+ * store these instances in context.undetparams.
+ * (4) When in mode EXPRmode but not FUNmode, convert unapplied methods to functions
+ * However, if function is `match' or a constructor, issue an error.
+ * (5) Convert a class type that serves as a constructor in a pattern as follows:
+ * (5.1) If this type refers to a case class, set tree's type to the unique
+ * instance of its primary constructor that is a subtype of the expected type.
+ * (5.2) Otherwise, if this type is a subtype of scala.Seq[A], set trees' type
+ * to a method type from a repeated parameter sequence type A* to the expected type.
+ * (6) Convert all other types to TypeTree nodes.
+ * (7) When in TYPEmode nut not FUNmode, check that types are fully parameterized
+ * (8) When in both EXPRmode and FUNmode, add apply method calls to values of object type.
+ * (9) If there are undetermined type variables and not POLYmode, infer expression instance
+ * Then, if tree's type is not a subtype of expected type, try the following adaptations:
+ * (10) If the expected type is byte, short or char, and the expression
+ * is an integer fitting in the range of that type, convert it to that type.
+ * (11) Widen numeric literals to their expected type, if necessary
+ * (12) When in mode EXPRmode, convert E to { E; () } if expected type is Scala.unit.
+ * (13) When in mode EXPRmode, apply a view
+ * If all this fails, error
+ */
+ private def adapt(tree: Tree, mode: int, pt: Type): Tree = tree.tpe match {
+ case OverloadedType(pre, alts) if ((mode & FUNmode) == 0) => // (1)
+ inferExprAlternative(tree, pt);
+ adapt(tree, mode, pt)
+ case PolyType(List(), restpe) => // (2)
+ transform(constfold(tree.setType(restpe)), mode, pt);
+ case PolyType(tparams, restpe) => // (3)
+ val tparams1 = tparams map (.cloneSymbol);
+ val tree1 = if (tree.isType) tree
+ else TypeApply(tree, tparams1 map (tparam =>
+ TypeTree() setPos tparam.pos setType tparam.tpe)
+ context.undetparams = context.undetparams ::: tparams1;
+ adapt(tree1 setType restpe.substSym(tparams, tparams1), mode, pt)
+ case MethodType(_, _) if ((mode & (EXPRmode | FUNmode)) == EXPRmode &&
+ isCompatible(tree.tpe, pt)) => // (4)
+ val meth = treeInfo.methSymbol(tree);
+ if (meth.isConstructor) errorTree(tree, "missing arguments for " + meth)
+ else transform(etaExpand(tree, tree.tpe), mode, pt)
+ case _ =>
+ if (tree.isType) {
+ val clazz = tree.tpe.symbol;
+ if ((mode & PATTERNmode) != 0) { // (5)
+ if (clazz.hasFlag(CASE)) { // (5.1)
+ val tparams = context.undetparams;
+ context.undetparams = List();
+ inferConstructorInstance(
+ TypeTree() setPos tree.pos
+ setType1 tree.tpe.prefix.memberType(clazz.primaryConstructor),
+ tparams, pt);
+ tree
+ } else if (clazz.isSubClass(SeqClass)) { // (5.2)
+ pt.baseType(clazz).baseType(SeqClass) match {
+ case TypeRef(pre, seqClass, args) =>
+ tree.setType(MethodType(List(typeRef(pre, RepeatedParamClass, args)), pt))
+ case NoType =>
+ errorTree(tree, "expected pattern type " + pt +
+ " does not conform to sequence " + clazz)
+ }
+ } else errorTree(tree,
+ clazz.toString() + " is neither a case class nor a sequence class")
+ } else if ((mode & FUNmode) == 0 && !context.undetparams.isEmpty) { // (7)
+ context.undetparams = List();
+ errorTree(tree, "" + clazz + " takes type parameters");
+ } else tree match { // (6)
+ case TypeTree() => tree
+ case _ => TypeTree() setPos tree.pos setType tree.tpe
+ }
+ } else if ((mode & (EXPRmode | FUNmode)) == (EXPRmode | FUNmode) &&
+ tree.tpe.member(nme.apply).filter(
+ m => m.tpe.paramSectionCount > 0) != NoSymbol) { // (8)
+ transform(Select(tree, nme.apply), mode, pt)
+ } else if (!context.undetparams.isEmpty & (mode & POLYmode) == 0) { // (9)
+ val tparams = context.undetparams;
+ context.undetparams = List();
+ inferExprInstance(tree, tparams, pt);
+ tree
+ } else if (tree.tpe <:< pt) {
+ tree
+ } else {
+ def adaptError: Tree = {
+ typeError(tree.pos, tree.tpe, pt);
+ explainTypes(tree.tpe, pt);
+ setError(tree)
+ }
+ val tree1 = constfold(tree, pt); // (10) (11)
+ if (tree1 != tree)) transform(tree1, mode, pt)
+ else if ((mode & EXPRmode) != 0)
+ if (pt.symbol == UnitClass) // (12)
+ transform(Block(List(tree), Literal(())), mode, pt)
+ else { // (13)
+ val vmeth = bestView(tree.tpe, pt);
+ if (vmeth != NoSymbol)
+ transform(Apply(Ident(vmeth.name), List(tree)), mode, pt)
+ else adaptError
+ }
+ else adaptError
+ }
+ }
- val QUALmode = 0x040; // orthogonal to above. When set
- // expressions may be packages and
- // Java statics modules.
+ def completeSuperType(supertpt: Tree, tparams: List[Symbol], vparamss: List[List[ValDef]], superargs: List[Tree]): Type = {
+ reenterValueParams(vparamss);
+ context.undetparams = tparams;
+ transformExpr(atPos(supertpt.pos)(Apply(Select(New(supertpt), nme.CONSTRUCTOR), superargs)))
+ .tpe
+ }
- val SUPERmode = 0x080; // Goes with CONSTRmode. When set
- // we are checking a superclass
- // constructor invocation.
+ def parentTypes(templ: Template): List[Tree] =
+ if (templ.parents.isEmpty) List()
+ else {
+ var supertpt = transform(templ.parents.head, TYPEmode | FUNmode, WildcardType);
+ val tparams = context.undetparams;
+ context.undetparams = List();
+ if (!tparams.isEmpty) {
+ val constr @ DefDef(_, _, _, vparamss, _, Apply(_, superargs)) =
+ treeInfo.firstConstructor(templ.body);
+ supertpt = TypeTree()
+ setPos supertpt.pos
+ setType new TypeChecker(context.makeNewScope(constr, constr.symbol))
+ .completeSuperType(supertpt, tparams, vparamss, superargs map (.duplicate));
+ }
+ checkNoEscape(context.owner, supertpt) ::
+ (templ.parents.tail mapConserve (tpt => transformType(tpt, context.owner)))
+ }
- val baseModes: int = EXPRmode | PATTERNmode;
+ /** Check that
+ * - all parents are class types,
+ * - first parent cluss is not a trait; following classes are traits,
+ * - fnal classes are not inherited,
+ * - sealed classes are only inherited by classes which are
+ * nested within definition of base class, or that occur within same
+ * statement sequence,
+ * - self-type of current class is a subtype of self-type of each parent class.
+ * - no two parents define same symbol.
+ */
+ def validateParentClasses(parents: List[Tree], selfType: Type): unit = {
+ var c = context;
+ do { c = c.outer } while (c.tree.owner == context.owner);
+ val defscope = c.scope;
+
+ def validateParentClass(parent: Tree, isFirst: boolean): unit = {
+ val psym = parent.tpe.symbol;
+ if (!psym.isClass && !parent.tpe.isError) error(parent.pos, "class type expected");
+ else if (isFirst == psym.hasFlag(TRAIT))
+ error(parent.pos, "" + psym +
+ (if (isFirst) " is a trait; cannot be used as superclass"
+ else " is not a trait; cannot be used as mixin"))
+ else if (psym.hasFlag(FINAL))
+ error(parent.pos, "illegal inheritance from final class");
+ else if (psym.isSealed) {
+ // are we in same scope as base type definition?
+ val e = defscope.lookupEntry(psym.name);
+ if (!(e.sym == psym && e.owner == defscope)) {
+ // we are not within same statement sequence
+ var c = context;
+ while (c != NoContext && c.owner != psym) c = c.outer.enclClass;
+ if (c == NoContext) error(parent.pos, "illegal inheritance from sealed class")
+ }
+ }
+ if (!(selfType <:< parent.tpe.typeOfThis)) {
+ error(parent.pos, "illegal inheritance;\n self-type " +
+ selfType + " does not conform to " + parent +
+ "'s selftype " + parent.tpe.typeOfThis)
+ }
+ if (parents exists (p => p != parent && p.tpe.symbol == psym && !psym.isError))
+ error(parent.pos, "" + psym + " is inherited twice")
+ }
- 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
+ if (!parents.isEmpty) {
+ validateParentClass(parents.head, true);
+ for (val p <- parents.tail) validateParentClass(p, false);
+ }
+ }
- def reenterValueParams(tree: Tree): unit = tree match {
- case DefDef(_, _, _, vparamss, _, _) =>
- for (val vparams <- vparamss; val vparam <- vparams) context.scope enter vparam.symbol
+ def transformClassDef(cdef: ClassDef): Tree = {
+ val clazz = cdef.symbol;
+ reenterTypeParams(cdef.tparams);
+ val tparams1 = cdef.tparams mapConserve transformAbsTypeDef;
+ val tpt1 = transformType(cdef.tpt, clazz.thisSym);
+ val impl1 = new TypeChecker(context.make(cdef.impl, clazz, clazz.info.decls))
+ .transformTemplate(cdef.impl);
+ copy.ClassDef(cdef, cdef.mods, cdef.name, tparams1, tpt1, impl1) setType NoType
}
- def checkStable(tree: Tree): Tree = tree;
- def checkNoEscape(pos: int, tpe: Type): Type = tpe;
+ def transformModuleDef(mdef: ModuleDef): Tree = {
+ val clazz = mdef.symbol.moduleClass;
+ val impl1 = new TypeChecker(context.make(mdef.impl, clazz, clazz.info.decls))
+ .transformTemplate(mdef.impl);
+ copy.ModuleDef(mdef, mdef.mods, mdef.name, impl1) setType NoType
+ }
- def transformConstr(tree: Tree): Tree = tree;
- def transformExpr(tree: Tree): Tree = tree;
- def transformType(tree: Tree): Tree = tree;
- def transformSuperType(tree: Tree): Tree = tree;
+ def transformTemplate(templ: Template): Template = {
+ templ setSymbol context.owner.newLocalDummy(templ.pos);
+ val parents1 = parentTypes(templ);
+ validateParentClasses(parents1, context.owner.thisType);
+ val body1 = transformStats(templ.body, templ.symbol);
+ copy.Template(templ, parents1, body1) setType context.owner.tpe
+ }
- def transform(tree: Tree, mode: int, pt: Type): Tree = {
+ def transformValDef(vdef: ValDef): ValDef = {
+ val sym = vdef.symbol;
+ val tpt1 = transformType(vdef.tpt, sym);
+ val rhs1 =
+ if (vdef.rhs.isEmpty) vdef.rhs
+ else new TypeChecker(context.make(vdef, sym)).transform(vdef.rhs, EXPRmode, tpt1.tpe);
+ copy.ValDef(vdef, vdef.mods, vdef.name, tpt1, rhs1) setType NoType
+ }
- /** 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
+ def transformDefDef(ddef: DefDef): DefDef = {
+ val meth = ddef.symbol;
+ reenterTypeParams(ddef.tparams);
+ reenterValueParams(ddef.vparamss);
+ val tparams1 = ddef.tparams mapConserve transformAbsTypeDef;
+ val vparamss1 = ddef.vparamss mapConserve (.mapConserve(transformValDef));
+ val tpt1 = transformType(ddef.tpt, meth);
+ val rhs1 =
+ if (ddef.name == nme.CONSTRUCTOR) {
+ context.enclClass.owner.setFlag(INCONSTRUCTOR);
+ val result = transform(ddef.rhs, EXPRmode | INCONSTRmode, UnitClass.tpe);
+ context.enclClass.owner.resetFlag(INCONSTRUCTOR);
+ result
+ } else {
+ transform(ddef.rhs, EXPRmode, tpt1.tpe);
+ }
+ copy.DefDef(ddef, ddef.mods, ddef.name, tparams1, vparamss1, tpt1, rhs1) setType NoType
+ }
+
+ def transformAbsTypeDef(tdef: AbsTypeDef): AbsTypeDef = {
+ val lo1 = transformType(tdef.lo, tdef.symbol);
+ val hi1 = transformType(tdef.hi, tdef.symbol);
+ copy.AbsTypeDef(tdef, tdef.mods, tdef.name, lo1, hi1) setType NoType
+ }
+
+ def transformAliasTypeDef(tdef: AliasTypeDef): AliasTypeDef = {
+ reenterTypeParams(tdef.tparams);
+ val tparams1 = tdef.tparams mapConserve transformAbsTypeDef;
+ val rhs1 = transformType(tdef.rhs, tdef.symbol);
+ copy.AliasTypeDef(tdef, tdef.mods, tdef.name, tparams1, rhs1) setType NoType
+ }
+
+ def transformLabelDef(ldef: LabelDef): LabelDef = {
+ val lsym = namer.enterInScope(
+ context.owner.newLabel(ldef.pos, ldef.name) setInfo MethodType(List(), UnitClass.tpe));
+ val rhs1 = transform(ldef.rhs, EXPRmode, UnitClass.tpe);
+ copy.LabelDef(ldef, ldef.name, ldef.params, rhs1) setType UnitClass.tpe
+ }
+
+ def transformBlock(block: Block, mode: int, pt: Type): Block = {
+ namer.enterSyms(block.stats);
+ val stats1 =
+ if ((mode & INCONSTRmode) != 0) {
+ val constrCall = transform(block.stats.head, mode, WildcardType);
+ context.enclClass.owner.resetFlag(INCONSTRUCTOR);
+ constrCall :: block.stats.tail mapConserve transformExpr
+ } else {
+ block.stats mapConserve transformExpr
+ }
+ val expr1 = transform(block.expr, mode & ~(FUNmode | QUALmode), pt);
+ checkNoEscape(NoSymbol, copy.Block(block, stats1, expr1) setType expr1.tpe.deconst)
+ }
+
+ def transformCase(cdef: CaseDef, pattpe: Type, pt: Type): CaseDef = {
+ val pat1: Tree = transform(cdef.pat, PATTERNmode, pattpe);
+ val guard1: Tree = if (cdef.guard == EmptyTree) EmptyTree
+ else transform(cdef.guard, EXPRmode, BooleanClass.tpe);
+ val body1: Tree = transform(cdef.body, EXPRmode, pt);
+ copy.CaseDef(cdef, pat1, guard1, body1) setType body1.tpe
+ }
+
+ def transformFunction(fun: Function, mode: int, pt: Type): Function = {
+ val Triple(clazz, argpts, respt) = pt match {
+ case TypeRef(_, sym, argtps)
+ if (sym == FunctionClass(fun.vparams.length) ||
+ sym == PartialFunctionClass && fun.body.isInstanceOf[Match]) =>
+ Triple(sym, argtps.init, argtps.last)
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
+ Triple(FunctionClass(fun.vparams.length), fun.vparams map (x => NoType), WildcardType)
+ }
+ val vparamSyms = List.map2(fun.vparams, argpts) { (vparam, argpt) =>
+ vparam match {
+ case ValDef(_, _, tpt, _) =>
+ if (tpt.isEmpty)
+ tpt.tpe =
+ if (argpt == NoType) {
+ error(vparam.pos, "missing parameter type");
+ ErrorType
+ } else argpt
+ }
+ namer.enterSym(vparam)
+ }
+ val vparams1 = fun.vparams mapConserve transformValDef;
+ val body1 = transform(fun.body, EXPRmode, respt);
+ copy.Function(fun, vparams1, body1)
+ setType typeRef(clazz.info.prefix, clazz, (vparamSyms map (.tpe)) ::: List(body1.tpe))
+ }
+
+ def transformRefinement(stats: List[Tree]): List[Tree] = {
+ for (val stat <- stats) namer.enterSym(stat) setFlag OVERRIDE;
+ transformStats(stats, NoSymbol);
+ }
+
+ def transformStats(stats: List[Tree], exprOwner: Symbol): List[Tree] =
+ stats mapConserve { stat =>
+ if (context.owner.isRefinementClass && !treeInfo.isDeclaration(stat))
+ errorTree(stat, "only declarations allowed here");
+ (if (stat.isDef) TypeChecker.this
+ else new TypeChecker(context.make(stat, exprOwner))).transformExpr(stat)
+ }
+
+ private def transform1(tree: Tree, mode: int, pt: Type): Tree = {
+
+ def transformCases(cases: List[CaseDef], pattp: Type): List[CaseDef] = {
+ val tc1 = new TypeChecker(context.makeNewScope(tree, context.owner));
+ cases mapConserve (cdef => tc1.transformCase(cdef, pattp, pt))
+ }
+
+ def transformApply(fn: Tree, args: List[Tree]): Tree = {
+ // if function is overloaded, filter all alternatives that match
+ // number of arguments and expected result type.
+ if (fn.hasSymbol && fn.symbol.hasFlag(OVERLOADED)) {
+ val argtypes = args map (arg => AllClass.tpe);
+ val pre = fn.symbol.info.prefix;
+ val sym = fn.symbol filter (alt =>
+ isApplicable(context.undetparams, pre.memberType(alt), argtypes, pt));
+ fn.symbol = sym;
+ fn.tpe = pre.memberType(sym)
+ }
+ fn.tpe match {
+ case OverloadedType(pre, alts) =>
+ val args1 = args mapConserve (arg =>
+ transform(arg, mode & stickyModes, WildcardType));
+ inferMethodAlternative(fn, context.undetparams, args1 map (.tpe.deconst), pt);
+ transformApply(fn, args1);
+ case MethodType(formals0, restpe) =>
+ val formals = formalTypes(formals0, args.length);
+ if (formals.length != args.length) {
+ errorTree(tree, "wrong number of arguments for " + treeSymTypeMsg(fn))
+ } else {
+ val tparams = context.undetparams;
+ context.undetparams = List();
+ if (!tparams.isEmpty) { // note: this case cannot arise for patterns
+ val lenientTargs = protoTypeArgs(tparams, formals, restpe, pt);
+ val strictTargs = List.map2(lenientTargs, tparams)((targ, tparam) =>
+ if (targ == WildcardType) tparam.tpe else targ);
+ def transformArg(tree: Tree, formal: Type): Tree = {
+ val lenientPt = formal.subst(tparams, lenientTargs);
+ val tree1 = transform(tree, mode & stickyModes | POLYmode, lenientPt);
+ val argtparams = context.undetparams;
+ context.undetparams = List();
+ if (!argtparams.isEmpty) {
+ val strictPt = formal.subst(tparams, strictTargs);
+ inferArgumentInstance(tree1, argtparams, strictPt, lenientPt);
+ }
+ tree1
+ }
+ val args1 = List.map2(args, formals)(transformArg);
+ if (args1 exists (.tpe.isError)) setError(tree)
+ else {
+ val undetparams = inferMethodInstance(fn, tparams, args1, pt);
+ val result = transformApply(fn, args1);
+ context.undetparams = undetparams;
+ result
+ }
+ } else {
+ val args1 = List.map2(args, formals) ((arg, formal) =>
+ transform(arg, mode & stickyModes, formal));
+ val tree1 = copy.Apply(tree, fn, args1).setType(restpe);
+ val tree2 = constfold(tree1);
+ if (tree1 == tree2) tree2 else transform(tree2, mode, pt)
+ }
+ }
+ case ErrorType =>
+ setError(tree)
+ }
+ }
+
+ /** The qualifying class of a this or super with prefix `qual' */
+ def qualifyingClass(qual: Name): Symbol = {
+ if (qual == nme.EMPTY.toTypeName) {
+ val clazz = context.enclClass.owner;
+ if (!clazz.isPackageClass) clazz
+ else {
+ error(tree.pos, "" + tree + " can be used only in a class, object, or template");
+ NoSymbol
+ }
+ } else {
+ var c = context;
+ while (c != NoContext && !(c.owner.isClass && c.owner.name == qual))
+ c = c.outer.enclClass;
+ if (c != NoContext) c.owner
+ else {
+ error(tree.pos, "" + qual + " is not an enclosing class");
+ NoSymbol
+ }
+ }
+ }
+
+ /** Attribute a selection where `tree' is `qual.name'.
+ * `qual' is already attributed.
+ */
+ def transformSelect(qual: Tree, name: Name): Tree = {
+ val sym = qual.tpe.member(name);
+ if (sym == NoSymbol && qual.isTerm) {
+ val vmeth = bestView(tree.tpe, name);
+ if (vmeth != NoSymbol)
+ return transform(Select(Apply(Ident(vmeth.name), List(qual)), name), mode, pt)
+ }
+ val pre = qual match {
+ case Super(_, _) => context.enclClass.owner.thisType
+ case _ => qual.tpe
+ }
+ stabilize(checkAccessible(tree, sym, pre, qual), pre);
}
/** Attribute an identifier consisting of a simple name or an outer reference.
@@ -201,253 +665,281 @@ trait TypeCheckers: Analyzer {
stabilize(checkAccessible(tree, sym, pre, qual), pre);
}
- 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))
+ /** Post-process an identifier or selection node, performing the following:
+ * (1) Turn trees of constant type into literals
+ * (2) Check that non-function pattern expressions are stable
+ * (3) Check that packages and static modules are not used as values
+ * (4) 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) => // (1)
+ Literal(value) setPos tree.pos setType tree.tpe
+ case PolyType(List(), restp @ ConstantType(base, value)) => // (1)
+ Literal(value) setPos tree.pos setType restp
+ case _ =>
+ if (tree.symbol.hasFlag(OVERLOADED) && (mode & FUNmode) == 0)
+ inferExprAlternative(tree, pt);
+ if ((mode & (PATTERNmode | FUNmode)) == PATTERNmode && tree.isTerm) // (2)
+ checkStable(tree)
+ else if ((mode & (EXPRmode | QUALmode)) == EXPRmode && !tree.symbol.isValue) // (3)
+ errorTree(tree, tree.symbol.toString() + " is not a value");
+ else if (tree.symbol.isStable && pre.isStable &&
+ (pt.isStable || (mode & QUALmode) != 0 || tree.symbol.isModule)) // (4)
+ tree.setType(singleType(pre, tree.symbol))
+ else
+ tree
}
- /** Attribute a selection where `tree' is `qual.name'.
- * `qual' is already attributed.
- */
- def transformSelect(tree: Tree, qual0: Tree, name: Name): Tree = {
- val qual = qual0.tpe match {
- case PolyType(tparams, restpe) =>
- assert(context.undetparams.isEmpty);
- applyPoly(qual, tparams, restpe);
- case _ =>
- qual0
- }
- val sym = qual.tpe.member(name);
- // if (sym == NoSymbol) try to insert view.
- 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);
+ // begin transform1
+ val sym: Symbol = tree.symbol;
+ if (sym != null) sym.initialize;
+ if (settings.debug.value && tree.isDef) global.log("transforming definition of " + sym);
+ tree match {
+ case PackageDef(name, stats) =>
+ val stats1 = new TypeChecker(context.make(tree, sym.moduleClass, sym.info.decls))
+ .transformStats(stats, NoSymbol);
+ copy.PackageDef(tree, name, stats1) setType NoType
+
+ case cdef @ ClassDef(_, _, _, _, _) =>
+ new TypeChecker(context.makeNewScope(tree, sym)).transformClassDef(cdef)
+
+ case mdef @ ModuleDef(_, _, _) =>
+ transformModuleDef(mdef)
+
+ case vdef @ ValDef(_, _, _, _) =>
+ transformValDef(vdef)
+
+ case ddef @ DefDef(_, _, _, _, _, _) =>
+ new TypeChecker(context.makeNewScope(tree, sym)).transformDefDef(ddef)
+
+ case tdef @ AbsTypeDef(_, _, _, _) =>
+ transformAbsTypeDef(tdef)
+
+ case tdef @ AliasTypeDef(_, _, _, _) =>
+ new TypeChecker(context.makeNewScope(tree, sym)).transformAliasTypeDef(tdef)
+
+ case ldef @ LabelDef(_, List(), _) =>
+ new TypeChecker(context.makeNewScope(tree, context.owner)).transformLabelDef(ldef)
+
+ case Import(_, _) =>
+ EmptyTree
+
+ case Attributed(attr, defn) =>
+ val attr1 = transform(attr, EXPRmode, AttributeClass.tpe);
+ val defn1 = transform(defn, mode, pt);
+ val existing = attributes.get(defn1.symbol) match {
+ case None => List()
+ case Some(attrs) => attrs
+ }
+ attributes(defn1.symbol) = attrInfo(attr1) :: existing;
+ defn1
+
+ case DocDef(comment, defn) =>
+ transform(defn, mode, pt);
+
+ case block @ Block(_, _) =>
+ new TypeChecker(context.makeNewScope(tree, context.owner))
+ .transformBlock(block, mode, pt)
+
+ case Sequence(elems) =>
+ copy.Sequence(tree, elems mapConserve (elem => transform(elem, mode, pt))) setType pt
+
+ case Alternative(alts) =>
+ copy.Alternative(tree, alts mapConserve (alt => transform(alt, mode, pt))) setType pt
+
+ case Bind(name, body) =>
+ val body1 = transform(body, mode, pt);
+ val vble = context.owner.newValue(tree.pos, name).setInfo(
+ if (treeInfo.isSequenceValued(body)) seqType(pt) else pt);
+ namer.enterInScope(vble);
+ copy.Bind(tree, name, body1) setSymbol vble setType pt
+
+ case fun @ Function(_, _) =>
+ new TypeChecker(context.makeNewScope(tree, context.owner))
+ .transformFunction(fun, mode, pt)
+
+ case Assign(lhs, rhs) =>
+ def isGetter(sym: Symbol) = sym.info match {
+ case PolyType(List(), _) => !sym.isStable
+ case _ => false
+ }
+ val lhs1 = transformExpr(lhs);
+ val varsym = lhs1.symbol;
+ if (varsym != null && isGetter(varsym)) {
+ lhs1 match {
+ case Select(qual, name) =>
+ transform(Apply(Select(qual, name.toString() + "_="), List(rhs)), mode, pt)
+ }
+ } else if (varsym != null && varsym.isVariable) {
+ val rhs1 = transform(rhs, EXPRmode, lhs.tpe);
+ copy.Assign(tree, lhs1, rhs1) setType UnitClass.tpe;
+ } else {
+ if (!lhs.tpe.isError) error(tree.pos, "assignment to non-variable ");
+ setError(tree)
+ }
+
+ case If(cond, thenp, elsep) =>
+ val cond1 = transform(cond, EXPRmode, BooleanClass.tpe);
+ if (elsep.isEmpty) {
+ val thenp1 = transform(thenp, EXPRmode, UnitClass.tpe);
+ copy.If(tree, cond1, thenp1, elsep) setType UnitClass.tpe
+ } else {
+ val thenp1 = transform(thenp, EXPRmode, pt);
+ val elsep1 = transform(thenp, EXPRmode, pt);
+ copy.If(tree, cond1, thenp1, elsep1) setType lub(List(thenp1.tpe, elsep1.tpe));
+ }
+
+ case Match(selector, cases) =>
+ val selector1 = transformExpr(selector);
+ val cases1 = transformCases(cases, selector1.tpe);
+ copy.Match(tree, selector1, cases1) setType lub(cases1 map (.tpe))
+
+ case Return(expr) =>
+ if ((context.owner.rawflags & INITIALIZED) == 0) {
+ errorTree(tree, "method with return needs result type")
+ } else {
+ val enclFun = context.owner.enclMethod;
+ if (!enclFun.isMethod || enclFun.isConstructor) {
+ errorTree(tree, "return outside method definition")
+ } else {
+ val expr1: Tree = transform(expr, EXPRmode, enclFun.tpe.resultType);
+ copy.Return(tree, expr1) setSymbol enclFun setType AllClass.tpe;
+ }
+ }
+
+ case Try(block, catches, finalizer) =>
+ val block1 = transform(block, EXPRmode, pt);
+ val catches1 = transformCases(catches, ThrowableClass.tpe);
+ val finalizer1 = if (finalizer.isEmpty) finalizer
+ else transform(finalizer, EXPRmode, UnitClass.tpe);
+ copy.Try(tree, block1, catches1, finalizer1)
+ setType lub(block1.tpe :: (catches1 map (.tpe)))
+
+ case Throw(expr) =>
+ val expr1 = transform(expr, EXPRmode, ThrowableClass.tpe);
+ copy.Throw(tree, expr1) setType AllClass.tpe
+
+ case New(tpt: Tree) =>
+ val tpt1 = transform(tpt, TYPEmode, WildcardType);
+ copy.New(tree, tpt1).setType(tpt.tpe)
+
+ case Typed(expr, tpt @ Ident(nme.WILDCARD_STAR)) =>
+ val expr1 = transform(expr, mode & stickyModes, seqType(pt));
+ expr1.tpe.baseType(SeqClass) match {
+ case TypeRef(_, _, List(elemtp)) =>
+ copy.Typed(tree, expr1, tpt setType elemtp) setType elemtp
+ case _ =>
+ setError(tree)
+ }
+ case Typed(expr, tpt) =>
+ val tpt1 = transform(tpt, TYPEmode, WildcardType);
+ val expr1 = transform(expr, mode & stickyModes, tpt1.tpe);
+ copy.Typed(tree, expr1, tpt1)
+
+ case TypeApply(fun, args) =>
+ val fun1 = transform(fun, mode & stickyModes | FUNmode, WildcardType);
+ inferPolyAlternative(fun1, args.length);
+ val args1 = args mapConserve (arg => transform(arg, TYPEmode, WildcardType));
+ val targs = args1 map (.tpe);
+ if (fun1.tpe.isError || (targs exists (.isError)))
+ setError(tree)
+ else fun1.tpe match {
+ case PolyType(tparams, restpe) =>
+ checkBounds(tree.pos, tparams, targs, "");
+ copy.TypeApply(tree, fun1, args1) setType restpe.subst(tparams, targs)
+ }
+
+ case Apply(fn, args) =>
+ val fnpt = if ((mode & PATTERNmode) != 0) pt else WildcardType;
+ transformApply(transform(fn, mode | FUNmode | POLYmode, fnpt), args)
+
+ case Super(qual, mix) =>
+ val clazz = qualifyingClass(qual);
+ if (clazz == NoSymbol)
+ setError(tree)
+ else
+ tree setSymbol clazz
+ setType (
+ if (mix == nme.EMPTY.toTypeName) {
+ intersectionType(clazz.info.parents)
+ } else {
+ val ps = clazz.info.parents dropWhile (p => p.symbol.name != mix);
+ if (ps.isEmpty) {
+ error(tree.pos, "" + mix + " does not name a mixin base class of " + clazz);
+ ErrorType
+ } else ps.head
+ })
+
+ case This(qual) =>
+ val clazz = qualifyingClass(qual);
+ if (clazz == NoSymbol) setError(tree)
+ else {
+ tree.setSymbol(clazz);
+ tree.setType(
+ if (pt.isStable || (mode & QUALmode) != 0) clazz.thisType
+ else clazz.typeOfThis)
+ }
+
+ case Select(qual, name) =>
+ val qual1 = transform(qual, EXPRmode | QUALmode | POLYmode, WildcardType);
+ if (name.isTypeName) checkStable(qual1);
+ transformSelect(qual1, name);
+
+ case Ident(name) =>
+ transformIdent(name)
+
+ case Literal(value) =>
+ tree.setType(literalType(value))
+
+ case SingletonTypeTree(ref) =>
+ val ref1 = checkStable(transform(ref, EXPRmode | QUALmode, AnyRefClass.tpe));
+ tree setType ref1.tpe.resultType;
+
+ case SelectFromTypeTree(qual, selector) =>
+ tree setType transformSelect(transform(qual, TYPEmode, WildcardType), selector).tpe
+
+ case CompoundTypeTree(parents, refinements) =>
+ tree setType {
+ val parents1 = parents mapConserve (parent => transform(parent, TYPEmode, WildcardType));
+ if (parents1 exists (.tpe.isError)) ErrorType
+ else {
+ val decls = new Scope();
+ val self = refinedType(parents1 map (.tpe), context.enclClass.owner, decls);
+ new TypeChecker(context.make(tree, self.symbol, decls))
+ .transformRefinement(refinements);
+ self
+ }
+ }
+
+ case AppliedTypeTree(tpt, args) =>
+ val tpt1 = transform(tpt, mode | FUNmode, WildcardType);
+ val args1 = args mapConserve (arg => transform(arg, TYPEmode, WildcardType));
+ val tparams = context.undetparams;
+ context.undetparams = List();
+ if (tpt1.tpe.isError)
+ setError(tree)
+ else if (tparams.length == args1.length)
+ tree setType appliedType(tpt1.tpe, args1 map (.tpe))
+ else if (tparams.length == 0)
+ errorTree(tree, "" + tpt1.tpe + " does not take type parameters")
+ else
+ errorTree(tree, "wrong number of type arguments for " + tpt1.tpe)
}
-
- /** 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]));
- }
- }
- 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
}
- }
+ def transform(tree: Tree, mode: int, pt: Type): Tree =
+ try {
+ if (tree.tpe != null) tree else adapt(transform1(tree, mode, pt), mode, pt)
+ } catch {
+ case ex: TypeError =>
+ reportTypeError(tree.pos, ex);
+ setError(tree)
+ }
+ def transformExpr(tree: Tree): Tree =
+ transform(tree, EXPRmode, WildcardType);
-/* tree
- }
+ def transformType(tree: Tree, owner: Symbol) =
+ checkNoEscape(owner, transform(tree, TYPEmode, WildcardType));
}
}
-*/
-
- 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 _ =>
- }
- }
-
- 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 4c2f785af5..12cfb8a66a 100755
--- a/sources/scala/tools/nsc/typechecker/Typers.scala
+++ b/sources/scala/tools/nsc/typechecker/Typers.scala
@@ -22,21 +22,41 @@ trait Typers: Analyzer {
def typeCompleter(tree: Tree) = new TypeCompleter(tree) {
override def complete(sym: Symbol): unit = {
- if (settings.debug.value) log("defining " + sym);
- sym.setInfo(typeSig(tree));
+ if (settings.debug.value) log("defining " + sym);
+ sym.setInfo(typeSig(tree));
+ if (settings.debug.value) log("defined " + sym);
+ validate(sym);
+ }
+ }
+
+ def getterTypeCompleter(tree: Tree) = new TypeCompleter(tree) {
+ override def complete(sym: Symbol): unit = {
+ if (settings.debug.value) log("defining " + sym);
+ sym.setInfo(PolyType(List(), typeSig(tree)));
+ if (settings.debug.value) log("defined " + sym);
+ validate(sym);
+ }
+ }
+
+ def setterTypeCompleter(tree: Tree) = new TypeCompleter(tree) {
+ override def complete(sym: Symbol): unit = {
+ if (settings.debug.value) log("defining " + sym);
+ sym.setInfo(MethodType(List(typeSig(tree)), definitions.UnitClass.tpe));
if (settings.debug.value) log("defined " + sym);
validate(sym);
}
}
def selfTypeCompleter(tree: Tree) = new TypeCompleter(tree) {
- override def complete(sym: Symbol): unit =
- sym.setInfo(typechecker.transformType(tree).tpe)
+ override def complete(sym: Symbol): unit = {
+ sym.setInfo(typechecker.transformType(tree, sym).tpe);
+ }
}
private def deconstIfNotFinal(sym: Symbol, tpe: Type): Type =
if (sym.isVariable || !sym.hasFlag(FINAL)) tpe.deconst else tpe;
+
private def enterTypeParams(owner: Symbol, tparams: List[AbsTypeDef]): List[Symbol] = {
List.map2(owner.typeParams, tparams)
{ (tpsym, tptree) => tptree.symbol = tpsym; context.scope enter tpsym; tpsym }
@@ -62,45 +82,29 @@ trait Typers: Analyzer {
case _ => tpe
});
- private def templateSig(clazz: Symbol, templ: Template): Type = {
- // determine parent types
- 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");
-
- // enter all members
+ private def templateSig(templ: Template): Type = {
+ val clazz = context.owner;
+ val parents = typechecker.parentTypes(templ) map (.tpe);
val decls = new Scope();
new Namer(context.make(templ, clazz, decls)).enterSyms(templ.body);
ClassInfoType(parents, decls, clazz)
}
- private def classSig(clazz: Symbol,
- tparams: List[AbsTypeDef],
- tpt: Tree, impl: Template): Type = {
+ private def classSig(tparams: List[AbsTypeDef], tpt: Tree, impl: Template): Type = {
+ val clazz = context.owner;
val tparamSyms = enterTypeParams(clazz, tparams);
if (!tpt.isEmpty) clazz.typeOfThis = selfTypeCompleter(tpt);
- val constrTree = treeInfo.firstConstructor(impl.body);
- val constr = new Namer(context).enterSym(constrTree).initialize;
- typechecker.reenterValueParams(constrTree);
- makePolyType(tparamSyms, templateSig(clazz, impl))
+ makePolyType(tparamSyms, templateSig(impl))
}
- private def methodSig(meth: Symbol,
- tparams: List[AbsTypeDef], vparamss: List[List[ValDef]],
- tpt: Tree, rhs: Tree): Type = {
+ private def methodSig(tparams: List[AbsTypeDef], vparamss: List[List[ValDef]], tpt: Tree, rhs: Tree): Type = {
+ val meth = context.owner;
val tparamSyms = enterTypeParams(meth, tparams);
val vparamSymss = enterValueParams(meth, vparamss);
- val restype =
- typechecker.checkNoEscape(tpt.pos,
- deconstIfNotFinal(meth,
- if (meth.name == nme.CONSTRUCTOR) context.enclClass.owner.tpe
- else if (tpt.isEmpty) { tpt.tpe = typechecker.transformExpr(rhs).tpe; tpt.tpe }
- else typechecker.transformType(tpt).tpe));
+ val restype = deconstIfNotFinal(meth,
+ if (meth.name == nme.CONSTRUCTOR) context.enclClass.owner.tpe
+ else if (tpt.isEmpty) { tpt.tpe = typechecker.transformExpr(rhs).tpe; tpt.tpe }
+ else typechecker.transformType(tpt, meth).tpe);
def mkMethodType(vparams: List[Symbol], restpe: Type) =
MethodType(vparams map (.tpe), restpe);
makePolyType(
@@ -110,24 +114,22 @@ trait Typers: Analyzer {
}
private def aliasTypeSig(tpsym: Symbol, tparams: List[AbsTypeDef], rhs: Tree): Type =
- makePolyType(enterTypeParams(tpsym, tparams), typechecker.transformType(rhs).tpe);
+ makePolyType(enterTypeParams(tpsym, tparams), typechecker.transformType(rhs, tpsym).tpe);
private def typeSig(tree: Tree): Type =
try {
val sym: Symbol = tree.symbol;
tree match {
case ClassDef(_, _, tparams, tpt, impl) =>
- new Typer(context.makeNewScope(tree, sym)).classSig(sym, tparams, tpt, impl)
+ new Typer(context.makeNewScope(tree, sym)).classSig(tparams, tpt, impl)
- case ModuleDef(_, _, tpt, impl) =>
+ case ModuleDef(_, _, impl) =>
val clazz = sym.moduleClass;
- clazz.setInfo(new Typer(context.make(tree, clazz)).templateSig(clazz, impl));
- if (tpt.isEmpty) { tpt.tpe = clazz.tpe; tpt.tpe }
- else typechecker.transformType(tpt).tpe
+ clazz.setInfo(new Typer(context.make(tree, clazz)).templateSig(impl));
+ clazz.tpe
case DefDef(_, _, tparams, vparamss, tpt, rhs) =>
- new Typer(context.makeNewScope(tree, sym))
- .methodSig(sym, tparams, vparamss, tpt, rhs)
+ new Typer(context.makeNewScope(tree, sym)).methodSig(tparams, vparamss, tpt, rhs)
case ValDef(_, _, tpt, rhs) =>
deconstIfNotFinal(sym,
@@ -140,13 +142,14 @@ trait Typers: Analyzer {
.transformExpr(rhs).tpe;
tpt.tpe
}
- else typechecker.transformType(tpt).tpe)
+ else typechecker.transformType(tpt, sym).tpe)
case AliasTypeDef(_, _, tparams, rhs) =>
new Typer(context.makeNewScope(tree, sym)).aliasTypeSig(sym, tparams, rhs)
case AbsTypeDef(_, _, lo, hi) =>
- TypeBounds(typechecker.transformType(lo).tpe, typechecker.transformType(hi).tpe);
+ TypeBounds(typechecker.transformType(lo, sym).tpe,
+ typechecker.transformType(hi, sym).tpe);
case imptree @ Import(expr, selectors) =>
val expr1 = typechecker.transformExpr(expr);