summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2005-03-22 15:26:54 +0000
committerMartin Odersky <odersky@gmail.com>2005-03-22 15:26:54 +0000
commit9e67e8eb2a4480d2761d2e08a87cea6b32a71fbb (patch)
treee71a2f25b3dd0072fa0db11c6e2e1282d4cfa97f
parent7179a093ef8f5c46941f6440704389316416b7f5 (diff)
downloadscala-9e67e8eb2a4480d2761d2e08a87cea6b32a71fbb.tar.gz
scala-9e67e8eb2a4480d2761d2e08a87cea6b32a71fbb.tar.bz2
scala-9e67e8eb2a4480d2761d2e08a87cea6b32a71fbb.zip
*** empty log message ***
-rw-r--r--sources/scala/List.scala2
-rwxr-xr-xsources/scala/tools/nsc/Global.scala6
-rw-r--r--sources/scala/tools/nsc/Phase.scala4
-rwxr-xr-xsources/scala/tools/nsc/ast/TreeGen.scala101
-rw-r--r--sources/scala/tools/nsc/ast/Trees.scala2
-rwxr-xr-xsources/scala/tools/nsc/ast/parser/Syntactic.scala154
-rwxr-xr-xsources/scala/tools/nsc/symtab/Definitions.scala8
-rw-r--r--sources/scala/tools/nsc/symtab/Flags.scala12
-rwxr-xr-xsources/scala/tools/nsc/symtab/Names.scala4
-rwxr-xr-xsources/scala/tools/nsc/symtab/StdNames.scala2
-rwxr-xr-xsources/scala/tools/nsc/symtab/SymbolLoaders.scala24
-rwxr-xr-xsources/scala/tools/nsc/symtab/Symbols.scala119
-rwxr-xr-xsources/scala/tools/nsc/symtab/Types.scala89
-rwxr-xr-xsources/scala/tools/nsc/symtab/classfile/ClassfileParser.scala11
-rwxr-xr-xsources/scala/tools/nsc/symtab/classfile/MetaParser.scala3
-rwxr-xr-xsources/scala/tools/nsc/typechecker/Contexts.scala15
-rwxr-xr-xsources/scala/tools/nsc/typechecker/Namers.scala36
-rwxr-xr-xsources/scala/tools/nsc/typechecker/TypeCheckers.scala276
-rwxr-xr-xsources/scala/tools/nsc/typechecker/Typers.scala37
-rwxr-xr-xsources/scala/tools/scalac/typechecker/RefCheck.scala26
-rw-r--r--test/files/pos/List1.scala6
-rw-r--r--test/files/pos/abstract.scala4
-rw-r--r--test/files/pos/arrays2.scala4
-rw-r--r--test/files/pos/bug115.scala5
24 files changed, 581 insertions, 369 deletions
diff --git a/sources/scala/List.scala b/sources/scala/List.scala
index 0563f49998..e4a109852d 100644
--- a/sources/scala/List.scala
+++ b/sources/scala/List.scala
@@ -748,7 +748,7 @@ sealed trait List[+a] extends Seq[a] {
def flatMap[b](f: a => List[b]): List[b] = match {
case Nil => Nil
case head :: tail => f(head) ::: (tail flatMap f)
- };
+ }
/** Reverses the elements of this list.
* <p/>
diff --git a/sources/scala/tools/nsc/Global.scala b/sources/scala/tools/nsc/Global.scala
index 36b250fbc3..aba47f7d89 100755
--- a/sources/scala/tools/nsc/Global.scala
+++ b/sources/scala/tools/nsc/Global.scala
@@ -11,7 +11,7 @@ import scala.tools.util._;
import scala.collection.mutable.{HashSet,HashMap,ListBuffer}
import symtab._;
-import symtab.pickles.{PickleBuffer, Pickles};
+import symtab.classfile.{PickleBuffer, Pickler};
import util._;
import ast._;
import ast.parser._;
@@ -38,7 +38,7 @@ class Global(val settings: Settings, val reporter: Reporter) extends SymbolTable
val global: Global.this.type = Global.this
}
- object pickles extends Pickles {
+ object pickler extends Pickler {
val global: Global.this.type = Global.this
}
@@ -132,7 +132,7 @@ class Global(val settings: Settings, val reporter: Reporter) extends SymbolTable
}
val namerPhase = new analyzer.NamerPhase(parserPhase);
val typeCheckPhase = new analyzer.TypeCheckPhase(namerPhase);
- val picklePhase = new pickles.PicklePhase(typeCheckPhase);
+ val picklePhase = new pickler.PicklePhase(typeCheckPhase);
val terminalPhase = new StdPhase(picklePhase) {
def name = "terminal";
diff --git a/sources/scala/tools/nsc/Phase.scala b/sources/scala/tools/nsc/Phase.scala
index e4c8bf3f0e..1bb14483ac 100644
--- a/sources/scala/tools/nsc/Phase.scala
+++ b/sources/scala/tools/nsc/Phase.scala
@@ -5,8 +5,6 @@
// $Id$
package scala.tools.nsc;
-import symtab.Flags.INITIALFLAGS;
-
abstract class Phase(val prev: Phase) {
val id: int = if (prev == null) 0 else prev.id + 1;
@@ -17,8 +15,6 @@ abstract class Phase(val prev: Phase) {
def name: String;
def description: String = name;
-
- val flagMask: long = if (prev == null) INITIALFLAGS else prev.flagMask;
def exactMatch: boolean = false;
def run: unit;
diff --git a/sources/scala/tools/nsc/ast/TreeGen.scala b/sources/scala/tools/nsc/ast/TreeGen.scala
index 523bf74b78..f152bb2f2e 100755
--- a/sources/scala/tools/nsc/ast/TreeGen.scala
+++ b/sources/scala/tools/nsc/ast/TreeGen.scala
@@ -6,14 +6,111 @@
package scala.tools.nsc.ast;
import scala.tools.util.Position;
+import symtab.Flags._;
abstract class TreeGen {
val global: Global;
import global._;
+ import definitions._;
+ import posAssigner.atPos;
- def mkGlobalRef(sym: Symbol): Tree = Ident(sym.name) setSymbol sym setType sym.tpe;
+ /** Builds a reference to value whose type is given stable prefix.
+ */
+ def mkQualifier(stable: Type): Tree = stable match {
+ case NoPrefix =>
+ EmptyTree
+ case ThisType(clazz) =>
+ if (clazz.isRoot || clazz.isEmptyPackageClass) EmptyTree else This(clazz)
+ case SingleType(pre, sym) =>
+ val qual = mkStableRef(pre, sym);
+ qual.tpe match {
+ case MethodType(params, _) =>
+ assert(params.isEmpty, qual.tpe);
+ Apply(qual, List());
+ case _ =>
+ qual
+ }
+ }
- def This(sym: Symbol): Tree = global.This(sym.name) setSymbol sym setType sym.thisType;
+ /** Builds a reference to given symbol with given stable prefix. */
+ def mkRef(pre: Type, sym: Symbol): Tree = {
+ val qual = mkQualifier(pre);
+ if (qual == EmptyTree) Ident(sym) else Select(qual, sym)
+ }
+
+ /** Builds a reference to given symbol. */
+ def mkRef(sym: Symbol): Tree = mkRef(sym.owner.thisType, sym);
+
+ /** Replacecs tree type with a stable type if possible */
+ def stabilize(tree: Tree): Tree = tree match {
+ case Ident(_) =>
+ if (tree.symbol.isStable) tree.setType(singleType(NoPrefix, tree.symbol))
+ else tree
+ case Select(qual, _) =>
+ if (tree.symbol.isStable && qual.tpe.isStable) tree.setType(singleType(qual.tpe, tree.symbol))
+ else tree
+ case _ =>
+ tree
+ }
+
+ /** Builds a reference with stable type to given symbol */
+ def mkStableRef(pre: Type, sym: Symbol): Tree = stabilize(mkRef(pre, sym));
+ def mkStableRef(sym: Symbol): Tree = stabilize(mkRef(sym));
+
+ def TypeTree(tp: Type) = global.TypeTree() setType tp;
+
+ def This(sym: Symbol) =
+ global.This(sym.name) setSymbol sym setType sym.thisType;
+
+ def Ident(sym: Symbol) = {
+ assert(sym.isTerm);
+ sym.setFlag(ACCESSED);
+ global.Ident(sym.name) setSymbol sym setType sym.tpe;
+ }
+
+ def Select(qual: Tree, sym: Symbol) = {
+ assert(sym.isTerm);
+ sym.setFlag(ACCESSED);
+ global.Select(qual, sym.name) setSymbol sym setType qual.tpe.memberType(sym);
+ }
+
+ def Apply(fun: Tree, args: List[Tree]) = fun.tpe match {
+ case MethodType(formals, restpe) =>
+ global.Apply(fun, args) setType restpe
+ }
+
+ def Assign(lhs: Tree, rhs: Tree) =
+ global.Assign(lhs, rhs) setType UnitClass.tpe;
+
+ def ValDef(sym: Symbol, rhs: Tree): ValDef = atPos(sym.pos) {
+ global.ValDef(flags2mods(sym.flags), sym.name, TypeTree(sym.tpe), rhs)
+ }
+ def ValDef(sym: Symbol): ValDef = ValDef(sym, EmptyTree);
+
+ def AbsTypeDef(sym: Symbol) =
+ global.AbsTypeDef(flags2mods(sym.flags), sym.name,
+ TypeTree(sym.info.bounds.lo), TypeTree(sym.info.bounds.hi));
+
+ def DefDef(sym: Symbol, rhs: List[List[Symbol]] => Tree) = atPos(sym.pos) {
+ var cnt = 0;
+ def freshName = { cnt = cnt + 1; newTermName("x$" + cnt) }
+ def mk(tparams: List[Symbol], vparamss: List[List[Symbol]], tpe: Type): DefDef = tpe match {
+ case PolyType(tparams, restpe) =>
+ mk(tparams, List(), restpe)
+ case MethodType(formals, restpe) =>
+ val vparams: List[Symbol] = formals map sym.newValueParameter(sym.pos, freshName).setInfo;
+ mk(tparams, vparamss ::: List(vparams), restpe)
+ case _ =>
+ global.DefDef(
+ flags2mods(sym.flags),
+ sym.name,
+ tparams.map(AbsTypeDef),
+ vparamss.map(.map(ValDef)),
+ TypeTree(tpe),
+ rhs(vparamss))
+ }
+ mk(List(), List(), sym.tpe)
+ }
}
diff --git a/sources/scala/tools/nsc/ast/Trees.scala b/sources/scala/tools/nsc/ast/Trees.scala
index 7e314683be..1a1f64a872 100644
--- a/sources/scala/tools/nsc/ast/Trees.scala
+++ b/sources/scala/tools/nsc/ast/Trees.scala
@@ -220,7 +220,7 @@ class Trees: Global {
/** General type term, introduced by RefCheck. */
case class TypeTree() extends TypTree {
- override def isEmpty = tpe == null;
+ override def isEmpty = tpe == null || tpe == NoType;
}
/** Singleton type, eliminated by RefCheck */
diff --git a/sources/scala/tools/nsc/ast/parser/Syntactic.scala b/sources/scala/tools/nsc/ast/parser/Syntactic.scala
index ac369fa790..479e0a65d6 100755
--- a/sources/scala/tools/nsc/ast/parser/Syntactic.scala
+++ b/sources/scala/tools/nsc/ast/parser/Syntactic.scala
@@ -1283,15 +1283,15 @@ abstract class Syntactic: ParserPhase {
false
}
- /** Def ::= val PatDef
- * | var VarDef
- * | def FunDef
- * | type TypeDef
+ /** Def ::= val PatDef {`,' PatDef}
+ * | var VarDef {`,' VatDef}
+ * | def FunDef {`,' FunDef}
+ * | type TypeDef {`,' TypeDef}
* | TmplDef
- * Dcl ::= val ValDcl
- * | var ValDcl
- * | def FunDcl
- * | type TypeDcl
+ * Dcl ::= val ValDcl {`,' ValDcl}
+ * | var ValDcl {`,' ValDcl}
+ * | def FunDcl {`,' FunDcl}
+ * | type TypeDcl {`,' TypeDcl}
*/
def defOrDcl(mods: int): List[Tree] = {
in.token match {
@@ -1300,12 +1300,12 @@ abstract class Syntactic: ParserPhase {
case VAR =>
varDefOrDcl(mods);
case DEF =>
- funDefOrDcl(mods);
+ List(funDefOrDcl(mods));
case TYPE =>
in.nextToken();
List(typeDefOrDcl(mods))
case _ =>
- tmplDef(mods)
+ List(tmplDef(mods))
}
}
@@ -1367,43 +1367,33 @@ abstract class Syntactic: ParserPhase {
atPos(pos) { ValDef(newmods, name, tp.duplicate, rhs.duplicate) }
}
- /** FunDef ::= FunSig {`,' FunSig} `:' Type `=' Expr
+ /** FunDef ::= FunSig `:' Type `=' Expr
* | this ParamClause `=' ConstrExpr
- * FunDcl ::= FunSig {`,' FunSig} `:' Type
+ * FunDcl ::= FunSig `:' Type
* FunSig ::= id [FunTypeParamClause] ParamClauses
*/
- def funDefOrDcl(mods: int): List[Tree] = {
- in.nextToken();
- if (in.token == THIS)
- List(
- atPos(in.skipToken()) {
- val vparams = List(paramClause(false));
- accept(EQUALS);
- DefDef(
- mods, nme.CONSTRUCTOR, List(), vparams, TypeTree(), constrExpr())
- })
- else {
- var newmods = mods;
- val lhs = new ListBuffer[Tuple4[Int, Name, List[AbsTypeDef], List[List[ValDef]]]]
- + Tuple4(
- in.pos, ident(), typeParamClauseOpt(false), paramClauses(false));
- while (in.token == COMMA)
- lhs += Tuple4(
- in.skipToken(), ident(), typeParamClauseOpt(false), paramClauses(false));
- val restype = typedOpt();
- val rhs =
- if (restype == EmptyTree || in.token == EQUALS) equalsExpr();
- else {
- newmods = newmods | Flags.DEFERRED;
- EmptyTree
- }
- for (val Tuple4(pos, name, tparams, vparams) <- lhs.toList) yield
- atPos(pos) {
- DefDef(newmods, name, tparams, vparams,
- restype.duplicate, rhs.duplicate)
- }
+ def funDefOrDcl(mods: int): Tree =
+ atPos(in.skipToken()) {
+ if (in.token == THIS) {
+ in.nextToken();
+ val vparams = List(paramClause(false));
+ accept(EQUALS);
+ DefDef(mods, nme.CONSTRUCTOR, List(), vparams, TypeTree(), constrExpr())
+ } else {
+ var newmods = mods;
+ val name = ident();
+ val tparams = typeParamClauseOpt(false);
+ val vparamss = paramClauses(false);
+ val restype = typedOpt();
+ val rhs =
+ if (restype == EmptyTree || in.token == EQUALS) equalsExpr();
+ else {
+ newmods = newmods | Flags.DEFERRED;
+ EmptyTree
+ }
+ DefDef(newmods, name, tparams, vparamss, restype, rhs)
+ }
}
- }
/** ConstrExpr ::= SelfInvocation
* | `{' SelfInvocation {`;' BlockStat} `}'
@@ -1452,9 +1442,9 @@ abstract class Syntactic: ParserPhase {
/** TmplDef ::= ([case] class | trait) ClassDef
* | [case] object ObjectDef
*/
- def tmplDef(mods: int): List[Tree] = in.token match {
+ def tmplDef(mods: int): Tree = in.token match {
case TRAIT =>
- classDef(mods | Flags.TRAIT | Flags.ABSTRACT);
+ classDef(mods | Flags.ABSTRACT);
case CLASS =>
classDef(mods);
case CASECLASS =>
@@ -1465,48 +1455,36 @@ abstract class Syntactic: ParserPhase {
objectDef(mods | Flags.CASE);
case _ =>
syntaxError("illegal start of definition", true);
- List()
+ EmptyTree
}
- /** ClassDef ::= ClassSig {`,' ClassSig} [`:' SimpleType] ClassTemplate
+ /** ClassDef ::= ClassSig [`:' SimpleType] ClassTemplate
* ClassSig ::= Id [TypeParamClause] [ClassParamClause]
*/
- def classDef(mods: int): List[Tree] = {
- val lhs = new ListBuffer[Tuple4[Int, Name, List[AbsTypeDef], List[List[ValDef]]]];
- do {
- lhs += Tuple4(in.skipToken(),
- ident().toTypeName,
- typeParamClauseOpt(true),
- if ((mods & Flags.TRAIT) != 0) List() else paramClauses(true))
- } while (in.token == COMMA);
- val thistpe = simpleTypedOpt();
- val template = classTemplate(mods);
- for (val Tuple4(pos, name, tparams, vparamss) <- lhs.toList) yield
- atPos(pos) {
- val template1 = if ((mods & Flags.TRAIT) != 0) template
- else addConstructor(mods, vparamss, template);
- ClassDef(mods, name, tparams, thistpe.duplicate, template1.duplicate.asInstanceOf[Template])
- }
- }
+ def classDef(mods: int): Tree =
+ atPos(in.skipToken()) {
+ val name = ident().toTypeName;
+ val tparams = typeParamClauseOpt(true);
+ if ((mods & Flags.CASE) != 0 && in.token != LPAREN) accept(LPAREN);
+ val vparamss = paramClauses(true);
+ val thistpe = simpleTypedOpt();
+ val mods1 = if (vparamss.isEmpty && (mods & ABSTRACT) != 0) mods | Flags.TRAIT else mods;
+ val template = classTemplate(mods1, vparamss);
+ ClassDef(mods1, name, tparams, thistpe, template)
+ }
- /** ObjectDef ::= Id { , Id } ClassTemplate
+ /** ObjectDef ::= 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 template = classTemplate(mods);
- for (val Pair(pos, name) <- lhs.toList) yield
- atPos(pos) {
- val template1 = addConstructor(mods, List(), template);
- ModuleDef(mods, name, template1.duplicate.asInstanceOf[Template])
- }
- }
+ def objectDef(mods: int): Tree =
+ atPos(in.skipToken()) {
+ val name = ident();
+ val template = classTemplate(mods, List());
+ ModuleDef(mods, name, template)
+ }
- /** ClassTemplate ::= [`extends' SimpleType [`(' [Exprs] `)']] {`with' SimpleType} [TemplateBody]
+ /** ClassTemplate ::= [`extends' TemplateParents] [TemplateBody]
*/
- def classTemplate(mods: int): Template =
+ def classTemplate(mods: int, vparamss: List[List[ValDef]]): Template =
atPos(in.pos) {
val parents = new ListBuffer[Tree];
var args: List[Tree] = List();
@@ -1514,14 +1492,13 @@ abstract class Syntactic: ParserPhase {
in.nextToken();
parents += simpleType();
if (in.token == LPAREN) args = argumentExprs();
- } else {
- parents += scalaAnyRefConstr
+ while (in.token == WITH) {
+ in.nextToken();
+ parents += simpleType()
+ }
}
- parents += scalaScalaObjectConstr;
+ parents += scalaScalaObjectConstr;
if ((mods & Flags.CASE)!= 0) parents += caseClassConstr;
- while (in.token == WITH) {
- in.nextToken(); parents += simpleType();
- }
val ps = parents.toList;
var body =
if (in.token == LBRACE) {
@@ -1531,7 +1508,8 @@ abstract class Syntactic: ParserPhase {
syntaxError("`extends' or `{' expected", true);
List()
}
- if ((mods & Flags.TRAIT) == 0) body = makeSuperCall(args) :: body;
+ if ((mods & Flags.TRAIT) == 0)
+ body = makeConstructorPart(mods, vparamss, args) ::: body;
Template(ps, body)
}
@@ -1591,7 +1569,7 @@ abstract class Syntactic: ParserPhase {
in.token == LBRACKET ||
isModifier) {
stats ++
- joinAttributes(attributeClauses(), joinComment(tmplDef(modifiers())))
+ joinAttributes(attributeClauses(), joinComment(List(tmplDef(modifiers()))))
} else if (in.token != SEMI) {
syntaxError("illegal start of class or object definition", true);
}
@@ -1696,7 +1674,7 @@ abstract class Syntactic: ParserPhase {
stats += Literal(()).setPos(in.pos)
}
} else if (isLocalModifier) {
- stats ++= tmplDef(localClassModifiers());
+ stats += tmplDef(localClassModifiers());
accept(SEMI);
if (in.token == RBRACE || in.token == CASE) {
stats += Literal(()).setPos(in.pos)
diff --git a/sources/scala/tools/nsc/symtab/Definitions.scala b/sources/scala/tools/nsc/symtab/Definitions.scala
index c3a3254cc9..c9561c5e30 100755
--- a/sources/scala/tools/nsc/symtab/Definitions.scala
+++ b/sources/scala/tools/nsc/symtab/Definitions.scala
@@ -133,7 +133,7 @@ abstract class Definitions: SymbolTable {
}
private def newMethod(owner: Symbol, name: Name): Symbol = {
- val msym = owner.newMethod(Position.NOPOS, name);
+ val msym = owner.newMethod(Position.NOPOS, name.encode);
owner.info.decls.enter(msym);
msym
}
@@ -145,13 +145,15 @@ abstract class Definitions: SymbolTable {
def init = {
RootClass =
NoSymbol.newClass(Position.NOPOS, nme.ROOT.toTypeName)
- .setFlag(FINAL | PACKAGE | JAVA).setInfo(rootLoader);
+ .setFlag(FINAL | MODULE | PACKAGE | JAVA).setInfo(rootLoader);
EmptyPackage =
RootClass.newPackage(Position.NOPOS, nme.EMPTY_PACKAGE_NAME).setFlag(FINAL);
EmptyPackageClass = EmptyPackage.moduleClass;
EmptyPackageClass.setInfo(ClassInfoType(List(), new Scope(), EmptyPackageClass));
- EmptyPackage.setInfo(EmptyPackageClass.typeConstructor);
+
+
+ EmptyPackage.setInfo(EmptyPackageClass.tpe);
RootClass.info.decls.enter(EmptyPackage);
JavaPackage = getModule("java");
diff --git a/sources/scala/tools/nsc/symtab/Flags.scala b/sources/scala/tools/nsc/symtab/Flags.scala
index fcaae4e8cf..776adab42e 100644
--- a/sources/scala/tools/nsc/symtab/Flags.scala
+++ b/sources/scala/tools/nsc/symtab/Flags.scala
@@ -63,11 +63,12 @@ object Flags {
val TRANS_FLAG = 0x800000000l; // 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 INITIALFLAGS = 0x777777777l;
// masks
val SOURCEFLAGS = 0x00077777; // these modifiers can be set in source programs.
- val EXPLICITFLAGS = // these modifiers can be explcitly in source programs.
+ val GENFLAGS = // these modifiers can be in generated trees
+ SOURCEFLAGS | SYNTHETIC | STABLE | ACCESSOR | ACCESS_METHOD | PARAMACCESSOR | LABEL | BRIDGE;
+ val EXPLICITFLAGS = // these modifiers can be set explicitly in source programs.
PRIVATE | PROTECTED | ABSTRACT | FINAL | SEALED | OVERRIDE | CASE;
val ACCESSFLAGS = PRIVATE | PROTECTED;
@@ -75,14 +76,11 @@ object Flags {
val CONSTRFLAGS = JAVA;
val PICKLEDFLAGS = 0x77777777 & ~LOCKED & ~INITIALIZED;
- /** Flags already set by object creation and never set afterwards */
- val CREATIONFLAGS = ACCESSFLAGS | METHOD | MODULE | MUTABLE | PARAM | PACKAGE |
- COVARIANT | CONTRAVARIANT | SYNTHETIC | STABLE | ACCESSOR | PARAMACCESSOR | LOCAL |
- IS_ERROR | OVERLOADED | INCONSTRUCTOR;
-
/** Module flags inherited by their module-class */
val MODULE2CLASSFLAGS = ACCESSFLAGS | PACKAGE;
+ def flags2mods(flags: long): int = flags.asInstanceOf[int] & GENFLAGS;
+
def flagsToString(flags: long): String =
List.range(0, 63)
.map(i => flagToString(flags & (1L << i)))
diff --git a/sources/scala/tools/nsc/symtab/Names.scala b/sources/scala/tools/nsc/symtab/Names.scala
index d5a51fc66d..ed9aad85fd 100755
--- a/sources/scala/tools/nsc/symtab/Names.scala
+++ b/sources/scala/tools/nsc/symtab/Names.scala
@@ -254,8 +254,8 @@ class Names {
val str = toString();
val res = NameTransformer.encode(str);
if (res == str) this
- else if (isTypeName) newTypeName(str)
- else newTermName(str)
+ else if (isTypeName) newTypeName(res)
+ else newTermName(res)
}
/** Replace $op_name by corresponding operator symbol */
diff --git a/sources/scala/tools/nsc/symtab/StdNames.scala b/sources/scala/tools/nsc/symtab/StdNames.scala
index 52f09275fc..2c3603dbaa 100755
--- a/sources/scala/tools/nsc/symtab/StdNames.scala
+++ b/sources/scala/tools/nsc/symtab/StdNames.scala
@@ -25,6 +25,8 @@ abstract class StdNames: SymbolTable {
def TUPLE_FIELD(index: int) = newTermName(TUPLE_FIELD_PREFIX_STRING + index);
+ def SETTER_NAME(name: Name) = encode(name.toString() + "_=");
+
val ERROR = newTermName("<error>");
val ERRORtype = newTypeName("<error>");
diff --git a/sources/scala/tools/nsc/symtab/SymbolLoaders.scala b/sources/scala/tools/nsc/symtab/SymbolLoaders.scala
index b441231bd4..7e69107d45 100755
--- a/sources/scala/tools/nsc/symtab/SymbolLoaders.scala
+++ b/sources/scala/tools/nsc/symtab/SymbolLoaders.scala
@@ -9,7 +9,7 @@ import java.io.IOException;
import scala.tools.util.{AbstractFile, Position}
import scala.tools.nsc.util.NameTransformer;
import scala.collection.mutable.HashMap;
-import classfile.ClassfileParser;
+import classfile.{ClassfileParser, SymblfileParser};
import Flags._;
@@ -80,12 +80,11 @@ abstract class SymbolLoaders {
module.moduleClass.setInfo(errorLoader);
owner.info.decls.enter(clazz);
owner.info.decls.enter(module);
- assert(clazz.linkedModule == module);
+ assert(clazz.linkedModule == module, "" + module + module.hasFlag(MODULE));
assert(module.linkedClass == clazz);
}
val sources = new HashMap[String, AbstractFile];
- val symbols = new HashMap[String, AbstractFile];
val classes = new HashMap[String, AbstractFile];
val packages = new HashMap[String, AbstractFile];
val it = directory.list();
@@ -96,8 +95,8 @@ abstract class SymbolLoaders {
if (filename != "META_INF" && !packages.isDefinedAt(filename)) packages(filename) = file;
} else if (filename.endsWith(".symbl")) {
val name = filename.substring(0, filename.length() - 6);
- if (!symbols.isDefinedAt(name) ||
- symbols(name).getName().endsWith(".class")) symbols(name) = file;
+ if (!classes.isDefinedAt(name) ||
+ classes(name).getName().endsWith(".class")) classes(name) = file;
} else if (filename.endsWith(".class")) {
val name = filename.substring(0, filename.length() - 6);
if (!classes.isDefinedAt(name)) classes(name) = file;
@@ -115,7 +114,10 @@ abstract class SymbolLoaders {
for (val Pair(name, cfile) <- classes.elements) {
sources.get(name) match {
case Some(sfile) if (sfile.lastModified() > cfile.lastModified()) => {}
- case _ => enterClassAndModule(name, classfileLoader(cfile));
+ case _ =>
+ val loader = if (cfile.getName().endsWith(".symbl")) symblfileLoader(cfile)
+ else classfileLoader(cfile);
+ enterClassAndModule(name, loader)
}
}
for (val Pair(name, file) <- packages.elements) {
@@ -130,12 +132,22 @@ abstract class SymbolLoaders {
val global: SymbolLoaders.this.global.type = SymbolLoaders.this.global;
}
+ private object symblfileParser extends SymblfileParser {
+ val global: SymbolLoaders.this.global.type = SymbolLoaders.this.global;
+ }
+
def classfileLoader(file: AbstractFile) =
new SymbolLoader(root => {
classfileParser.parse(file, root);
"class file '" + file + "'";
});
+ def symblfileLoader(file: AbstractFile) =
+ new SymbolLoader(root => {
+ symblfileParser.parse(file, root);
+ "symbl file '" + file + "'";
+ });
+
def sourcefileLoader(file: AbstractFile) =
new SymbolLoader(root => {
global.compileLate(file);
diff --git a/sources/scala/tools/nsc/symtab/Symbols.scala b/sources/scala/tools/nsc/symtab/Symbols.scala
index e7eeaa92c2..7d87f7e552 100755
--- a/sources/scala/tools/nsc/symtab/Symbols.scala
+++ b/sources/scala/tools/nsc/symtab/Symbols.scala
@@ -22,7 +22,7 @@ abstract class Symbols: SymbolTable {
var name = initName;
var pos = initPos;
val id = { ids = ids + 1; ids }
- var rawflags: long = 0;
+ private var rawflags: long = 0;
// Creators -------------------------------------------------------------------
@@ -51,8 +51,9 @@ abstract class Symbols: SymbolTable {
m.moduleClass.setFlag(JAVA | PACKAGE);
m
}
- final def newThisSym(pos: int) =
+ final def newThisSym(pos: int) = {
newValue(pos, nme.this_).setFlag(SYNTHETIC);
+ }
final def newImport(pos: int) =
newValue(pos, nme.IMPORT).setFlag(SYNTHETIC);
final def newOverloaded(pre: Type, alternatives: List[Symbol]): Symbol =
@@ -88,33 +89,33 @@ abstract class Symbols: SymbolTable {
def isType = false; //to be overridden
def isClass = false; //to be overridden
- 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 isValue = isTerm && !(isModule && hasFlag(PACKAGE | JAVA));
+ final def isVariable = isTerm && hasFlag(MUTABLE);
+ final def isGetter = isTerm && hasFlag(ACCESSOR) && !name.endsWith(nme._EQ);
+ final def isSetter = isTerm && hasFlag(ACCESSOR) && name.endsWith(nme._EQ);
+ final def isValueParameter = isTerm && hasFlag(PARAM);
final def isLocalDummy = isTerm && (name startsWith nme.LOCAL_PREFIX);
- final def isMethod = isTerm && (rawflags & (METHOD | STABLE)) == METHOD;
- final def isLabel = isTerm && (rawflags & LABEL) != 0;
+ final def isMethod = isTerm && (flags & (METHOD | STABLE)) == METHOD;
+ final def isLabel = isTerm && hasFlag(LABEL);
final def isConstructor = isTerm && name == nme.CONSTRUCTOR;
- final def isModule = isTerm && (rawflags & MODULE) != 0;
- final def isPackage = isModule && (rawflags & PACKAGE) != 0;
+ final def isModule = isTerm && hasFlag(MODULE);
+ final def isPackage = isModule && hasFlag(PACKAGE);
final def isThisSym = isTerm && name == nme.this_;
- final def isError = (rawflags & IS_ERROR) != 0;
- final def isAliasType = isType && !isClass && (rawflags & DEFERRED) == 0;
- final def isAbstractType = isType && !isClass && (rawflags & DEFERRED) != 0;
- final def isTypeParameter = isType && (rawflags & PARAM) != 0;
+ final def isError = hasFlag(IS_ERROR);
+ final def isTrait = isClass & hasFlag(TRAIT);
+ final def isAliasType = isType && !isClass && !hasFlag(DEFERRED);
+ final def isAbstractType = isType && !isClass && hasFlag(DEFERRED);
+ final def isTypeParameter = isType && hasFlag(PARAM);
final def isAnonymousClass = isClass && (name startsWith nme.ANON_CLASS_NAME); // startsWith necessary because name may grow when lifted
final def isRefinementClass = isClass && name == nme.REFINE_CLASS_NAME; // no lifting for refinement classes
- final def isModuleClass = isClass && (rawflags & MODULE) != 0;
- final def isPackageClass = isClass && (rawflags & PACKAGE) != 0;
+ final def isModuleClass = isClass && hasFlag(MODULE);
+ final def isPackageClass = isClass && hasFlag(PACKAGE);
final def isRoot = isPackageClass && name == nme.ROOT.toTypeName;
final def isEmptyPackageClass = isPackageClass && name == nme.EMPTY_PACKAGE_NAME.toTypeName;
/** Does this symbol denote a stable value? */
final def isStable =
- isTerm && (rawflags & MUTABLE) == 0 &&
- ((rawflags & METHOD) == 0 || (rawflags & STABLE) != 0);
+ isTerm && !hasFlag(MUTABLE) && (!hasFlag(METHOD) || hasFlag(STABLE));
/** Does this symbol denote the primary constructor
* of its enclosing class? */
@@ -155,21 +156,18 @@ abstract class Symbols: SymbolTable {
/** The variance of this symbol as an integer */
final def variance: int =
- if ((rawflags & COVARIANT) != 0) 1
- else if ((rawflags & CONTRAVARIANT) != 0) -1
+ if (hasFlag(COVARIANT)) 1
+ else if (hasFlag(CONTRAVARIANT)) -1
else 0;
// Flags ----------------------------------------------------------------------------
- final def flags = {
- initialize; rawflags & phase.flagMask
- }
+ final def flags = rawflags;
+ final def flags_=(fs: long) = rawflags = fs;
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 getFlag(mask: long): long = rawflags & mask;
+ final def hasFlag(mask: long): boolean = (rawflags & mask) != 0;
final def resetFlags: unit = { rawflags = rawflags & SOURCEFLAGS }
// Info and Type -------------------------------------------------------------------
@@ -200,8 +198,8 @@ abstract class Symbols: SymbolTable {
phase = infos.start;
//System.out.println("completing " + this);//DEBUG
tp.complete(this);
- phase = current;
rawflags = rawflags & ~LOCKED;
+ phase = current;
cnt = cnt + 1;
// allow for two completions:
// one: sourceCompleter to LazyType, two: LazyType to completed type
@@ -215,10 +213,10 @@ abstract class Symbols: SymbolTable {
infos = new TypeHistory(phase, info, null);
limit = phase;
assert(info != null, "setInfo(null) for " + name + " at phase " + phase);//debug
- rawflags = if (info.isComplete) rawflags | INITIALIZED
- else rawflags & ~INITIALIZED;
+ rawflags = if (info.isComplete) rawflags | INITIALIZED & ~LOCKED;
+ else rawflags & ~INITIALIZED & ~LOCKED;
if (info.isInstanceOf[MethodType] || info.isInstanceOf[PolyType])
- assert(isClass || (rawflags & METHOD) != 0);
+ assert(isClass || hasFlag(METHOD));
this
}
@@ -351,7 +349,7 @@ abstract class Symbols: SymbolTable {
/** A clone of this symbol, but with given owner */
final def cloneSymbol(owner: Symbol): Symbol =
- cloneSymbolImpl(owner).setInfo(info.cloneInfo(owner)).setFlag(rawflags);
+ cloneSymbolImpl(owner).setInfo(info.cloneInfo(owner)).setFlag(flags);
/** Internal method to clone a symbol's implementation without flags or type
*/
@@ -390,7 +388,7 @@ abstract class Symbols: SymbolTable {
/** The symbol accessed by this accessor function.
*/
final def accessed: Symbol = {
- assert((rawflags & ACCESSOR) != 0);
+ assert(hasFlag(ACCESSOR));
val name1 = if (name.endsWith(nme._EQ)) name.subName(0, name.length - nme._EQ.length)
else name;
owner.info.decl(name1.toString() + "$")
@@ -423,7 +421,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.
*/
@@ -450,10 +448,9 @@ abstract class Symbols: SymbolTable {
/** String representation of symbol's definition key word */
final def keyString: String =
- if (isClass)
- if ((rawflags & TRAIT) != 0)
- if ((rawflags & JAVA) != 0) "interface" else "trait"
- else "class"
+ if (isTrait)
+ if (hasFlag(JAVA)) "interface" else "trait"
+ else if (isClass) "class"
else if (isType && !hasFlag(PARAM)) "type"
else if (isVariable) "var"
else if (isPackage) "package"
@@ -469,8 +466,8 @@ abstract class Symbols: SymbolTable {
else if (isAnonymousClass) "<template>"
else if (isRefinementClass) ""
else if (isModuleClass) "singleton class"
- else if (isClass)
- if ((rawflags & TRAIT) != 0) "trait" else "class"
+ else if (isTrait) "trait"
+ else if (isClass) "class"
else if (isType) "type"
else if (isVariable) "variable"
else if (isPackage) "package"
@@ -557,7 +554,7 @@ abstract class Symbols: SymbolTable {
/** String representation of symbol's definition */
final def defString: String =
- compose(List(flagsToString(rawflags & EXPLICITFLAGS),
+ compose(List(flagsToString(flags & EXPLICITFLAGS),
keyString,
varianceString + nameString,
infoString(rawInfo)));
@@ -593,17 +590,27 @@ abstract class Symbols: SymbolTable {
private var tpeCache: Type = _;
private var valid: Phase = null;
override def tpe: Type = {
+ assert(tpeCache != NoType, this);
if (valid != phase) {
valid = phase;
- tpeCache = typeRef(owner.thisType, this, typeParams map (.tpe));
+ tpeCache = NoType;
+ tpeCache = typeRef(if (isTypeParameter) NoPrefix else owner.thisType,
+ this, typeParams map (.tpe));
}
+ assert(tpeCache != null, "" + this + " " + phase);
tpeCache
}
override def typeConstructor: Type = {
if (tyconCache == null)
- tyconCache = typeRef(owner.thisType, this, List());
+ tyconCache = typeRef(if (isTypeParameter) NoPrefix else owner.thisType,
+ this, List());
tyconCache;
}
+ override def setInfo(tp: Type): this.type = {
+ valid = null;
+ tyconCache = null;
+ super.setInfo(tp)
+ }
override def reset(completer: Type): unit = {
super.reset(completer);
valid = null;
@@ -624,8 +631,19 @@ abstract class Symbols: SymbolTable {
thissym = this;
}
+ private var thisTypeCache: Type = null;
+
/** the type this.type in this class */
- override val thisType: Type = ThisType(this);
+ override def thisType: Type = {
+ if (thisTypeCache == null) {
+ thisTypeCache =
+ if (isModuleClass && !isRoot) {
+ assert(sourceModule != NoSymbol);
+ singleType(owner.thisType, sourceModule);
+ } else ThisType(this);
+ }
+ thisTypeCache
+ }
/** A symbol carrying the self type of the class as its type */
override def thisSym: Symbol = thissym;
@@ -640,13 +658,16 @@ abstract class Symbols: SymbolTable {
if (thisSym != this) clone.typeOfThis = typeOfThis;
clone
}
+
+ override def sourceModule = if (isModuleClass) owner.linkedModule else NoSymbol;
}
- /** A class for module class symbols */
- class ModuleClassSymbol(module: ModuleSymbol)
- extends ClassSymbol(module.owner, module.pos, module.name.toTypeName) {
+ /** A class for module class symbols
+ * Note: Not all module classes are of this type; when unpickled, we get plain class symbols!
+ */
+ 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 */
diff --git a/sources/scala/tools/nsc/symtab/Types.scala b/sources/scala/tools/nsc/symtab/Types.scala
index 3dfc7651cd..a693da77a5 100755
--- a/sources/scala/tools/nsc/symtab/Types.scala
+++ b/sources/scala/tools/nsc/symtab/Types.scala
@@ -159,8 +159,10 @@ abstract class Types: SymbolTable {
sym.info.asSeenFrom(this, sym.owner);
/** The type of `sym', seen as a member of this type. */
- def memberType(sym: Symbol): Type =
+ def memberType(sym: Symbol): Type = {
+ assert(sym.tpe != null, sym);//debug
sym.tpe.asSeenFrom(this, sym.owner);
+ }
/** Substitute types `to' for occurrences of references to symbols `from'
* in this type. */
@@ -291,7 +293,7 @@ abstract class Types: SymbolTable {
var sym: Symbol = NoSymbol;
var e: ScopeEntry = decls.lookupEntry(name);
while (e != null) {
- if ((e.sym.rawflags & excludedFlags) == 0) {
+ if (!e.sym.hasFlag(excludedFlags)) {
if (sym == NoSymbol) sym = e.sym
else {
if (alts.isEmpty) alts = List(sym);
@@ -315,11 +317,11 @@ abstract class Types: SymbolTable {
var bcs = baseClasses;
while (!bcs.isEmpty) {
val decls = bcs.head.info.decls;
- bcs = bcs.tail;
+ bcs = if (name == nme.CONSTRUCTOR) Nil else bcs.tail;
var entry = if (name == nme.ANYNAME) decls.elems else decls lookupEntry name;
while (entry != null) {
val sym = entry.sym;
- val excl = sym.rawflags & excluded;
+ val excl = sym.getFlag(excluded);
if (excl == 0) {
if (name.isTypeName) {
return sym
@@ -407,6 +409,7 @@ abstract class Types: SymbolTable {
/** A class for this-types of the form <sym>.this.type
*/
case class ThisType(sym: Symbol) extends SingletonType {
+ assert(!sym.isModuleClass || sym.isRoot, sym);
override def symbol = sym;
override def singleDeref: Type = sym.typeOfThis;
override def prefixString =
@@ -585,7 +588,13 @@ abstract class Types: SymbolTable {
override def closure: Array[Type] =
if (sym.isAbstractType) addClosure(this, transform(bounds.hi).closure)
- else transform(sym.info.closure);
+ else {
+ val result = transform(sym.info.closure);
+ System.out.println("closure[" + this + "] = " +
+ List.fromArray(sym.info.closure) + " => " + result);
+ result
+ }
+
override def baseClasses: List[Symbol] = sym.info.baseClasses;
@@ -691,7 +700,7 @@ abstract class Types: SymbolTable {
private def rebind(pre: Type, sym: Symbol): Symbol = {
val owner = sym.owner;
if (owner.isClass && owner != pre.symbol && !sym.isFinal) {
- val rebind = pre.nonPrivateMember(sym.name).suchThat(.isStable);
+ val rebind = pre.nonPrivateMember(sym.name).suchThat(sym => sym.isType || sym.isStable);
if (rebind == NoSymbol) sym else rebind
} else sym
}
@@ -988,9 +997,11 @@ abstract class Types: SymbolTable {
case _ =>
mapOver(tp)
}
- private def register(sym: Symbol) =
- if (result == NoSymbol || (result isNestedIn sym)) result = sym
- else assert(result == sym || (sym isNestedIn result));
+ private def register(sym: Symbol) = {
+ while (result != NoSymbol && sym != result && !(sym isNestedIn result))
+ result = result.owner;
+ result
+ }
}
// Helper Methods -------------------------------------------------------------
@@ -998,21 +1009,22 @@ abstract class Types: SymbolTable {
/** Do tp1 and tp2 denote equivalent types? */
def isSameType(tp1: Type, tp2: Type): boolean = (tp1 eq tp2) || {
Pair(tp1, tp2) match {
- case Pair(ErrorType, _)
- | Pair(WildcardType, _)
- | Pair(_, ErrorType)
- | Pair(_, WildcardType) =>
- true
- case Pair(NoType, _)
- | Pair(NoPrefix, _)
- | Pair(_, NoType)
- | Pair(_, NoPrefix) =>
- false
+ case Pair(ErrorType, _) => true
+ case Pair(WildcardType, _) => true
+ case Pair(_, ErrorType) => true
+ case Pair(_, WildcardType) => true
+
+ case Pair(NoType, _) => false
+ case Pair(NoPrefix, _) => false
+ case Pair(_, NoType) => false
+ case Pair(_, NoPrefix) => false
+
case Pair(ThisType(sym1), ThisType(sym2)) =>
sym1 == sym2
case Pair(SingleType(pre1, sym1), SingleType(pre2, sym2))
if (sym1 == sym2 && pre1 =:= pre2) =>
true
+ /*
case Pair(SingleType(pre1, sym1), ThisType(sym2))
if (sym1.isModule &&
sym1.moduleClass == sym2 &&
@@ -1023,6 +1035,7 @@ abstract class Types: SymbolTable {
sym2.moduleClass == sym1 &&
pre2 =:= sym1.owner.thisType) =>
true
+ */
case Pair(ConstantType(base1, value1), ConstantType(base2, value2)) =>
base1 =:= base2 && value1 == value2
case Pair(TypeRef(pre1, sym1, args1), TypeRef(pre2, sym2, args2)) =>
@@ -1070,22 +1083,22 @@ abstract class Types: SymbolTable {
/** Does tp1 conform to tp2? */
def isSubType(tp1: Type, tp2: Type): boolean = (tp1 eq tp2) || {
Pair(tp1, tp2) match {
- case Pair(ErrorType, _)
- | Pair(WildcardType, _)
- | Pair(_, ErrorType)
- | Pair(_, WildcardType) =>
- true
- case Pair(NoType, _)
- | Pair(NoPrefix, _)
- | Pair(_, NoType)
- | Pair(_, NoPrefix) =>
- false
- case Pair(ThisType(_), ThisType(_))
- | Pair(ThisType(_), SingleType(_, _))
- | Pair(SingleType(_, _), ThisType(_))
- | Pair(SingleType(_, _), SingleType(_, _))
- | Pair(ConstantType(_, _), ConstantType(_, _)) =>
- tp1 =:= tp2
+ case Pair(ErrorType, _) => true
+ case Pair(WildcardType, _) => true
+ case Pair(_, ErrorType) => true
+ case Pair(_, WildcardType) => true
+
+ case Pair(NoType, _) => false
+ case Pair(NoPrefix, _) => false
+ case Pair(_, NoType) => false
+ case Pair(_, NoPrefix) => false
+
+ case Pair(ThisType(_), ThisType(_)) => tp1 =:= tp2
+ case Pair(ThisType(_), SingleType(_, _)) => tp1 =:= tp2
+ case Pair(SingleType(_, _), ThisType(_)) => tp1 =:= tp2
+ case Pair(SingleType(_, _), SingleType(_, _)) => tp1 =:= tp2
+ case Pair(ConstantType(_, _), ConstantType(_, _)) => tp1 =:= tp2
+
case Pair(TypeRef(pre1, sym1, args1), TypeRef(pre2, sym2, args2)) =>
def isSubArgs(tps1: List[Type], tps2: List[Type],
tparams: List[Symbol]): boolean = {
@@ -1105,9 +1118,7 @@ abstract class Types: SymbolTable {
sym2.isAbstractType && (tp1 <:< tp2.bounds.lo)
||
sym2.isClass &&
- ({ val base = tp1 baseType sym2;
- System.out.println("" + tp1 + " baseType " + sym2 + " = " + base);
- !(base eq tp1) && (base <:< tp2) })//debug
+ ({ val base = tp1 baseType sym2; !(base eq tp1) && (base <:< tp2) })//debug
||
sym1 == AllClass
||
@@ -1193,6 +1204,7 @@ abstract class Types: SymbolTable {
/** Prepend type `tp' to closure `cl' */
private def addClosure(tp: Type, cl: Array[Type]): Array[Type] = {
val cl1 = new Array[Type](cl.length + 1);
+ assert(!tp.isInstanceOf[CompoundType], tp);//debug
cl1(0) = tp;
System.arraycopy(cl, 0, cl1, 1, cl.length);
cl1
@@ -1446,6 +1458,7 @@ abstract class Types: SymbolTable {
/** The most deeply nested owner that contains all the symbols
* of thistype or prefixless typerefs/singletype occurrences in given list of types */
private def commonOwner(tps: List[Type]): Symbol = {
+ System.out.println("computing common owner of types " + tps);//debug
commonOwnerMap.init;
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 38cebbe26c..8554452376 100755
--- a/sources/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
+++ b/sources/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
@@ -176,9 +176,12 @@ abstract class ClassfileParser {
private def sigToType(name: Name): Type = {
var index = 0;
val end = name.length;
+ def objToAny(tp: Type): Type =
+ if (tp.symbol == definitions.ObjectClass) definitions.AnyClass.tpe
+ else tp;
def paramsigs2types: List[Type] =
if (name(index) == ')') { index = index + 1; List() }
- else sig2type :: paramsigs2types;
+ else objToAny(sig2type) :: paramsigs2types;
def sig2type: Type = {
val tag = name(index); index = index + 1;
tag match {
@@ -240,6 +243,12 @@ abstract class ClassfileParser {
for (val i <- Iterator.range(0, fieldCount)) parseField();
val methodCount = in.nextChar();
for (val i <- Iterator.range(0, methodCount)) parseMethod();
+ if (instanceDefs.lookup(nme.CONSTRUCTOR) == NoSymbol && (sflags & INTERFACE) == 0) {
+ System.out.println("adding constructor to " + clazz);//debug
+ instanceDefs enter
+ clazz.newConstructor(Position.NOPOS)
+ .setFlag(clazz.flags & CONSTRFLAGS).setInfo(MethodType(List(), clazz.tpe));
+ }
}
}
diff --git a/sources/scala/tools/nsc/symtab/classfile/MetaParser.scala b/sources/scala/tools/nsc/symtab/classfile/MetaParser.scala
index e123de3434..8bfd9709ad 100755
--- a/sources/scala/tools/nsc/symtab/classfile/MetaParser.scala
+++ b/sources/scala/tools/nsc/symtab/classfile/MetaParser.scala
@@ -146,9 +146,10 @@ abstract class MetaParser{
def parse(): Type = {
nextToken();
if (token == "(") MethodType(parseParams(), parse())
- else definitions.UnitClass.tpe
+ else owner.owner.tpe
}
owner.setInfo(parse());
+ System.out.println("constr " + owner + " = " + owner.info);
assert(token == ";")
}
}
diff --git a/sources/scala/tools/nsc/typechecker/Contexts.scala b/sources/scala/tools/nsc/typechecker/Contexts.scala
index 65e8b0925d..afaa1542b3 100755
--- a/sources/scala/tools/nsc/typechecker/Contexts.scala
+++ b/sources/scala/tools/nsc/typechecker/Contexts.scala
@@ -21,8 +21,9 @@ class Contexts: Analyzer {
definitions.RootClass,
definitions.RootClass.info.decls);
def addImport(pkg: Symbol): unit = {
- val impTree = Import(gen.mkGlobalRef(pkg), List(Pair(nme.WILDCARD, null)))
- setSymbol NoSymbol.newImport(Position.NOPOS).setInfo(pkg.tpe)
+ val qual = gen.mkStableRef(pkg);
+ val impTree = Import(qual, List(Pair(nme.WILDCARD, null)))
+ setSymbol NoSymbol.newImport(Position.NOPOS).setInfo(ImportType(qual))
setType NoType;
sc = sc.make(
Template(List(), List(impTree)) setSymbol NoSymbol setType NoType, sc.owner, sc.scope)
@@ -123,7 +124,13 @@ class Contexts: Analyzer {
}
}
- class ImportInfo(val tree: Import, val depth: int) {
+ class ImportInfo(tree: Import, val depth: int) {
+
+ /** The prefix expression */
+ def qual: Tree = tree.symbol.info match {
+ case ImportType(expr) => expr
+ case _ => throw new FatalError("symbol " + tree.symbol + " has bad type: " + tree.symbol.info);//debug
+ }
/** Is name imported explicitly, not via wildcard? */
def isExplicitImport(name: Name): boolean =
@@ -150,6 +157,8 @@ class Contexts: Analyzer {
override def toString() = tree.toString();
}
+
+ case class ImportType(expr: Tree) extends Type;
}
diff --git a/sources/scala/tools/nsc/typechecker/Namers.scala b/sources/scala/tools/nsc/typechecker/Namers.scala
index 693d1db576..7b1ac4f6cc 100755
--- a/sources/scala/tools/nsc/typechecker/Namers.scala
+++ b/sources/scala/tools/nsc/typechecker/Namers.scala
@@ -26,14 +26,14 @@ trait Namers: Analyzer {
private def doubleDefError(pos: int, sym: Symbol): unit =
context.unit.error(pos,
sym.name.toString() + " is already defined as " +
- (if ((sym.rawflags & CASE) != 0) "case class " + sym.name else sym.toString()));
+ (if (sym.hasFlag(CASE)) "case class " + sym.name else sym.toString()));
private def updatePosFlags(sym: Symbol, pos: int, mods: int): Symbol = {
if (settings.debug.value) System.out.println("overwriting " + sym);
sym.pos = pos;
- val oldflags = sym.rawflags & (INITIALIZED | LOCKED);
+ val oldflags = sym.flags & (INITIALIZED | LOCKED);
val newflags = mods & ~(INITIALIZED | LOCKED);
- sym.rawflags = oldflags | newflags;
+ sym.flags = oldflags | newflags;
if (sym.isModule)
updatePosFlags(sym.moduleClass, pos, (mods & MODULE2CLASSFLAGS) | MODULE | FINAL);
sym
@@ -54,7 +54,10 @@ trait Namers: Analyzer {
if (p.isPackage && context.scope == p.owner.info.decls) {
p.pos = pos; p.moduleClass.pos = pos; p
} else {
- enterInScope(context.owner.newPackage(pos, name))
+ val pkg = context.owner.newPackage(pos, name);
+ pkg.moduleClass.setInfo(new PackageClassInfoType(new Scope(), pkg));
+ pkg.setInfo(pkg.moduleClass.tpe);
+ enterInScope(pkg)
}
}
@@ -94,14 +97,13 @@ trait Namers: Analyzer {
def enterSym(tree: Tree): Symbol = {
def finishWith(tparams: List[AbsTypeDef]) = {
- if (settings.debug.value) log("entered " + tree.symbol);
- val ltype = typer.typeCompleter(tree);
- def makeParam(tparam: AbsTypeDef): Symbol =
- tree.symbol.newTypeParameter(tparam.pos, tparam.name)
- .setInfo(typer.typeCompleter(tparam));
- tree.symbol.setInfo(
- if (tparams.isEmpty) ltype
- else new LazyPolyType(tparams map makeParam, ltype))
+ if (settings.debug.value) log("entered " + tree.symbol);
+ var ltype: LazyType = typer.typeCompleter(tree);
+ if (!tparams.isEmpty) {
+ new Namer(context.makeNewScope(tree, tree.symbol)).enterSyms(tparams);
+ ltype = new LazyPolyType(tparams map (.symbol), ltype);
+ }
+ tree.symbol.setInfo(ltype)
}
def finish = finishWith(List());
@@ -119,7 +121,7 @@ trait Namers: Analyzer {
if ((mods & (CASE | ABSTRACT)) == CASE) { // enter case factory method.
tree.symbol = enterCaseFactorySymbol(
tree.pos, mods & ACCESSFLAGS | CASE, name.toTermName);
- finishWith(tparams);
+ finishWith(tparams map (.duplicate.asInstanceOf[AbsTypeDef]));
}
tree.symbol = enterClassSymbol(tree.pos, mods, name);
finishWith(tparams)
@@ -135,7 +137,7 @@ trait Namers: Analyzer {
.setFlag(accmods).setInfo(typer.getterTypeCompleter(tree));
enterInScope(getter);
if ((mods & MUTABLE) != 0) {
- val setter = owner.newMethod(tree.pos, name)
+ val setter = owner.newMethod(tree.pos, nme.SETTER_NAME(name))
.setFlag(accmods).setInfo(typer.setterTypeCompleter(tree));
enterInScope(setter)
}
@@ -152,16 +154,16 @@ trait Namers: Analyzer {
}
case DefDef(mods, nme.CONSTRUCTOR, tparams, vparams, tp, rhs) =>
tree.symbol = enterInScope(owner.newConstructor(tree.pos))
- .setFlag(mods | owner.rawflags & CONSTRFLAGS);
+ .setFlag(mods | owner.getFlag(CONSTRFLAGS));
finishWith(tparams)
case DefDef(mods, name, tparams, _, _, _) =>
tree.symbol = enterInScope(owner.newMethod(tree.pos, name)).setFlag(mods);
finishWith(tparams)
case AbsTypeDef(mods, name, _, _) =>
- tree.symbol = enterInScope(owner.newAbstractType(tree.pos, name));
+ tree.symbol = enterInScope(owner.newAbstractType(tree.pos, name)).setFlag(mods);
finish
case AliasTypeDef(mods, name, tparams, _) =>
- tree.symbol = enterInScope(owner.newAliasType(tree.pos, name));
+ tree.symbol = enterInScope(owner.newAliasType(tree.pos, name)).setFlag(mods);
finishWith(tparams)
case Attributed(_, defn) =>
enterSym(defn)
diff --git a/sources/scala/tools/nsc/typechecker/TypeCheckers.scala b/sources/scala/tools/nsc/typechecker/TypeCheckers.scala
index a00b9829b1..3f9b4b41fa 100755
--- a/sources/scala/tools/nsc/typechecker/TypeCheckers.scala
+++ b/sources/scala/tools/nsc/typechecker/TypeCheckers.scala
@@ -51,6 +51,10 @@ trait TypeCheckers: Analyzer {
// expressions may be packages and
// Java statics modules.
+ private val TAPPmode = 0x080; // Set for the function/type constructor part
+ // of a type application. When set we do not
+ // decompose PolyTypes.
+
private val stickyModes: int = EXPRmode | PATTERNmode | TYPEmode | INCONSTRmode;
/** Report a type error.
@@ -81,11 +85,21 @@ trait TypeCheckers: Analyzer {
/** Check that type of given tree does not contain local or private components
*/
- private object checkNoEscape extends TypeMap {
+ object checkNoEscaping extends TypeMap {
private var owner: Symbol = _;
+ private var scope: Scope = _;
private var badSymbol: Symbol = _;
- def apply[T <: Tree](owner: Symbol, tree: T): T = {
+
+ /** Check that type `tree' does not refer to private components unless itself is wrapped
+ * in something private (`owner' tells where the type occurs). */
+ def privates[T <: Tree](owner: Symbol, tree: T): T = check(owner, EmptyScope, tree);
+
+ /** Check that type `tree' does not refer to entities defined in scope `scope'. */
+ def locals[T <: Tree](scope: Scope, tree: T): T = check(NoSymbol, scope, tree);
+
+ def check[T <: Tree](owner: Symbol, scope: Scope, tree: T): T = {
this.owner = owner;
+ this.scope = scope;
badSymbol = NoSymbol;
apply(tree.tpe);
if (badSymbol == NoSymbol) tree
@@ -98,21 +112,21 @@ trait TypeCheckers: Analyzer {
}
override def apply(t: Type): Type = {
def checkNoEscape(sym: Symbol): unit = {
- val e = context.scope.lookupEntry(sym.name);
- if (e != null && e.sym == sym && e.owner == context.scope && !e.sym.isTypeParameter) {
- badSymbol = e.sym
- } else if (sym.hasFlag(PRIVATE)) {
+ 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
+ } else if (sym.owner.isTerm) {
+ val e = scope.lookupEntry(sym.name);
+ if (e != null && e.sym == sym && e.owner == scope) badSymbol = e.sym
}
}
if (badSymbol == NoSymbol)
t match {
- case TypeRef(NoPrefix, sym, args) => checkNoEscape(sym)
- case SingleType(NoPrefix, sym) => checkNoEscape(sym)
- case _ =>
+ case TypeRef(_, sym, _) => checkNoEscape(sym)
+ case SingleType(_, sym) => checkNoEscape(sym)
+ case _ =>
}
mapOver(t)
}
@@ -121,8 +135,8 @@ trait TypeCheckers: Analyzer {
def reenterValueParams(vparamss: List[List[ValDef]]): unit =
for (val vparams <- vparamss; val vparam <- vparams) context.scope enter vparam.symbol;
- def reenterTypeParams(tparams: List[AbsTypeDef]): unit =
- for (val tparam <- tparams) context.scope enter tparam.symbol;
+ def reenterTypeParams(tparams: List[AbsTypeDef]): List[Symbol] =
+ for (val tparam <- tparams) yield { context.scope enter tparam.symbol; tparam.symbol }
def attrInfo(attr: Tree): AttrInfo = attr match {
case Apply(Select(New(tpt), nme.CONSTRUCTOR), args) =>
@@ -151,7 +165,8 @@ trait TypeCheckers: Analyzer {
* (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.
+ * store these instances in context.undetparams,
+ * unless followed by explicit type application.
* (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:
@@ -177,7 +192,7 @@ trait TypeCheckers: Analyzer {
adapt(tree, mode, pt)
case PolyType(List(), restpe) => // (2)
transform(constfold(tree.setType(restpe)), mode, pt);
- case PolyType(tparams, restpe) => // (3)
+ case PolyType(tparams, restpe) if ((mode & TAPPmode) == 0) => // (3)
val tparams1 = tparams map (.cloneSymbol);
val tree1 = if (tree.isType) tree
else TypeApply(tree, tparams1 map (tparam =>
@@ -247,29 +262,34 @@ trait TypeCheckers: Analyzer {
}
def completeSuperType(supertpt: Tree, tparams: List[Symbol], vparamss: List[List[ValDef]], superargs: List[Tree]): Type = {
- reenterValueParams(vparamss);
+ new Typer(context).enterValueParams(context.owner, vparamss);
context.undetparams = tparams;
transformExpr(atPos(supertpt.pos)(Apply(Select(New(supertpt), nme.CONSTRUCTOR), superargs)))
.tpe
}
- 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();
+ def parentTypes(templ: Template): List[Tree] = {
+ var supertpt = transform(templ.parents.head, TYPEmode | FUNmode, WildcardType);
+ var mixins = templ.parents.tail map transformType;
+ if (supertpt.symbol != null) {
+ val tparams = supertpt.symbol.typeParams;
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));
+ supertpt = gen.TypeTree(
+ new TypeChecker(context.makeNewScope(constr, context.owner.owner))
+ .completeSuperType(
+ supertpt,
+ tparams,
+ vparamss map (.map(.duplicate.asInstanceOf[ValDef])),
+ superargs map (.duplicate))) setPos supertpt.pos;
+ } else if (supertpt.symbol.isTrait) {
+ supertpt = gen.TypeTree(supertpt.tpe.parents(0)) setPos supertpt.pos;
+ mixins = templ.parents
}
- checkNoEscape(context.owner, supertpt) ::
- (templ.parents.tail mapConserve (tpt => transformType(tpt, context.owner)))
}
+ (supertpt :: mixins) mapConserve (tpt => checkNoEscaping.privates(context.owner, tpt))
+ }
/** Check that
* - all parents are class types,
@@ -286,34 +306,36 @@ trait TypeCheckers: Analyzer {
do { c = c.outer } while (c.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")
+ def validateParentClass(parent: Tree, isFirst: boolean): unit =
+ if (!parent.tpe.isError) {
+ val psym = parent.tpe.symbol;
+ if (!psym.isClass)
+ error(parent.pos, "class type expected");
+ else if (!isFirst && !psym.isTrait)
+ error(parent.pos, "" + psym + " 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)) {
+ System.out.println(context.owner);//debug
+ System.out.println(context.owner.thisSym);//debug
+ error(parent.pos, "illegal inheritance;\n self-type " +
+ selfType + " does not conform to " + parent +
+ "'s selftype " + parent.tpe.typeOfThis);
+ if (settings.explaintypes.value) explainTypes(selfType, parent.tpe.typeOfThis);
}
+ if (parents exists (p => p != parent && p.tpe.symbol == psym && !psym.isError))
+ error(parent.pos, "" + psym + " is inherited twice")
}
- 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 (settings.explaintypes.value) explainTypes(selfType, parent.tpe.typeOfThis);
- }
- if (parents exists (p => p != parent && p.tpe.symbol == psym && !psym.isError))
- error(parent.pos, "" + psym + " is inherited twice")
- }
if (!parents.isEmpty) {
validateParentClass(parents.head, true);
@@ -325,7 +347,7 @@ trait TypeCheckers: Analyzer {
val clazz = cdef.symbol;
reenterTypeParams(cdef.tparams);
val tparams1 = cdef.tparams mapConserve transformAbsTypeDef;
- val tpt1 = transformType(cdef.tpt, clazz.thisSym);
+ val tpt1 = checkNoEscaping.privates(clazz.thisSym, transformType(cdef.tpt));
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
@@ -338,17 +360,39 @@ trait TypeCheckers: Analyzer {
copy.ModuleDef(mdef, mdef.mods, mdef.name, impl1) setType NoType
}
+ def addGetterSetter(stat: Tree): List[Tree] = stat match {
+ case vd @ ValDef(mods, _, _, _) if (mods & PRIVATE) == 0 =>
+ def setter: DefDef = {
+ val sym = vd.symbol;
+ val setter = sym.owner.info.decls.lookup(nme.SETTER_NAME(sym.name)).suchThat(.hasFlag(ACCESSOR));
+ atPos(vd.pos)(
+ gen.DefDef(setter, vparamss => gen.Assign(gen.mkRef(vparamss.head.head), gen.mkRef(sym)))
+ ).setType(null) // to force type check
+ }
+ def getter: ValDef = {
+ val sym = vd.symbol;
+ val getter = sym.owner.info.decls.lookup(sym.name).suchThat(.hasFlag(ACCESSOR));
+ atPos(vd.pos)(
+ gen.ValDef(getter, gen.mkRef(sym))
+ ).setType(null) // to force type check
+ }
+ if ((mods & MUTABLE) != 0) List(stat, getter, setter) else List(stat, getter)
+ case _ =>
+ List(stat)
+ }
+
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
+ validateParentClasses(parents1, context.owner.typeOfThis);
+ val body1 = templ.body flatMap addGetterSetter;
+ val body2 = transformStats(templ.body, templ.symbol);
+ copy.Template(templ, parents1, body2) setType context.owner.tpe
}
def transformValDef(vdef: ValDef): ValDef = {
val sym = vdef.symbol;
- val tpt1 = transformType(vdef.tpt, sym);
+ var tpt1 = checkNoEscaping.privates(sym, transformType(vdef.tpt));
val rhs1 =
if (vdef.rhs.isEmpty) vdef.rhs
else new TypeChecker(context.make(vdef, sym)).transform(vdef.rhs, EXPRmode, tpt1.tpe);
@@ -361,7 +405,7 @@ trait TypeCheckers: Analyzer {
reenterValueParams(ddef.vparamss);
val tparams1 = ddef.tparams mapConserve transformAbsTypeDef;
val vparamss1 = ddef.vparamss mapConserve (.mapConserve(transformValDef));
- val tpt1 = transformType(ddef.tpt, meth);
+ var tpt1 = checkNoEscaping.privates(meth, transformType(ddef.tpt));
val rhs1 =
if (ddef.name == nme.CONSTRUCTOR) {
if (!meth.hasFlag(SYNTHETIC) &&
@@ -381,15 +425,15 @@ trait TypeCheckers: Analyzer {
}
def transformAbsTypeDef(tdef: AbsTypeDef): AbsTypeDef = {
- val lo1 = transformType(tdef.lo, tdef.symbol);
- val hi1 = transformType(tdef.hi, tdef.symbol);
+ val lo1 = checkNoEscaping.privates(tdef.symbol, transformType(tdef.lo));
+ val hi1 = checkNoEscaping.privates(tdef.symbol, transformType(tdef.hi));
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);
+ val rhs1 = checkNoEscaping.privates(tdef.symbol, transformType(tdef.rhs));
copy.AliasTypeDef(tdef, tdef.mods, tdef.name, tparams1, rhs1) setType NoType
}
@@ -411,7 +455,8 @@ trait TypeCheckers: Analyzer {
block.stats mapConserve transformExpr
}
val expr1 = transform(block.expr, mode & ~(FUNmode | QUALmode), pt);
- checkNoEscape(NoSymbol, copy.Block(block, stats1, expr1) setType expr1.tpe.deconst)
+ checkNoEscaping.locals(
+ context.scope, copy.Block(block, stats1, expr1) setType expr1.tpe.deconst)
}
def transformCase(cdef: CaseDef, pattpe: Type, pt: Type): CaseDef = {
@@ -444,7 +489,7 @@ trait TypeCheckers: Analyzer {
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))
+ setType typeRef(clazz.tpe.prefix, clazz, (vparamSyms map (.tpe)) ::: List(body1.tpe))
}
def transformRefinement(stats: List[Tree]): List[Tree] = {
@@ -469,20 +514,23 @@ trait TypeCheckers: Analyzer {
cases mapConserve (cdef => tc1.transformCase(cdef, pattp, pt))
}
- def transformTypeApply(fun: Tree, args: List[Tree]): Tree =
- if (fun.hasSymbol && fun.symbol.hasFlag(OVERLOADED)) {
- transformTypeApply(
- adapt(inferPolyAlternative(fun, args.length), funmode, WildcardType))
- } else {
- val tparams = context.undetparams;
- context.undetparams = List();
+ def transformTypeApply(fun: Tree, args: List[Tree]): Tree = fun.tpe match {
+ case OverloadedType(pre, alts) =>
+ inferPolyAlternative(fun, args.length);
+ transformTypeApply(fun, args)
+ case PolyType(tparams, restpe) if (tparams.length != 0) =>
if (tparams.length == args.length) {
- new TreeSubstituter(tparams, targs).traverse(fun); fun
- } else if (tparams.length == 0) {
- errorTree(tree, treeSymTypeMsg(tree, args) + " takes type parameters.");
+ val targs = args map (.tpe);
+ checkBounds(tree.pos, tparams, targs, "");
+ System.out.println("type app " + tparams + " => " + targs + " = " + restpe.subst(tparams, targs));//debug
+ copy.TypeApply(tree, fun, args) setType restpe.subst(tparams, targs);
} else {
errorTree(tree, "wrong number of type parameters for " + treeSymTypeMsg(fun))
}
+ case ErrorType =>
+ setError(tree)
+ case _ =>
+ errorTree(tree, treeSymTypeMsg(fun) + " takes type parameters.");
}
def transformApply(fun: Tree, args: List[Tree]): Tree = fun.tpe match {
@@ -564,7 +612,10 @@ trait TypeCheckers: Analyzer {
if (vmeth != NoSymbol)
return transform(Select(Apply(Ident(vmeth.name), List(qual)), name), mode, pt)
}
- stabilize(checkAccessible(tree, sym, qual.tpe, qual), qual.tpe)
+ if (sym.info == NoType)
+ errorTree(tree, decode(name) + " is not a member of " + qual.tpe.widen)
+ else
+ stabilize(checkAccessible(tree, sym, qual.tpe, qual), qual.tpe)
}
/** Attribute an identifier consisting of a simple name or an outer reference.
@@ -606,15 +657,17 @@ trait TypeCheckers: Analyzer {
// update `pre' to be `sym's prefix type in case it is an imported member,
// and compute value of:
var qual: Tree = EmptyTree; // the qualififier tree if transformed tree is a select
- if (defSym != NoSymbol) {
- if (impSym != NoSymbol)
+ if (defSym.tpe != NoType) {
+ if (impSym.tpe != NoType)
ambiguousError(
"it is both defined in " + defSym.owner +
" and imported subsequently by \n" + imports.head);
- else if (defSym.owner.isClass && !defSym.owner.isPackageClass)
- qual = gen.This(pre.symbol) setPos tree.pos;
+ else if (defSym.owner.isClass && !defSym.owner.isPackageClass && !defSym.isTypeParameter)
+ qual = gen.This(pre.symbol) setPos tree.pos
+ else
+ pre = NoPrefix;
} else {
- if (impSym != NoSymbol) {
+ if (impSym.tpe != NoType) {
var impSym1 = NoSymbol;
var imports1 = imports.tail;
def ambiguousImportError = ambiguousError(
@@ -632,14 +685,15 @@ trait TypeCheckers: Analyzer {
}
if (impSym1 != NoSymbol) ambiguousImportError;
defSym = impSym;
- qual = imports.head.tree.expr;
+ qual = imports.head.qual;
pre = qual.tpe;
} else {
error(tree.pos, "not found: " + decode(name));
defSym = context.owner.newErrorSymbol(name);
}
}
- stabilize(checkAccessible(tree, defSym, pre, qual), pre);
+ val tree1 = if (qual == EmptyTree) tree else Select(qual, name) setPos tree.pos;
+ stabilize(checkAccessible(tree1, defSym, pre, qual), pre);
}
/** Post-process an identifier or selection node, performing the following:
@@ -747,15 +801,17 @@ trait TypeCheckers: Analyzer {
}
val lhs1 = transformExpr(lhs);
val varsym = lhs1.symbol;
+ System.out.println("" + lhs1 + " " + " " + lhs1.getClass() + varsym);//debug
if (varsym != null && isGetter(varsym)) {
lhs1 match {
case Select(qual, name) =>
- transform(Apply(Select(qual, name.toString() + "_="), List(rhs)), mode, pt)
+ transform(Apply(Select(qual, nme.SETTER_NAME(name)), 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 {
+ System.out.println("" + lhs1 + " " + " " + lhs1.getClass() + varsym);//debug
if (!lhs.tpe.isError) error(tree.pos, "assignment to non-variable ");
setError(tree)
}
@@ -780,7 +836,7 @@ trait TypeCheckers: Analyzer {
val enclFun = context.owner.enclMethod;
if (!enclFun.isMethod || enclFun.isConstructor)
errorTree(tree, "return outside method definition")
- else if ((context.owner.rawflags & INITIALIZED) == 0)
+ else if (context.owner.hasFlag(INITIALIZED))
errorTree(tree, "method with return needs result type")
else {
val expr1: Tree = transform(expr, EXPRmode, enclFun.tpe.resultType);
@@ -800,8 +856,14 @@ trait TypeCheckers: Analyzer {
copy.Throw(tree, expr1) setType AllClass.tpe
case New(tpt: Tree) =>
- val tpt1 = transform(tpt, TYPEmode | FUNmode, WildcardType);
- copy.New(tree, tpt1).setType(tpt.tpe)
+ var tpt1 = transform(tpt, TYPEmode | FUNmode, WildcardType);
+ if (tpt1.symbol != null && !tpt1.symbol.typeParams.isEmpty) {
+ context.undetparams = tpt1.symbol.typeParams;
+ tpt1 = TypeTree()
+ setPos tpt1.pos
+ setType appliedType(tpt1.tpe, context.undetparams map (.tpe));
+ }
+ copy.New(tree, tpt1).setType(tpt1.tpe)
case Typed(expr, tpt @ Ident(nme.WILDCARD_STAR)) =>
val expr1 = transform(expr, mode & stickyModes, seqType(pt));
@@ -812,12 +874,14 @@ trait TypeCheckers: Analyzer {
setError(tree)
}
case Typed(expr, tpt) =>
- val tpt1 = transform(tpt, TYPEmode, WildcardType);
+ val tpt1 = transformType(tpt);
val expr1 = transform(expr, mode & stickyModes, tpt1.tpe);
- copy.Typed(tree, expr1, tpt1)
+ copy.Typed(tree, expr1, tpt1) setType tpt1.tpe
case TypeApply(fun, args) =>
- transformTypeApply(transform(fun, funmode, WildcardType), args)
+ val args1 = args mapConserve transformType;
+ // do args first in order to maintain conext.undetparams on the function side.
+ transformTypeApply(transform(fun, funmode | TAPPmode, WildcardType), args1)
case Apply(fun, args) =>
val funpt = if ((mode & PATTERNmode) != 0) pt else WildcardType;
@@ -826,7 +890,7 @@ trait TypeCheckers: Analyzer {
// number of arguments and expected result type.
if (fun1.hasSymbol && fun1.symbol.hasFlag(OVERLOADED)) {
val argtypes = args map (arg => AllClass.tpe);
- val pre = fun1.symbol.info.prefix;
+ val pre = fun1.symbol.tpe.prefix;
val sym = fun1.symbol filter (alt =>
isApplicable(context.undetparams, pre.memberType(alt), argtypes, pt));
if (sym != NoSymbol)
@@ -843,7 +907,8 @@ trait TypeCheckers: Analyzer {
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);
+ System.out.println(clazz.info.parents map (.symbol.name));//debug
+ error(tree.pos, "" + mix + " does not name a base class of " + clazz);
ErrorType
} else ps.head
}
@@ -859,6 +924,15 @@ trait TypeCheckers: Analyzer {
tree setSymbol clazz setType owntype
}
+ case Select(qual @ Super(_, _), nme.CONSTRUCTOR) =>
+ val qual1 = transform(qual, EXPRmode | QUALmode | POLYmode, WildcardType);
+ // the qualifier type of a supercall constructor is its first parent class
+ qual1.tpe match {
+ case RefinedType(parents, _) => qual1.tpe = parents.head;
+ case _ =>
+ }
+ transformSelect(qual1, nme.CONSTRUCTOR);
+
case Select(qual, name) =>
var qual1 = transform(qual, EXPRmode | QUALmode | POLYmode, WildcardType);
if (name.isTypeName) qual1 = checkStable(qual1);
@@ -875,12 +949,11 @@ trait TypeCheckers: Analyzer {
tree setType ref1.tpe.resultType;
case SelectFromTypeTree(qual, selector) =>
- tree setType transformSelect(transform(qual, TYPEmode, WildcardType), selector).tpe
+ tree setType transformSelect(transformType(qual), selector).tpe
case CompoundTypeTree(templ: Template) =>
tree setType {
- val parents1 = templ.parents mapConserve (parent =>
- transform(parent, TYPEmode, WildcardType));
+ val parents1 = templ.parents mapConserve transformType;
if (parents1 exists (.tpe.isError)) ErrorType
else {
val decls = new Scope();
@@ -891,9 +964,9 @@ trait TypeCheckers: Analyzer {
}
case AppliedTypeTree(tpt, args) =>
- val tpt1 = transform(tpt, mode | FUNmode, WildcardType);
- val tparams = tpt.tpe.symbol.typeParams;
- val args1 = args mapConserve (arg => transform(arg, TYPEmode, WildcardType));
+ val tpt1 = transform(tpt, mode | FUNmode | TAPPmode, WildcardType);
+ val tparams = tpt1.tpe.symbol.typeParams;
+ val args1 = args mapConserve transformType;
if (tpt1.tpe.isError)
setError(tree)
else if (tparams.length == args1.length)
@@ -919,14 +992,9 @@ trait TypeCheckers: Analyzer {
setError(tree)
}
- def transformExpr(tree: Tree): Tree =
- transform(tree, EXPRmode, WildcardType);
-
- def transformQualExpr(tree: Tree): Tree =
- transform(tree, EXPRmode | QUALmode, WildcardType);
-
- def transformType(tree: Tree, owner: Symbol) =
- checkNoEscape(owner, transform(tree, TYPEmode, WildcardType));
+ def transformExpr(tree: Tree): Tree = transform(tree, EXPRmode, WildcardType);
+ def transformQualExpr(tree: Tree): Tree = transform(tree, EXPRmode | QUALmode, WildcardType);
+ def transformType(tree: Tree) = transform(tree, TYPEmode, WildcardType);
}
}
diff --git a/sources/scala/tools/nsc/typechecker/Typers.scala b/sources/scala/tools/nsc/typechecker/Typers.scala
index e600c86625..441d6ab1e5 100755
--- a/sources/scala/tools/nsc/typechecker/Typers.scala
+++ b/sources/scala/tools/nsc/typechecker/Typers.scala
@@ -49,21 +49,14 @@ trait Typers: Analyzer {
def selfTypeCompleter(tree: Tree) = new TypeCompleter(tree) {
override def complete(sym: Symbol): unit = {
- sym.setInfo(typechecker.transformType(tree, sym).tpe);
+ sym.setInfo(typechecker.transformType(tree).tpe);
}
}
private def deconstIfNotFinal(sym: Symbol, tpe: Type): Type =
- if (sym.isVariable || (sym.rawflags & FINAL) == 0) tpe.deconst else tpe;
+ 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 }
- }
-
- private def enterValueParams(owner: Symbol,
- vparamss: List[List[ValDef]]): List[List[Symbol]] = {
+ def enterValueParams(owner: Symbol, vparamss: List[List[ValDef]]): List[List[Symbol]] = {
def enterValueParam(param: ValDef): Symbol = {
param.symbol = owner.newValueParameter(param.pos, param.name)
.setInfo(typeCompleter(param));
@@ -87,27 +80,26 @@ trait Typers: Analyzer {
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)
- }
+ ClassInfoType(parents, decls, clazz) }
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 tparamSyms = typechecker.reenterTypeParams(tparams);
+ if (!tpt.isEmpty)
+ context.owner.typeOfThis = selfTypeCompleter(tpt);
else tpt.tpe = NoType;
makePolyType(tparamSyms, templateSig(impl))
}
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 tparamSyms = typechecker.reenterTypeParams(tparams);
val vparamSymss = enterValueParams(meth, vparamss);
val restype = deconstIfNotFinal(meth,
if (tpt.isEmpty) {
tpt.tpe = if (meth.name == nme.CONSTRUCTOR) context.enclClass.owner.tpe
else typechecker.transformExpr(rhs).tpe;
tpt.tpe
- } else typechecker.transformType(tpt, meth).tpe);
+ } else typechecker.transformType(tpt).tpe);
def mkMethodType(vparams: List[Symbol], restpe: Type) =
MethodType(vparams map (.tpe), restpe);
makePolyType(
@@ -117,7 +109,7 @@ trait Typers: Analyzer {
}
private def aliasTypeSig(tpsym: Symbol, tparams: List[AbsTypeDef], rhs: Tree): Type =
- makePolyType(enterTypeParams(tpsym, tparams), typechecker.transformType(rhs, tpsym).tpe);
+ makePolyType(typechecker.reenterTypeParams(tparams), typechecker.transformType(rhs).tpe);
private def typeSig(tree: Tree): Type =
try {
@@ -129,7 +121,7 @@ trait Typers: Analyzer {
case ModuleDef(_, _, impl) =>
val clazz = sym.moduleClass;
clazz.setInfo(new Typer(context.make(tree, clazz)).templateSig(impl));
- clazz.tpe
+ clazz.tpe;
case DefDef(_, _, tparams, vparamss, tpt, rhs) =>
new Typer(context.makeNewScope(tree, sym)).methodSig(tparams, vparamss, tpt, rhs)
@@ -145,14 +137,13 @@ trait Typers: Analyzer {
.transformExpr(rhs).tpe;
tpt.tpe
}
- else typechecker.transformType(tpt, sym).tpe)
+ else typechecker.transformType(tpt).tpe)
case AliasTypeDef(_, _, tparams, rhs) =>
new Typer(context.makeNewScope(tree, sym)).aliasTypeSig(sym, tparams, rhs)
case AbsTypeDef(_, _, lo, hi) =>
- TypeBounds(typechecker.transformType(lo, sym).tpe,
- typechecker.transformType(hi, sym).tpe);
+ TypeBounds(typechecker.transformType(lo).tpe, typechecker.transformType(hi).tpe);
case Import(expr, selectors) =>
val expr1 = typechecker.transformQualExpr(expr);
@@ -168,7 +159,7 @@ trait Typers: Analyzer {
checkSelectors(rest)
case Nil =>
}
- expr1.tpe
+ ImportType(expr1)
}
} catch {
case ex: TypeError =>
diff --git a/sources/scala/tools/scalac/typechecker/RefCheck.scala b/sources/scala/tools/scalac/typechecker/RefCheck.scala
index 99e3ed2b75..25eab9e202 100755
--- a/sources/scala/tools/scalac/typechecker/RefCheck.scala
+++ b/sources/scala/tools/scalac/typechecker/RefCheck.scala
@@ -978,18 +978,30 @@ class RefCheck(globl: scalac.Global) extends Transformer(globl) {
// Tree node simplification---------------------------------------------------
- private def elimTypeNode(tree: Tree): Tree =
+ private def elimTypeNode(tree: Tree): Tree = {
+ def checkLegal(tp: Type): unit = tp match {
+ case Type.TypeRef(pre, sym, args) =>
+ sym.kind match {
+ case ALIAS | TYPE =>
+ checkLegal(sym.info().asSeenFrom(pre, sym.owner()));
+ case CLASS =>
+ if (sym == defs.ANY_CLASS)
+ unit.error(tree.pos, "Array[Any] not supported");
+ else if (sym == defs.ANYVAL_CLASS)
+ unit.error(tree.pos, "Array[AnyVal] not supported");
+ case _ =>
+ }
+ case _ =>
+ }
if (tree.isType()) {
val resultType = tree.getType().deconst();
val resultArgs = resultType.typeArgs();
- if (resultType.symbol() == defs.ARRAY_CLASS && resultArgs.length == 1) {
- if (resultArgs(0).symbol() == defs.ANY_CLASS)
- unit.error(tree.pos, "Array[Any] not supported");
- else if (resultArgs(0).symbol() == defs.ANYVAL_CLASS)
- unit.error(tree.pos, "Array[AnyVal] not supported");
+ if (resultType.symbol() == defs.ARRAY_CLASS && resultArgs.length == 1 && global.runTimeTypes) {
+ checkLegal(resultArgs(0))
}
gen.mkType(tree.pos, resultType);
- } else tree;
+ } else tree
+ }
// Transformation ------------------------------------------------------------
diff --git a/test/files/pos/List1.scala b/test/files/pos/List1.scala
index f0fce9501f..1321d95c20 100644
--- a/test/files/pos/List1.scala
+++ b/test/files/pos/List1.scala
@@ -1,19 +1,19 @@
object lists {
- trait List[a] {
+ abstract class List[a] {
def isEmpty: Boolean;
def head: a;
def tail: List[a];
def prepend(x: a) = Cons[a](x, this);
}
- def Nil[a] = new List[a] {
+ def Nil[b] = new List[b] {
def isEmpty: Boolean = true;
def head = error("head of Nil");
def tail = error("tail of Nil");
}
- def Cons[a](x: a, xs: List[a]): List[a] = new List[a] {
+ def Cons[c](x: c, xs: List[c]): List[c] = new List[c] {
def isEmpty = false;
def head = x;
def tail = xs;
diff --git a/test/files/pos/abstract.scala b/test/files/pos/abstract.scala
index f51ae63e6b..533f996931 100644
--- a/test/files/pos/abstract.scala
+++ b/test/files/pos/abstract.scala
@@ -1,9 +1,9 @@
-trait C {
+abstract class C() {
type t;
def copy(x: t): t = x;
}
-class D() extends C {
+class D() extends C() {
type t = Int;
System.out.println(copy(1));
}
diff --git a/test/files/pos/arrays2.scala b/test/files/pos/arrays2.scala
index 26adaf63ca..6f4a09a401 100644
--- a/test/files/pos/arrays2.scala
+++ b/test/files/pos/arrays2.scala
@@ -2,8 +2,8 @@ case class C();
object arrays2 {
- def main(args: Array[String]): unit = {
- val a = new Array[Array[C]](2);
+ def main(args: Array[String]): Unit = {
+ val a: Array[Array[C]] = new Array[Array[C]](2);
a(0) = new Array[C](2);
a(0)(0) = new C();
}
diff --git a/test/files/pos/bug115.scala b/test/files/pos/bug115.scala
index 87a5c10915..970636f708 100644
--- a/test/files/pos/bug115.scala
+++ b/test/files/pos/bug115.scala
@@ -1,8 +1,9 @@
class S[A](f: A => A, x: A) {
System.out.println(f(x));
}
-class T[A](f: A => A, y: A) extends S(x: A => f(x), y) {
+class T[B](f: B => B, y: B) extends S(x: B => f(x), y) {
}
object Test with Application {
- new T[int](x: int => x * 2, 1);
+ new T[Int](x => x * 2, 1);
+ val f = new S(x: Int => x, 1);
}