summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2007-02-19 13:56:55 +0000
committerMartin Odersky <odersky@gmail.com>2007-02-19 13:56:55 +0000
commit68508bdd74fbb6e14143132b5e9bdaf89e4adf06 (patch)
tree53d5c39fe5d0f77aaca88484cc8b1479a58a67ce
parentce7fe41d5f7d831648068c8d82b7c6caa27aa3f5 (diff)
downloadscala-68508bdd74fbb6e14143132b5e9bdaf89e4adf06.tar.gz
scala-68508bdd74fbb6e14143132b5e9bdaf89e4adf06.tar.bz2
scala-68508bdd74fbb6e14143132b5e9bdaf89e4adf06.zip
added explicit self defs
-rw-r--r--src/compiler/scala/tools/nsc/Interpreter.scala2
-rw-r--r--src/compiler/scala/tools/nsc/ast/TreeBrowsers.scala6
-rw-r--r--src/compiler/scala/tools/nsc/ast/TreePrinters.scala14
-rw-r--r--src/compiler/scala/tools/nsc/ast/Trees.scala48
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/Parsers.scala149
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala7
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/GenICode.scala2
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Symbols.scala7
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Types.scala2
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala4
-rw-r--r--src/compiler/scala/tools/nsc/transform/AddInterfaces.scala4
-rw-r--r--src/compiler/scala/tools/nsc/transform/Constructors.scala4
-rw-r--r--src/compiler/scala/tools/nsc/transform/Erasure.scala4
-rw-r--r--src/compiler/scala/tools/nsc/transform/LambdaLift.scala8
-rw-r--r--src/compiler/scala/tools/nsc/transform/LiftCode.scala6
-rw-r--r--src/compiler/scala/tools/nsc/transform/Mixin.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/TailCalls.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala26
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/RefChecks.scala4
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala34
-rw-r--r--src/library/scala/collection/immutable/Map.scala16
21 files changed, 212 insertions, 139 deletions
diff --git a/src/compiler/scala/tools/nsc/Interpreter.scala b/src/compiler/scala/tools/nsc/Interpreter.scala
index 6ea4d43143..c8115cf7b4 100644
--- a/src/compiler/scala/tools/nsc/Interpreter.scala
+++ b/src/compiler/scala/tools/nsc/Interpreter.scala
@@ -184,7 +184,7 @@ class Interpreter(val settings: Settings, reporter: Reporter, out: PrintWriter)
val unit =
new CompilationUnit(
new SourceFile("<console>", code.toCharArray()))
- new compiler.syntaxAnalyzer.Parser(unit).templateStatSeq
+ new compiler.syntaxAnalyzer.Parser(unit).templateStatSeq._2
}
// parse the main code along with the imports
diff --git a/src/compiler/scala/tools/nsc/ast/TreeBrowsers.scala b/src/compiler/scala/tools/nsc/ast/TreeBrowsers.scala
index 9179533e43..038daeb815 100644
--- a/src/compiler/scala/tools/nsc/ast/TreeBrowsers.scala
+++ b/src/compiler/scala/tools/nsc/ast/TreeBrowsers.scala
@@ -260,7 +260,7 @@ abstract class TreeBrowsers {
case DocDef(comment, definition) =>
Pair("DocDef", EMPTY)
- case ClassDef(mods, name, tparams, tpt, impl) =>
+ case ClassDef(mods, name, tparams, self, impl) =>
Pair("ClassDef", name)
case PackageDef(packaged, impl) =>
@@ -395,10 +395,10 @@ abstract class TreeBrowsers {
case DocDef(comment, definition) =>
List(definition)
- case ClassDef(mods, name, tparams, tpt, impl) => {
+ case ClassDef(mods, name, tparams, self, impl) => {
var children: List[Tree] = List()
children = tparams ::: children
- tpt :: impl :: children
+ self :: impl :: children
}
case PackageDef(name, stats) =>
diff --git a/src/compiler/scala/tools/nsc/ast/TreePrinters.scala b/src/compiler/scala/tools/nsc/ast/TreePrinters.scala
index 5d2afcc332..89fc896003 100644
--- a/src/compiler/scala/tools/nsc/ast/TreePrinters.scala
+++ b/src/compiler/scala/tools/nsc/ast/TreePrinters.scala
@@ -121,12 +121,22 @@ abstract class TreePrinters {
case EmptyTree =>
print("<empty>")
- case ClassDef(mods, name, tparams, tp, impl) =>
+ case ClassDef(mods, name, tparams, self, impl) =>
printAnnotations(tree)
printModifiers(tree, mods)
print((if (mods hasFlag TRAIT) "trait " else "class ") + symName(tree, name))
printTypeParams(tparams)
- printOpt(" requires ", tp); print(" extends "); print(impl)
+ print(" extends ");
+ printRow(impl.parents, " with ")
+ if (!impl.body.isEmpty) {
+ print(" {");
+ if (self.name != nme.WILDCARD) {
+ print(" "); print(self.name); printOpt(": ", self.tpt); print(" => ")
+ } else if (!self.tpt.isEmpty) {
+ print(" _ : "); print(self); print(" => ")
+ }
+ }
+ printColumn(impl.body, "", ";", "}")
case PackageDef(packaged, stats) =>
printAnnotations(tree)
diff --git a/src/compiler/scala/tools/nsc/ast/Trees.scala b/src/compiler/scala/tools/nsc/ast/Trees.scala
index abcbcf3cf6..b385760a80 100644
--- a/src/compiler/scala/tools/nsc/ast/Trees.scala
+++ b/src/compiler/scala/tools/nsc/ast/Trees.scala
@@ -222,7 +222,7 @@ trait Trees requires Global {
}
/** Class definition */
- case class ClassDef(mods: Modifiers, name: Name, tparams: List[AbsTypeDef], tpt: Tree, impl: Template)
+ case class ClassDef(mods: Modifiers, name: Name, tparams: List[AbsTypeDef], self: ValDef, impl: Template)
extends ImplDef
/**
@@ -235,7 +235,7 @@ trait Trees requires Global {
ClassDef(Modifiers(sym.flags),
sym.name,
sym.typeParams map AbsTypeDef,
- if (sym.thisSym == sym) EmptyTree else TypeTree(sym.typeOfThis),
+ if (sym.thisSym == sym || phase.erasedTypes) emptyValDef else ValDef(sym.thisSym),
impl) setSymbol sym
}
@@ -298,6 +298,8 @@ trait Trees requires Global {
def ValDef(sym: Symbol): ValDef = ValDef(sym, EmptyTree)
+ object emptyValDef extends ValDef(Modifiers(PRIVATE), nme.WILDCARD, TypeTree(), EmptyTree)
+
/** Method definition
*
* @param mods
@@ -695,7 +697,7 @@ trait Trees requires Global {
/* A standard pattern match
case EmptyTree =>
case PackageDef(name, stats) =>
- case ClassDef(mods, name, tparams, tpt, impl) =>
+ case ClassDef(mods, name, tparams, self, impl) =>
case ModuleDef(mods, name, impl) => (eliminated by refcheck)
case ValDef(mods, name, tpt, rhs) =>
case DefDef(mods, name, tparams, vparamss, tpt, rhs) =>
@@ -741,7 +743,7 @@ trait Trees requires Global {
*/
abstract class TreeCopier {
- def ClassDef(tree: Tree, mods: Modifiers, name: Name, tparams: List[AbsTypeDef], tpt: Tree, impl: Template): ClassDef
+ def ClassDef(tree: Tree, mods: Modifiers, name: Name, tparams: List[AbsTypeDef], self: ValDef, impl: Template): ClassDef
def PackageDef(tree: Tree, name: Name, stats: List[Tree]): PackageDef
def ModuleDef(tree: Tree, mods: Modifiers, name: Name, impl: Template): ModuleDef
def ValDef(tree: Tree, mods: Modifiers, name: Name, tpt: Tree, rhs: Tree): ValDef
@@ -788,8 +790,8 @@ trait Trees requires Global {
}
class StrictTreeCopier extends TreeCopier {
- def ClassDef(tree: Tree, mods: Modifiers, name: Name, tparams: List[AbsTypeDef], tpt: Tree, impl: Template) =
- new ClassDef(mods, name, tparams, tpt, impl).copyAttrs(tree);
+ def ClassDef(tree: Tree, mods: Modifiers, name: Name, tparams: List[AbsTypeDef], self: ValDef, impl: Template) =
+ new ClassDef(mods, name, tparams, self, impl).copyAttrs(tree);
def PackageDef(tree: Tree, name: Name, stats: List[Tree]) =
new PackageDef(name, stats).copyAttrs(tree)
def ModuleDef(tree: Tree, mods: Modifiers, name: Name, impl: Template) =
@@ -880,10 +882,10 @@ trait Trees requires Global {
class LazyTreeCopier(copy: TreeCopier) extends TreeCopier {
def this() = this(new StrictTreeCopier)
- def ClassDef(tree: Tree, mods: Modifiers, 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 ClassDef(tree: Tree, mods: Modifiers, name: Name, tparams: List[AbsTypeDef], self: ValDef, impl: Template) = tree match {
+ case t @ ClassDef(mods0, name0, tparams0, self0, impl0)
+ if (mods0 == mods && (name0 == name) && (tparams0 == tparams) && (self0 == self) && (impl0 == impl)) => t
+ case _ => copy.ClassDef(tree, mods, name, tparams, self, impl)
}
def PackageDef(tree: Tree, name: Name, stats: List[Tree]) = tree match {
case t @ PackageDef(name0, stats0)
@@ -1115,22 +1117,22 @@ trait Trees requires Global {
atOwner(tree.symbol.moduleClass) {
copy.PackageDef(tree, name, transformStats(stats, currentOwner))
}
- case ClassDef(mods, name, tparams, tpt, impl) =>
+ case ClassDef(mods, name, tparams, self, impl) =>
atOwner(tree.symbol) {
copy.ClassDef(tree, mods, name, transformAbsTypeDefs(tparams),
- transform(tpt), transformTemplate(impl))
+ transformValDef(self), transformTemplate(impl))
}
case ModuleDef(mods, name, impl) =>
- atOwner(tree.symbol.moduleClass) {
- copy.ModuleDef(tree, mods, name, transformTemplate(impl))
+ atOwner(tree.symbol.moduleClass) {
+ copy.ModuleDef(tree, mods, name, transformTemplate(impl))
}
case ValDef(mods, name, tpt, rhs) =>
- atOwner(tree.symbol) {
- copy.ValDef(tree, mods, name, transform(tpt), transform(rhs))
+ atOwner(tree.symbol) {
+ copy.ValDef(tree, mods, name, transform(tpt), transform(rhs))
}
case DefDef(mods, name, tparams, vparamss, tpt, rhs) =>
- atOwner(tree.symbol) {
- copy.DefDef(
+ atOwner(tree.symbol) {
+ copy.DefDef(
tree, mods, name, transformAbsTypeDefs(tparams), transformValDefss(vparamss), transform(tpt), transform(rhs))
}
case AbsTypeDef(mods, name, lo, hi) =>
@@ -1225,10 +1227,12 @@ trait Trees requires Global {
transform(tree: Tree).asInstanceOf[Template]
def transformAbsTypeDefs(trees: List[AbsTypeDef]): List[AbsTypeDef] =
List.mapConserve(trees)(tree => transform(tree).asInstanceOf[AbsTypeDef])
+ def transformValDef(tree: ValDef): ValDef =
+ transform(tree).asInstanceOf[ValDef]
def transformValDefs(trees: List[ValDef]): List[ValDef] =
- List.mapConserve(trees)(tree => transform(tree).asInstanceOf[ValDef])
+ List.mapConserve(trees)(transformValDef)
def transformValDefss(treess: List[List[ValDef]]): List[List[ValDef]] =
- List.mapConserve(treess)(tree => transformValDefs(tree))
+ List.mapConserve(treess)(transformValDefs)
def transformCaseDefs(trees: List[CaseDef]): List[CaseDef] =
List.mapConserve(trees)(tree => transform(tree).asInstanceOf[CaseDef])
def transformIdents(trees: List[Ident]): List[Ident] =
@@ -1257,9 +1261,9 @@ trait Trees requires Global {
atOwner(tree.symbol.moduleClass) {
traverseTrees(stats)
}
- case ClassDef(mods, name, tparams, tpt, impl) =>
+ case ClassDef(mods, name, tparams, self, impl) =>
atOwner(tree.symbol) {
- traverseTrees(tparams); traverse(tpt); traverse(impl)
+ traverseTrees(tparams); traverse(self); traverse(impl)
}
case ModuleDef(mods, name, impl) =>
atOwner(tree.symbol.moduleClass) {
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
index 8934906b26..9affe5be75 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
@@ -279,7 +279,6 @@ trait Parsers requires SyntaxAnalyzer {
case Typed(Ident(name), tpe) =>
ValDef(Modifiers(Flags.PARAM), name, tpe, EmptyTree)
case _ =>
- Console.println("CTP "+tree) //debug
syntaxError(tree.pos, "not a legal formal parameter", false)
throw new Error()
ValDef(Modifiers(Flags.PARAM), nme.ERROR, errorTypeTree, EmptyTree)
@@ -802,6 +801,10 @@ trait Parsers requires SyntaxAnalyzer {
ts.toList
}
+ private final val Local = 0
+ private final val InBlock = 1
+ private final val InTemplate = 2
+
/** Expr ::= (Bindings | Id) `=>' Expr
* | PostfixExpr `:' Type
* | Expr1
@@ -826,10 +829,8 @@ trait Parsers requires SyntaxAnalyzer {
* | `:' Annotation {Annotation}
* | `:' `_' `*'
*/
- def expr(): Tree = exprImpl(false)
- def blockStatExpr(): Tree = exprImpl(true)
-
- private def exprImpl(isInBlock: boolean): Tree = in.token match {
+ def expr(): Tree = expr(Local)
+ def expr(location: int): Tree = in.token match {
case IF =>
val pos = in.skipToken()
accept(LPAREN)
@@ -930,7 +931,7 @@ trait Parsers requires SyntaxAnalyzer {
}
} else if (annots.isEmpty || isTypeIntro) {
t = atPos(pos) {
- val tpt = if (isInBlock) compoundType(false) else typ()
+ val tpt = if (location != Local) compoundType(false) else typ()
// this does not correspond to syntax, but is necessary to
// accept closures. We might restrict closures to be between {...} only!
Typed(t, (tpt /: annots) (makeAnnotated))
@@ -946,9 +947,9 @@ trait Parsers requires SyntaxAnalyzer {
Match(stripParens(t), cases)
}
}
- if (in.token == ARROW) {
+ if (in.token == ARROW && location != InTemplate) {
t = atPos(in.skipToken()) {
- Function(convertToParams(t), if (isInBlock) block() else expr())
+ Function(convertToParams(t), if (location == Local) expr() else block())
}
}
stripParens(t)
@@ -1059,8 +1060,9 @@ trait Parsers requires SyntaxAnalyzer {
parents += annotType(false)
}
newLineOptWhenFollowedBy(LBRACE)
- val stats = if (in.token == LBRACE) templateBody() else List()
- makeNew(parents.toList, stats, argss.toList)
+ val Pair(self, stats) = if (in.token == LBRACE) templateBody()
+ else Pair(emptyValDef, List())
+ makeNew(parents.toList, self, stats, argss.toList)
}
canApply = false
case _ =>
@@ -1969,12 +1971,14 @@ trait Parsers requires SyntaxAnalyzer {
else Pair(accessModifierOpt(),
paramClauses(name, implicitClassViews, mods.hasFlag(Flags.CASE)))
val thistpe = requiresTypeOpt()
- val template = classTemplate(mods, name, constrMods withAnnotations constrAnnots, vparamss)
+ val Pair(self0, template) =
+ classTemplate(mods, name, constrMods withAnnotations constrAnnots, vparamss)
val mods1 = if (mods.hasFlag(Flags.TRAIT) &&
(template.body forall treeInfo.isInterfaceMember))
mods | Flags.INTERFACE
else mods
- val result = ClassDef(mods1, name, tparams, thistpe, template)
+ val self = if (thistpe.isEmpty) self0 else makeSelfDef(nme.WILDCARD, thistpe)
+ val result = ClassDef(mods1, name, tparams, self, template)
implicitClassViews = savedViews
result
}
@@ -1984,7 +1988,14 @@ trait Parsers requires SyntaxAnalyzer {
def objectDef(mods: Modifiers): ModuleDef =
atPos(in.skipToken()) {
val name = ident()
- val template = classTemplate(mods, name, NoMods, List())
+ val Pair(self, template0) = classTemplate(mods, name, NoMods, List())
+ val template = self match {
+ case ValDef(mods, name, tpt, EmptyTree) if (name != nme.WILDCARD) =>
+ val vd = ValDef(mods, name, tpt, This(nme.EMPTY.toTypeName)) setPos self.pos
+ Template(template0.parents, vd :: template0.body)
+ case _ =>
+ template0
+ }
ModuleDef(mods, name, template)
}
@@ -1993,59 +2004,61 @@ trait Parsers requires SyntaxAnalyzer {
* TraitTemplate ::= [extends MixinParents] [TemplateBody]
* MixinParents ::= AnnotType {with AnnotType}
*/
- def classTemplate(mods: Modifiers, name: Name, constrMods: Modifiers, vparamss: List[List[ValDef]]): Template =
- atPos(in.currentPos) {
- def acceptEmptyTemplateBody(msg: String): unit = {
- if (in.token == LPAREN && settings.migrate.value)
- syntaxErrorMigrate("traits may not have parameters")
- if (!(isStatSep || in.token == COMMA || in.token == RBRACE || in.token == EOF))
- syntaxError(msg, true)
- }
- val parents = new ListBuffer[Tree]
- val argss = new ListBuffer[List[Tree]]
- if (in.token == EXTENDS) {
+ def classTemplate(mods: Modifiers, name: Name, constrMods: Modifiers, vparamss: List[List[ValDef]]): Pair[ValDef, Template] = {
+ val pos = in.currentPos;
+ def acceptEmptyTemplateBody(msg: String): unit = {
+ if (in.token == LPAREN && settings.migrate.value)
+ syntaxErrorMigrate("traits may not have parameters")
+ if (!(isStatSep || in.token == COMMA || in.token == RBRACE || in.token == EOF))
+ syntaxError(msg, true)
+ }
+ val parents = new ListBuffer[Tree]
+ val argss = new ListBuffer[List[Tree]]
+ if (in.token == EXTENDS) {
+ in.nextToken()
+ val parent = annotType(false)
+ // System.err.println("classTempl: " + parent)
+ parents += parent
+ if (in.token == LPAREN && !mods.hasFlag(Flags.TRAIT))
+ do { argss += argumentExprs() } while (in.token == LPAREN)
+ else argss += List()
+ while (in.token == WITH) {
in.nextToken()
- val parent = annotType(false)
- // System.err.println("classTempl: " + parent)
- parents += parent
- if (in.token == LPAREN && !mods.hasFlag(Flags.TRAIT))
- do { argss += argumentExprs() } while (in.token == LPAREN)
- else argss += List()
- while (in.token == WITH) {
- in.nextToken()
- parents += annotType(false)
- }
- } else {
- if (in.token == WITH && settings.migrate.value)
- syntaxErrorMigrate("`extends' needed before `with'")
- newLineOptWhenFollowedBy(LBRACE)
- if (in.token != LBRACE) acceptEmptyTemplateBody("`extends' or `{' expected")
- argss += List()
- }
- if (name != nme.ScalaObject.toTypeName)
- parents += scalaScalaObjectConstr
- if (mods.hasFlag(Flags.CASE)) {
- parents += productConstr
+ parents += annotType(false)
}
- val ps = parents.toList
+ } else {
+ if (in.token == WITH && settings.migrate.value)
+ syntaxErrorMigrate("`extends' needed before `with'")
newLineOptWhenFollowedBy(LBRACE)
- var body =
- if (in.token == LBRACE) templateBody()
- else { acceptEmptyTemplateBody("`{' expected"); List() }
- if (!mods.hasFlag(Flags.TRAIT)) Template(ps, constrMods, vparamss, argss.toList, body)
- else Template(ps, body)
+ if (in.token != LBRACE) acceptEmptyTemplateBody("`extends' or `{' expected")
+ argss += List()
+ }
+ if (name != nme.ScalaObject.toTypeName)
+ parents += scalaScalaObjectConstr
+ if (mods.hasFlag(Flags.CASE)) {
+ parents += productConstr
}
+ val ps = parents.toList
+ newLineOptWhenFollowedBy(LBRACE)
+ val Pair(self, body) =
+ if (in.token == LBRACE) templateBody()
+ else { acceptEmptyTemplateBody("`{' expected"); Pair(emptyValDef, List()) }
+ Pair(self,
+ atPos(pos) {
+ if (!mods.hasFlag(Flags.TRAIT)) Template(ps, constrMods, vparamss, argss.toList, body)
+ else Template(ps, body)
+ })
+ }
////////// TEMPLATES ////////////////////////////////////////////////////////////
- /** TemplateBody ::= [nl] `{' TemplateStat {semi TemplateStat} `}'
+ /** TemplateBody ::= [nl] `{' TemplateStatSeq `}'
*/
- def templateBody(): List[Tree] = {
+ def templateBody(): Pair[ValDef, List[Tree]] = {
accept(LBRACE)
- var body = templateStatSeq()
- if (body.isEmpty) body = List(EmptyTree)
+ val result = templateStatSeq()
accept(RBRACE)
- body
+ result
}
/** Refinement ::= [nl] `{' RefineStat {semi RefineStat} `}'
@@ -2103,20 +2116,32 @@ trait Parsers requires SyntaxAnalyzer {
stats.toList
}
- /** TemplateStatSeq ::= TemplateStat {semi TemplateStat}
+ /** TemplateStatSeq ::= [id [`:' Type] `=>'] TemplateStat {semi TemplateStat}
* TemplateStat ::= Import
* | Annotations Modifiers Def
* | Annotations Modifiers Dcl
- * | Expr
+ * | Expr1
* |
*/
- def templateStatSeq(): List[Tree] = {
+ def templateStatSeq(): Pair[ValDef, List[Tree]] = {
+ var self: ValDef = emptyValDef
val stats = new ListBuffer[Tree]
+ if (isExprIntro) {
+ val first = expr(InTemplate)
+ if (in.token == ARROW) {
+ convertToParam(first) match {
+ case ValDef(_, name, tpt, EmptyTree) if (name != nme.ERROR) =>
+ self = makeSelfDef(name, tpt)
+ case _ =>
+ }
+ in.nextToken()
+ } else stats += first
+ }
while (in.token != RBRACE && in.token != EOF) {
if (in.token == IMPORT) {
stats ++= importClause()
} else if (isExprIntro) {
- stats += expr()
+ stats += expr(InTemplate)
} else if (isDefIntro || isModifier || in.token == LBRACKET /*todo: remove */ || in.token == AT) {
val annots = annotations()
stats ++ joinComment(defOrDcl(modifiers() withAnnotations annots))
@@ -2125,7 +2150,7 @@ trait Parsers requires SyntaxAnalyzer {
}
if (in.token != RBRACE && in.token != EOF) acceptStatSep()
}
- stats.toList
+ Pair(self, if (!stats.hasNext) List(EmptyTree) else stats.toList)
}
/** RefineStatSeq ::= RefineStat {semi RefineStat}
@@ -2170,7 +2195,7 @@ trait Parsers requires SyntaxAnalyzer {
stats ++= importClause()
acceptStatSep()
} else if (isExprIntro) {
- stats += blockStatExpr()
+ stats += expr(InBlock)
if (in.token != RBRACE && in.token != CASE) acceptStatSep()
} else if (isDefIntro) {
localDef(NoMods)
diff --git a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala
index f3685365d2..5118d12236 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala
@@ -107,6 +107,9 @@ abstract class TreeBuilder {
case Annotation(constr, elements) => Annotated(constr, elements, t) setPos attr.pos
}
+ def makeSelfDef(name: Name, tpt: Tree): ValDef =
+ ValDef(Modifiers(PRIVATE), name, tpt, EmptyTree)
+
/** If tree is a variable pattern, return Some("its name and type").
* Otherwise return none */
private def matchVarPattern(tree: Tree): Option[Pair[Name, Tree]] = tree match {
@@ -138,14 +141,14 @@ abstract class TreeBuilder {
}
/** Create tree representing an object creation <new parents { stats }> */
- def makeNew(parents: List[Tree], stats: List[Tree], argss: List[List[Tree]]): Tree =
+ def makeNew(parents: List[Tree], self: ValDef, stats: List[Tree], argss: List[List[Tree]]): Tree =
if (parents.tail.isEmpty && stats.isEmpty)
New(parents.head, argss)
else {
val x = nme.ANON_CLASS_NAME.toTypeName
Block(
List(ClassDef(
- Modifiers(FINAL | SYNTHETIC), x, List(), TypeTree(),
+ Modifiers(FINAL | SYNTHETIC), x, List(), self,
Template(parents, NoMods, List(List()), argss, stats))),
New(Ident(x), List(List())))
}
diff --git a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
index 0219442b8a..be74fe4e78 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
@@ -78,7 +78,7 @@ abstract class GenICode extends SubComponent {
case PackageDef(name, stats) =>
gen(stats, ctx setPackage name)
- case ClassDef(mods, name, tparams, tpt, impl) =>
+ case ClassDef(mods, name, _, _, impl) =>
log("Generating class: " + tree.symbol.fullNameString)
ctx setClass (new IClass(tree.symbol) setCompilationUnit unit)
addClassFields(ctx, tree.symbol);
diff --git a/src/compiler/scala/tools/nsc/symtab/Symbols.scala b/src/compiler/scala/tools/nsc/symtab/Symbols.scala
index 5d2e5220d4..5c58352a36 100644
--- a/src/compiler/scala/tools/nsc/symtab/Symbols.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Symbols.scala
@@ -189,7 +189,7 @@ trait Symbols requires SymbolTable {
final def isModule = isTerm && hasFlag(MODULE)
final def isStaticModule = isModule && isStatic && !isMethod
final def isPackage = isModule && hasFlag(PACKAGE)
- final def isThisSym = isTerm && name == nme.this_
+ final def isThisSym = isTerm && owner.thisSym == this
final def isThisSkolem = isTerm && deSkolemize != this
final def isError = hasFlag(IS_ERROR)
final def isErroneous = isError || isInitialized && tpe.isErroneous
@@ -1252,7 +1252,10 @@ trait Symbols requires SymbolTable {
override def cloneSymbolImpl(owner: Symbol): Symbol = {
assert(!isModuleClass)
val clone = new ClassSymbol(owner, pos, name)
- if (thisSym != this) clone.typeOfThis = typeOfThis
+ if (thisSym != this) {
+ clone.typeOfThis = typeOfThis
+ clone.thisSym.name = thisSym.name
+ }
clone
}
diff --git a/src/compiler/scala/tools/nsc/symtab/Types.scala b/src/compiler/scala/tools/nsc/symtab/Types.scala
index 27bc11ff67..163683401a 100644
--- a/src/compiler/scala/tools/nsc/symtab/Types.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Types.scala
@@ -1285,7 +1285,7 @@ trait Types requires SymbolTable {
abstract class LazyType extends Type {
override def isComplete: boolean = false
override def complete(sym: Symbol): unit
- override def toString = "LazyType"
+ override def toString = "<?>"
}
/** A class representing a lazy type with known type parameters.
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala
index 78ab6c0d34..f1ed8f36c0 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala
@@ -105,7 +105,7 @@ abstract class Pickler extends SubComponent {
putSymbol(sym.owner)
putSymbol(sym.privateWithin)
putType(sym.info)
- if (sym.thisSym != sym)
+ if (sym.thisSym.tpe != sym.tpe)
putType(sym.typeOfThis);
putSymbol(sym.alias)
if (!sym.children.isEmpty)
@@ -236,7 +236,7 @@ abstract class Pickler extends SubComponent {
tag
case sym: ClassSymbol =>
val posOffset = writeSymInfo(sym)
- if (sym.thisSym != sym) writeRef(sym.typeOfThis)
+ if (sym.thisSym.tpe != sym.tpe) writeRef(sym.typeOfThis)
CLASSsym + posOffset
case sym: TypeSymbol =>
val posOffset = writeSymInfo(sym)
diff --git a/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala b/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala
index 5b264a33e8..64f2bf2625 100644
--- a/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala
+++ b/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala
@@ -301,9 +301,9 @@ abstract class AddInterfaces extends InfoTransform {
override def transform(tree: Tree): Tree = {
val sym = tree.symbol
val tree1 = tree match {
- case ClassDef(mods, name, tparams, tpt, impl) if (sym.needsImplClass) =>
+ case ClassDef(mods, name, tparams, self, impl) if (sym.needsImplClass) =>
implClass(sym).initialize // to force lateDEFERRED flags
- copy.ClassDef(tree, mods | INTERFACE, name, tparams, tpt, ifaceTemplate(impl))
+ copy.ClassDef(tree, mods | INTERFACE, name, tparams, self, ifaceTemplate(impl))
case DefDef(mods, name, tparams, vparamss, tpt, rhs)
if (sym.isClassConstructor && sym.isPrimaryConstructor && sym.owner != ArrayClass) =>
copy.DefDef(tree, mods, name, tparams, vparamss, tpt,
diff --git a/src/compiler/scala/tools/nsc/transform/Constructors.scala b/src/compiler/scala/tools/nsc/transform/Constructors.scala
index 29e1ceeb1d..76ad75e317 100644
--- a/src/compiler/scala/tools/nsc/transform/Constructors.scala
+++ b/src/compiler/scala/tools/nsc/transform/Constructors.scala
@@ -184,8 +184,8 @@ abstract class Constructors extends Transform {
override def transform(tree: Tree): Tree = {
tree match {
- case ClassDef(mods, name, tparams, tpt, impl) if !tree.symbol.hasFlag(INTERFACE) =>
- copy.ClassDef(tree, mods, name, tparams, tpt, transformClassTemplate(impl))
+ case ClassDef(mods, name, tparams, self, impl) if !tree.symbol.hasFlag(INTERFACE) =>
+ copy.ClassDef(tree, mods, name, tparams, self, transformClassTemplate(impl))
case _ =>
super.transform(tree)
}
diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala
index 8d70c8360c..ed540ea1f4 100644
--- a/src/compiler/scala/tools/nsc/transform/Erasure.scala
+++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala
@@ -717,10 +717,10 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer {
override def transform(tree: Tree): Tree = {
if (tree.symbol == ArrayClass) return tree
val tree1 = tree match {
- case ClassDef(mods, name, tparams, tpt, impl) =>
+ case ClassDef(mods, name, tparams, self, impl) =>
if (settings.debug.value)
log("defs of " + tree.symbol + " = " + tree.symbol.info.decls)
- copy.ClassDef(tree, mods, name, List(), tpt, impl)
+ copy.ClassDef(tree, mods, name, List(), emptyValDef, impl)
case DefDef(mods, name, tparams, vparamss, tpt, rhs) =>
copy.DefDef(tree, mods, name, List(), vparamss, tpt, rhs)
case AbsTypeDef(_, _, _, _) =>
diff --git a/src/compiler/scala/tools/nsc/transform/LambdaLift.scala b/src/compiler/scala/tools/nsc/transform/LambdaLift.scala
index d47a209ebe..9d370bcc6f 100644
--- a/src/compiler/scala/tools/nsc/transform/LambdaLift.scala
+++ b/src/compiler/scala/tools/nsc/transform/LambdaLift.scala
@@ -319,8 +319,8 @@ abstract class LambdaLift extends InfoTransform {
sym.updateInfo(
lifted(MethodType(sym.info.paramTypes ::: (ps map (.tpe)), sym.info.resultType)));
copy.DefDef(tree, mods, name, tparams, List(vparams ::: freeParams), tpt, rhs)
- case ClassDef(mods, name, tparams, tpt, impl @ Template(parents, body)) =>
- copy.ClassDef(tree, mods, name, tparams, tpt,
+ case ClassDef(mods, name, tparams, self, impl @ Template(parents, body)) =>
+ copy.ClassDef(tree, mods, name, tparams, self,
copy.Template(impl, parents, body ::: freeParams))
}
case None =>
@@ -397,10 +397,10 @@ abstract class LambdaLift extends InfoTransform {
/** Transform statements and add lifted definitions to them. */
override def transformStats(stats: List[Tree], exprOwner: Symbol): List[Tree] = {
def addLifted(stat: Tree): Tree = stat match {
- case ClassDef(mods, name, tparams, tpt, impl @ Template(parents, body)) =>
+ case ClassDef(mods, name, tparams, self, impl @ Template(parents, body)) =>
val lifted = liftedDefs(stat.symbol).toList map addLifted
val result = copy.ClassDef(
- stat, mods, name, tparams, tpt, copy.Template(impl, parents, body ::: lifted))
+ stat, mods, name, tparams, self, copy.Template(impl, parents, body ::: lifted))
liftedDefs -= stat.symbol
result
case _ =>
diff --git a/src/compiler/scala/tools/nsc/transform/LiftCode.scala b/src/compiler/scala/tools/nsc/transform/LiftCode.scala
index 3a633bb2c7..db27ab88fe 100644
--- a/src/compiler/scala/tools/nsc/transform/LiftCode.scala
+++ b/src/compiler/scala/tools/nsc/transform/LiftCode.scala
@@ -124,12 +124,12 @@ abstract class LiftCode extends Transform {
val rhs_ = reify(rhs)
reflect.ValDef(sym, rhs_)
- case cd @ ClassDef(mods, name, tparams, tpt, impl) =>
+ case cd @ ClassDef(mods, name, tparams, self, impl) =>
if(!tparams.isEmpty)
throw new TypeError("cannot handle polymorphic ClassDef ("+name+"): " + tparams)
val rsym = reify(cd.symbol)
val rimp = reify(impl)
- val rtpe = reify(tpt.tpe)
+ val rtpe = reify(self.tpe) //todo: update
reflect.ClassDef(rsym, rtpe, rimp.asInstanceOf[reflect.Template])
case tmpl @ Template(parents, body) =>
@@ -299,7 +299,7 @@ abstract class LiftCode extends Transform {
// case EmptyTree =>
// case LiftPoint(tree) =>
// case PackageDef(name, stats) =>
-// case ClassDef(mods, name, tparams, tpt, impl) =>
+// case ClassDef(mods, name, tparams, self, impl) =>
// case ValDef(mods, name, tpt, rhs) =>
// case DefDef(mods, name, tparams, vparamss, tpt, rhs) =>
// case AbsTypeDef(mods, name, lo, hi) =>
diff --git a/src/compiler/scala/tools/nsc/transform/Mixin.scala b/src/compiler/scala/tools/nsc/transform/Mixin.scala
index 82ff45a644..f35eb5dcc4 100644
--- a/src/compiler/scala/tools/nsc/transform/Mixin.scala
+++ b/src/compiler/scala/tools/nsc/transform/Mixin.scala
@@ -365,7 +365,7 @@ abstract class Mixin extends InfoTransform {
tree.tpe = ifacetpe
}
tree
- case ValDef(_, _, _, _) if (currentOwner.isImplClass) =>
+ case ValDef(_, _, _, _) if (currentOwner.isImplClass && tree != emptyValDef) =>
EmptyTree
case _ =>
tree
diff --git a/src/compiler/scala/tools/nsc/transform/TailCalls.scala b/src/compiler/scala/tools/nsc/transform/TailCalls.scala
index c83430f265..1fc2f43e3e 100644
--- a/src/compiler/scala/tools/nsc/transform/TailCalls.scala
+++ b/src/compiler/scala/tools/nsc/transform/TailCalls.scala
@@ -180,7 +180,7 @@ abstract class TailCalls extends Transform
case EmptyTree => tree
case PackageDef(name, stats) => super.transform(tree)
- case ClassDef(mods, name, tparams, tpt, impl) =>
+ case ClassDef(_, name, _, _, _) =>
log("Entering class " + name)
val res = super.transform(tree)
log("Leaving class " + name)
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
index d7025f3dc1..000c57d766 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -432,11 +432,25 @@ trait Namers requires Analyzer {
ClassInfoType(parents, decls, clazz)
}
- private def classSig(tparams: List[AbsTypeDef], tpt: Tree, impl: Template): Type = {
+ private def classSig(tparams: List[AbsTypeDef], self: ValDef, impl: Template): Type = {
+ val clazz = context.owner
val tparamSyms = typer.reenterTypeParams(tparams)
- if (!tpt.isEmpty)
- context.owner.typeOfThis = selfTypeCompleter(tpt)
- else tpt.tpe = NoType
+ if (!self.tpt.isEmpty) {
+ clazz.typeOfThis = selfTypeCompleter(self.tpt)
+ self.symbol = clazz.thisSym
+ } else {
+ self.tpt.tpe = NoType
+ if (self.name != nme.WILDCARD) {
+ clazz.typeOfThis = clazz.tpe
+ self.symbol = clazz.thisSym
+ } else {
+ self.symbol = clazz.newThisSym(self.pos) setInfo clazz.tpe
+ }
+ }
+ if (self.name != nme.WILDCARD) {
+ context.scope enter self.symbol
+ clazz.thisSym.name = self.name
+ }
makePolyType(tparamSyms, templateSig(impl))
}
@@ -561,8 +575,8 @@ trait Namers requires Analyzer {
try {
val sym: Symbol = tree.symbol
tree match {
- case ClassDef(_, _, tparams, tpt, impl) =>
- new Namer(makeNewScope(context, tree, sym)).classSig(tparams, tpt, impl)
+ case ClassDef(_, _, tparams, self, impl) =>
+ new Namer(makeNewScope(context, tree, sym)).classSig(tparams, self, impl)
case ModuleDef(_, _, impl) =>
val clazz = sym.moduleClass
diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
index 2afb6dd493..7a06d45cb5 100644
--- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
@@ -458,7 +458,7 @@ abstract class RefChecks extends InfoTransform {
def transformStat(tree: Tree, index: int): List[Tree] = tree match {
case ModuleDef(mods, name, impl) =>
val sym = tree.symbol
- val cdef = ClassDef(mods | MODULE, name, List(), EmptyTree, impl)
+ val cdef = ClassDef(mods | MODULE, name, List(), emptyValDef, impl)
.setPos(tree.pos)
.setSymbol(sym.moduleClass)
.setType(NoType);
@@ -577,7 +577,7 @@ abstract class RefChecks extends InfoTransform {
val sym = tree.symbol
var result = tree
tree match {
- case ClassDef(mods, name, tparams, tpe, impl) =>
+ case ClassDef(mods, name, tparams, _, impl) =>
validateVariance(sym, sym.info, CoVariance)
validateVariance(sym, sym.typeOfThis, CoVariance)
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index c05c17a0a2..dc82bfdc9c 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -833,11 +833,17 @@ trait Typers requires Analyzer {
val clazz = cdef.symbol
reenterTypeParams(cdef.tparams)
val tparams1 = List.mapConserve(cdef.tparams)(typedAbsTypeDef)
- val tpt1 = checkNoEscaping.privates(clazz.thisSym, typedType(cdef.tpt))
- val impl1 = newTyper(context.make(cdef.impl, clazz, newScope))
+ val self1 = cdef.self match {
+ case ValDef(mods, name, tpt, EmptyTree) =>
+ val tpt1 = checkNoEscaping.privates(clazz.thisSym, typedType(tpt))
+ copy.ValDef(cdef.self, mods, name, tpt1, EmptyTree) setType NoType
+ }
+ val implScope = newScope
+ if (self1.name != nme.WILDCARD) implScope enter self1.symbol
+ val impl1 = newTyper(context.make(cdef.impl, clazz, implScope))
.typedTemplate(cdef.impl, parentTypes(cdef.impl))
val impl2 = addSyntheticMethods(impl1, clazz, context.unit)
- val ret = copy.ClassDef(cdef, cdef.mods, cdef.name, tparams1, tpt1, impl2)
+ val ret = copy.ClassDef(cdef, cdef.mods, cdef.name, tparams1, self1, impl2)
.setType(NoType)
ret
}
@@ -1847,17 +1853,6 @@ trait Typers requires Analyzer {
(context.unit ne null) && defSym.sourceFile != context.unit.source.file))
defSym = NoSymbol
-/*
- /*<unapply>*/
- if(settings.Xunapply.value)
- // unapply: in patterns, look for an object if can't find type
- if (!defSym.exists && !impSym.exists && name.isTypeName && (mode & PATTERNmode) != 0) {
- val mod = typedIdent(name.toTermName)
- return tree setSymbol mod.symbol setType mod.tpe
- }
- /*</unapply>*/
-*/
-
if (defSym.exists) {
if (impSym.exists)
ambiguousError(
@@ -1904,10 +1899,13 @@ trait Typers requires Analyzer {
}
}
if (defSym.owner.isPackageClass) pre = defSym.owner.thisType
- val tree1 = if (qual == EmptyTree) tree
- else atPos(tree.pos)(Select(qual, name))
- // atPos necessary because qualifier might come from startContext
- stabilize(checkAccessible(tree1, defSym, pre, qual), pre, mode, pt)
+ if (defSym.isThisSym) typed1(This(defSym.owner), mode, pt)
+ else {
+ val tree1 = if (qual == EmptyTree) tree
+ else atPos(tree.pos)(Select(qual, name))
+ // atPos necessary because qualifier might come from startContext
+ stabilize(checkAccessible(tree1, defSym, pre, qual), pre, mode, pt)
+ }
}
// begin typed1
diff --git a/src/library/scala/collection/immutable/Map.scala b/src/library/scala/collection/immutable/Map.scala
index 108cb07f44..65b0df4979 100644
--- a/src/library/scala/collection/immutable/Map.scala
+++ b/src/library/scala/collection/immutable/Map.scala
@@ -132,6 +132,22 @@ trait Map[A, +B] extends collection.Map[A, B] {
def -- (keys: Iterator[A]): Map[A, B] =
(this /: keys) ((m, key) => m - key)
+
+ /** The same map with a given default function */
+ def withDefault[B1 >: B](d: A => B1): Map[A, B1] = new Map[A, B1] {
+ def size = Map.this.size
+ def get(key: A) = Map.this.get(key)
+ def elements = Map.this.elements
+ def empty[C] = Map.this.empty
+ def update [B2 >: B1](key: A, value: B2): Map[A, B2] =
+ Map.this.update(key, value) withDefault d
+ def -(key: A): Map[A, B1] = Map.this - key withDefault d
+ override def default(key: A): B1 = d(key)
+ }
+
+ /** The same map with a given default value */
+ def withDefaultValue[B1 >: B](d: B1): Map[A, B1] = withDefault(x => d)
+
/** This function transforms all the values of mappings contained
* in this map with function <code>f</code>.
*