summaryrefslogtreecommitdiff
path: root/sources/scala/tools/nsc
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2005-02-16 13:15:42 +0000
committerMartin Odersky <odersky@gmail.com>2005-02-16 13:15:42 +0000
commit28c2394d012195e38308bcd6fd5049bcde635b4c (patch)
treeefc1ab19ecba057cf626af0d86e0aa85b985b941 /sources/scala/tools/nsc
parent431abf42bda2c97ff062594a8f1d15fd7776350c (diff)
downloadscala-28c2394d012195e38308bcd6fd5049bcde635b4c.tar.gz
scala-28c2394d012195e38308bcd6fd5049bcde635b4c.tar.bz2
scala-28c2394d012195e38308bcd6fd5049bcde635b4c.zip
*** empty log message ***
Diffstat (limited to 'sources/scala/tools/nsc')
-rw-r--r--sources/scala/tools/nsc/CompilationUnits.scala5
-rw-r--r--sources/scala/tools/nsc/CompilerCommand.scala5
-rwxr-xr-xsources/scala/tools/nsc/FatalError.scala5
-rwxr-xr-xsources/scala/tools/nsc/Global.scala7
-rwxr-xr-xsources/scala/tools/nsc/Main.scala5
-rw-r--r--sources/scala/tools/nsc/NoPhase.scala5
-rw-r--r--sources/scala/tools/nsc/Phase.scala5
-rw-r--r--sources/scala/tools/nsc/Settings.scala5
-rw-r--r--sources/scala/tools/nsc/StdPhase.scala5
-rwxr-xr-xsources/scala/tools/nsc/ast/TreeGen.scala19
-rw-r--r--sources/scala/tools/nsc/ast/TreeInfo.scala16
-rw-r--r--sources/scala/tools/nsc/ast/TreePrinters.scala18
-rw-r--r--sources/scala/tools/nsc/ast/Trees.scala31
-rw-r--r--sources/scala/tools/nsc/ast/parser/Lexical.scala5
-rw-r--r--sources/scala/tools/nsc/ast/parser/ParserPhase.scala5
-rwxr-xr-xsources/scala/tools/nsc/ast/parser/Syntactic.scala5
-rw-r--r--sources/scala/tools/nsc/ast/parser/Tokens.scala5
-rwxr-xr-xsources/scala/tools/nsc/symtab/Definitions.scala20
-rw-r--r--sources/scala/tools/nsc/symtab/Flags.scala11
-rw-r--r--sources/scala/tools/nsc/symtab/InfoTransformers.scala5
-rwxr-xr-xsources/scala/tools/nsc/symtab/Names.scala5
-rwxr-xr-xsources/scala/tools/nsc/symtab/Scopes.scala58
-rwxr-xr-xsources/scala/tools/nsc/symtab/StdNames.scala6
-rwxr-xr-xsources/scala/tools/nsc/symtab/SymbolLoaders.scala5
-rwxr-xr-xsources/scala/tools/nsc/symtab/SymbolTable.scala5
-rwxr-xr-xsources/scala/tools/nsc/symtab/Symbols.scala112
-rwxr-xr-xsources/scala/tools/nsc/symtab/Types.scala260
-rw-r--r--sources/scala/tools/nsc/symtab/classfile/ClassfileConstants.scala13
-rwxr-xr-xsources/scala/tools/nsc/symtab/classfile/ClassfileParser.scala27
-rwxr-xr-xsources/scala/tools/nsc/symtab/classfile/MetaParser.scala11
-rw-r--r--sources/scala/tools/nsc/symtab/classfile/Pickle.scala5
-rwxr-xr-xsources/scala/tools/nsc/symtab/classfile/UnPickle.scala13
-rw-r--r--sources/scala/tools/nsc/typechecker/Analyzer.scala5
-rwxr-xr-xsources/scala/tools/nsc/typechecker/Contexts.scala98
-rwxr-xr-xsources/scala/tools/nsc/typechecker/DeSugarizePhase.scala219
-rwxr-xr-xsources/scala/tools/nsc/typechecker/Namers.scala166
-rwxr-xr-xsources/scala/tools/nsc/typechecker/TypeCheckers.scala246
-rwxr-xr-xsources/scala/tools/nsc/typechecker/Typers.scala217
-rw-r--r--sources/scala/tools/nsc/util/CharArrayReader.scala5
-rw-r--r--sources/scala/tools/nsc/util/FreshNameCreator.scala5
-rwxr-xr-xsources/scala/tools/nsc/util/NameTransformer.scala5
41 files changed, 1395 insertions, 278 deletions
diff --git a/sources/scala/tools/nsc/CompilationUnits.scala b/sources/scala/tools/nsc/CompilationUnits.scala
index 303f4dcdfd..dd81fff836 100644
--- a/sources/scala/tools/nsc/CompilationUnits.scala
+++ b/sources/scala/tools/nsc/CompilationUnits.scala
@@ -1,3 +1,8 @@
+/* NSC -- new scala compiler
+ * Copyright 2005 LAMP/EPFL
+ * @author Martin Odersky
+ */
+// $Id$
package scala.tools.nsc;
import scala.tools.util.{SourceFile, Position};
diff --git a/sources/scala/tools/nsc/CompilerCommand.scala b/sources/scala/tools/nsc/CompilerCommand.scala
index 3d7b048292..fdea5cf424 100644
--- a/sources/scala/tools/nsc/CompilerCommand.scala
+++ b/sources/scala/tools/nsc/CompilerCommand.scala
@@ -1,3 +1,8 @@
+/* NSC -- new scala compiler
+ * Copyright 2005 LAMP/EPFL
+ * @author Martin Odersky
+ */
+// $Id$
package scala.tools.nsc;
import scala.tools.util.Reporter;
diff --git a/sources/scala/tools/nsc/FatalError.scala b/sources/scala/tools/nsc/FatalError.scala
index 6a139069d6..aa849fa5d0 100755
--- a/sources/scala/tools/nsc/FatalError.scala
+++ b/sources/scala/tools/nsc/FatalError.scala
@@ -1,3 +1,8 @@
+/* NSC -- new scala compiler
+ * Copyright 2005 LAMP/EPFL
+ * @author Martin Odersky
+ */
+// $Id$
package scala.tools.nsc;
case class FatalError(msg: String) extends Exception;
diff --git a/sources/scala/tools/nsc/Global.scala b/sources/scala/tools/nsc/Global.scala
index c6a8c668dd..b87b9e26f9 100755
--- a/sources/scala/tools/nsc/Global.scala
+++ b/sources/scala/tools/nsc/Global.scala
@@ -1,3 +1,8 @@
+/* NSC -- new scala compiler
+ * Copyright 2005 LAMP/EPFL
+ * @author Martin Odersky
+ */
+// $Id$
package scala.tools.nsc;
import java.io._;
@@ -204,7 +209,7 @@ class Global(val settings: Settings, val reporter: Reporter)
val root = getSym(name.subName(0, i), name(i) == '.');
var selector = name.subName(i+1, name.length);
if (module) selector = selector.toTypeName;
- root.info.lookup(selector)
+ root.info.member(selector)
}
}
val sym = getSym(name, module);
diff --git a/sources/scala/tools/nsc/Main.scala b/sources/scala/tools/nsc/Main.scala
index 36b3b12fe1..04b8ee3437 100755
--- a/sources/scala/tools/nsc/Main.scala
+++ b/sources/scala/tools/nsc/Main.scala
@@ -1,3 +1,8 @@
+/* NSC -- new scala compiler
+ * Copyright 2005 LAMP/EPFL
+ * @author Martin Odersky
+ */
+// $Id$
package scala.tools.nsc;
import scala.tools.util.{Position, Reporter, ConsoleReporter}
diff --git a/sources/scala/tools/nsc/NoPhase.scala b/sources/scala/tools/nsc/NoPhase.scala
index f9685f8010..342b022842 100644
--- a/sources/scala/tools/nsc/NoPhase.scala
+++ b/sources/scala/tools/nsc/NoPhase.scala
@@ -1,3 +1,8 @@
+/* NSC -- new scala compiler
+ * Copyright 2005 LAMP/EPFL
+ * @author Martin Odersky
+ */
+// $Id$
package scala.tools.nsc;
object NoPhase extends Phase(null) {
diff --git a/sources/scala/tools/nsc/Phase.scala b/sources/scala/tools/nsc/Phase.scala
index cd6034d29e..c110b54134 100644
--- a/sources/scala/tools/nsc/Phase.scala
+++ b/sources/scala/tools/nsc/Phase.scala
@@ -1,3 +1,8 @@
+/* NSC -- new scala compiler
+ * Copyright 2005 LAMP/EPFL
+ * @author Martin Odersky
+ */
+// $Id$
package scala.tools.nsc;
abstract class Phase(val prev: Phase) {
diff --git a/sources/scala/tools/nsc/Settings.scala b/sources/scala/tools/nsc/Settings.scala
index 7820f0adcb..409655560f 100644
--- a/sources/scala/tools/nsc/Settings.scala
+++ b/sources/scala/tools/nsc/Settings.scala
@@ -1,3 +1,8 @@
+/* NSC -- new scala compiler
+ * Copyright 2005 LAMP/EPFL
+ * @author Martin Odersky
+ */
+// $Id$
package scala.tools.nsc;
class Settings(error: String => unit) {
diff --git a/sources/scala/tools/nsc/StdPhase.scala b/sources/scala/tools/nsc/StdPhase.scala
index 46f4d296f4..36bfaebf2c 100644
--- a/sources/scala/tools/nsc/StdPhase.scala
+++ b/sources/scala/tools/nsc/StdPhase.scala
@@ -1,3 +1,8 @@
+/* NSC -- new scala compiler
+ * Copyright 2005 LAMP/EPFL
+ * @author Martin Odersky
+ */
+// $Id$
package scala.tools.nsc;
abstract class StdPhase(prev: Phase) extends Phase(prev) {
diff --git a/sources/scala/tools/nsc/ast/TreeGen.scala b/sources/scala/tools/nsc/ast/TreeGen.scala
new file mode 100755
index 0000000000..52848b1b5a
--- /dev/null
+++ b/sources/scala/tools/nsc/ast/TreeGen.scala
@@ -0,0 +1,19 @@
+/* NSC -- new scala compiler
+ * Copyright 2005 LAMP/EPFL
+ * @author Martin Odersky
+ */
+// $Id$
+package scala.tools.nsc.ast;
+
+import scala.tools.util.Position;
+
+abstract class TreeGen {
+
+ val global: Global;
+
+ import global._;
+
+ def mkGlobalRef(sym: Symbol): Tree = EmptyTree;
+
+ def This(pos: int, sym: Symbol): Tree = EmptyTree;
+}
diff --git a/sources/scala/tools/nsc/ast/TreeInfo.scala b/sources/scala/tools/nsc/ast/TreeInfo.scala
index a058fd34e5..7e703fbaf4 100644
--- a/sources/scala/tools/nsc/ast/TreeInfo.scala
+++ b/sources/scala/tools/nsc/ast/TreeInfo.scala
@@ -1,3 +1,8 @@
+/* NSC -- new scala compiler
+ * Copyright 2005 LAMP/EPFL
+ * @author Martin Odersky
+ */
+// $Id$
package scala.tools.nsc.ast;
import symtab.Flags._;
@@ -106,7 +111,7 @@ abstract class TreeInfo {
/** The first constructor in a list of statements */
def firstConstructor(stats: List[Tree]): Tree = stats.head match {
case DefDef(_, nme.CONSTRUCTOR, _, _, _, _) => stats.head
- case _ => primaryConstrTree(stats.tail)
+ case _ => firstConstructor(stats.tail)
}
/** Is name a variable name */
@@ -141,9 +146,8 @@ abstract class TreeInfo {
}
/** Is name imported explicitly, not via wildcard? */
- def isExplicitImport(tree: Import, name: Name): Symbol = {
- tree.selectors exists (.2.==(name.toTermName))
- }
+ def isExplicitImport(tree: Import, name: Name): boolean =
+ tree.selectors exists (._2.==(name.toTermName));
/** The symbol with name `name' imported from import clause `tree'.
*/
@@ -153,12 +157,12 @@ abstract class TreeInfo {
var selectors = tree.selectors;
while (selectors != Nil && result == NoSymbol) {
if (selectors.head._2 == name.toTermName)
- result = tree.expr.tpe.lookupNonPrivate(
+ result = tree.expr.tpe.member(
if (name.isTypeName) selectors.head._1.toTypeName else selectors.head._1);
else if (selectors.head._1 == name.toTermName)
renamed = true
else if (selectors.head._1 == nme.WILDCARD && !renamed)
- result = tree.expr.tpe.lookupNonPrivate(name)
+ result = tree.expr.tpe.member(name);
selectors = selectors.tail
}
result
diff --git a/sources/scala/tools/nsc/ast/TreePrinters.scala b/sources/scala/tools/nsc/ast/TreePrinters.scala
index 6b0b2a5e43..ae61481f85 100644
--- a/sources/scala/tools/nsc/ast/TreePrinters.scala
+++ b/sources/scala/tools/nsc/ast/TreePrinters.scala
@@ -1,12 +1,8 @@
-/* ____ ____ ____ ____ ______ *\
-** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala **
-** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL **
-** /_____/\____/\___/\____/____/ **
-** **
-\* */
-
-// $Id: TreePrinter.scala
-
+/* NSC -- new scala compiler
+ * Copyright 2005 LAMP/EPFL
+ * @author Martin Odersky
+ */
+// $Id$
package scala.tools.nsc.ast;
import java.io._;
@@ -261,8 +257,8 @@ abstract class TreePrinters {
case IntersectionTypeTree(parents) =>
printRow(parents, " with ")
- case RefinementTypeTree(base, members) =>
- print(base); printColumn(members, "{", ";", "}")
+ case RefinementTypeTree(base, decls) =>
+ print(base); printColumn(decls, "{", ";", "}")
case AppliedTypeTree(tp, args) =>
print(tp); printRow(args, "[", ", ", "]")
diff --git a/sources/scala/tools/nsc/ast/Trees.scala b/sources/scala/tools/nsc/ast/Trees.scala
index a1897a196a..909c15d5b0 100644
--- a/sources/scala/tools/nsc/ast/Trees.scala
+++ b/sources/scala/tools/nsc/ast/Trees.scala
@@ -1,3 +1,8 @@
+/* NSC -- new scala compiler
+ * Copyright 2005 LAMP/EPFL
+ * @author Martin Odersky
+ */
+// $Id$
package scala.tools.nsc.ast;
import java.io.StringWriter;
@@ -237,7 +242,7 @@ class Trees: Global {
extends TypeTree;
/** Refinement type, eliminated by RefCheck */
- case class RefinementTypeTree(base: Tree, members: List[Tree])
+ case class RefinementTypeTree(base: Tree, decls: List[Tree])
extends TypeTree;
/** Applied type, eliminated by RefCheck */
@@ -287,7 +292,7 @@ class Trees: Global {
case SelectFromTypeTree(qualifier, selector) =>
case FunctionTypeTree(argtpes, restpe) =>
case IntersectionTypeTree(parents) =>
- case RefinementTypeTree(base, members) =>
+ case RefinementTypeTree(base, decls) =>
case AppliedTypeTree(tp, args) =>
*/
@@ -333,7 +338,7 @@ class Trees: Global {
def SelectFromTypeTree(tree: Tree, qualifier: Tree, selector: Name): SelectFromTypeTree;
def FunctionTypeTree(tree: Tree, argtpes: List[Tree], restpe: Tree): FunctionTypeTree;
def IntersectionTypeTree(tree: Tree, parents: List[Tree]): IntersectionTypeTree;
- def RefinementTypeTree(tree: Tree, base: Tree, members: List[Tree]): RefinementTypeTree;
+ def RefinementTypeTree(tree: Tree, base: Tree, decls: List[Tree]): RefinementTypeTree;
def AppliedTypeTree(tree: Tree, tp: Tree, args: List[Tree]): AppliedTypeTree;
}
@@ -420,8 +425,8 @@ class Trees: Global {
{ val t = new FunctionTypeTree(argtpes, restpe); t.setPos(tree.pos); t }
def IntersectionTypeTree(tree: Tree, parents: List[Tree]) =
{ val t = new IntersectionTypeTree(parents); t.setPos(tree.pos); t }
- def RefinementTypeTree(tree: Tree, base: Tree, members: List[Tree]) =
- { val t = new RefinementTypeTree(base, members); t.setPos(tree.pos); t }
+ def RefinementTypeTree(tree: Tree, base: Tree, decls: List[Tree]) =
+ { val t = new RefinementTypeTree(base, decls); t.setPos(tree.pos); t }
def AppliedTypeTree(tree: Tree, tp: Tree, args: List[Tree]) =
{ val t = new AppliedTypeTree(tp, args); t.setPos(tree.pos); t }
}
@@ -632,10 +637,10 @@ class Trees: Global {
if (parents0 == parents) => t
case _ => copy.IntersectionTypeTree(tree, parents)
}
- def RefinementTypeTree(tree: Tree, base: Tree, members: List[Tree]) = tree match {
- case t @ RefinementTypeTree(base0, members0)
- if (base0 == base && members0 == members) => t
- case _ => copy.RefinementTypeTree(tree, base, members)
+ def RefinementTypeTree(tree: Tree, base: Tree, decls: List[Tree]) = tree match {
+ case t @ RefinementTypeTree(base0, decls0)
+ if (base0 == base && decls0 == decls) => t
+ case _ => copy.RefinementTypeTree(tree, base, decls)
}
def AppliedTypeTree(tree: Tree, tp: Tree, args: List[Tree]) = tree match {
case t @ AppliedTypeTree(tp0, args0)
@@ -731,8 +736,8 @@ class Trees: Global {
copy.FunctionTypeTree(tree, transformTrees(argtpes), transform(restpe))
case IntersectionTypeTree(parents) =>
copy.IntersectionTypeTree(tree, transformTrees(parents))
- case RefinementTypeTree(base, members) =>
- copy.RefinementTypeTree(tree, transform(base), transformTrees(members))
+ case RefinementTypeTree(base, decls) =>
+ copy.RefinementTypeTree(tree, transform(base), transformTrees(decls))
case AppliedTypeTree(tp, args) =>
copy.AppliedTypeTree(tree, transform(tp), transformTrees(args))
}
@@ -827,8 +832,8 @@ class Trees: Global {
traverseTrees(argtpes); traverse(restpe)
case IntersectionTypeTree(parents) =>
traverseTrees(parents)
- case RefinementTypeTree(base, members) =>
- traverse(base); traverseTrees(members)
+ case RefinementTypeTree(base, decls) =>
+ traverse(base); traverseTrees(decls)
case AppliedTypeTree(tp, args) =>
traverse(tp); traverseTrees(args)
case EmptyTree | Super(_, _) | This(_) | Ident(_) | Literal(_) | EmptyTypeTree() =>
diff --git a/sources/scala/tools/nsc/ast/parser/Lexical.scala b/sources/scala/tools/nsc/ast/parser/Lexical.scala
index 0daa68febe..d7ab47f91a 100644
--- a/sources/scala/tools/nsc/ast/parser/Lexical.scala
+++ b/sources/scala/tools/nsc/ast/parser/Lexical.scala
@@ -1,3 +1,8 @@
+/* NSC -- new scala compiler
+ * Copyright 2005 LAMP/EPFL
+ * @author Martin Odersky
+ */
+// $Id$
package scala.tools.nsc.ast.parser;
import Tokens._;
diff --git a/sources/scala/tools/nsc/ast/parser/ParserPhase.scala b/sources/scala/tools/nsc/ast/parser/ParserPhase.scala
index dab3581355..f4cac5680f 100644
--- a/sources/scala/tools/nsc/ast/parser/ParserPhase.scala
+++ b/sources/scala/tools/nsc/ast/parser/ParserPhase.scala
@@ -1,3 +1,8 @@
+/* NSC -- new scala compiler
+ * Copyright 2005 LAMP/EPFL
+ * @author Martin Odersky
+ */
+// $Id$
package scala.tools.nsc.ast.parser;
abstract class ParserPhase(prev: Phase)
diff --git a/sources/scala/tools/nsc/ast/parser/Syntactic.scala b/sources/scala/tools/nsc/ast/parser/Syntactic.scala
index 0c094e0a74..7ba1574072 100755
--- a/sources/scala/tools/nsc/ast/parser/Syntactic.scala
+++ b/sources/scala/tools/nsc/ast/parser/Syntactic.scala
@@ -1,3 +1,8 @@
+/* NSC -- new scala compiler
+ * Copyright 2005 LAMP/EPFL
+ * @author Martin Odersky
+ */
+// $Id$
package scala.tools.nsc.ast.parser;
import scala.tools.util.Position;
diff --git a/sources/scala/tools/nsc/ast/parser/Tokens.scala b/sources/scala/tools/nsc/ast/parser/Tokens.scala
index 682e12581d..8b26a259ca 100644
--- a/sources/scala/tools/nsc/ast/parser/Tokens.scala
+++ b/sources/scala/tools/nsc/ast/parser/Tokens.scala
@@ -1,3 +1,8 @@
+/* NSC -- new scala compiler
+ * Copyright 2005 LAMP/EPFL
+ * @author Martin Odersky
+ */
+// $Id$
package scala.tools.nsc.ast.parser;
object Tokens {
diff --git a/sources/scala/tools/nsc/symtab/Definitions.scala b/sources/scala/tools/nsc/symtab/Definitions.scala
index f9b4be936e..11e4a10684 100755
--- a/sources/scala/tools/nsc/symtab/Definitions.scala
+++ b/sources/scala/tools/nsc/symtab/Definitions.scala
@@ -1,3 +1,8 @@
+/* NSC -- new scala compiler
+ * Copyright 2005 LAMP/EPFL
+ * @author Martin Odersky
+ */
+// $Id$
package scala.tools.nsc.symtab;
import scala.tools.util.Position;
@@ -86,15 +91,12 @@ abstract class Definitions: SymbolTable {
var i = 0;
var j = fullname.pos('.', i);
while (j < fullname.length) {
- sym = sym.info.lookup(fullname.subName(i, j));
+ sym = sym.info.nonPrivateMember(fullname.subName(i, j));
i = j + 1;
j = fullname.pos('.', i)
}
- val result =
- if (module)
- sym.info.lookup(fullname.subName(i, j)).withFlag(MODULE | PACKAGE)
- else
- sym.info.lookup(fullname.subName(i, j).toTypeName);
+ val result = sym.info.nonPrivateMember(fullname.subName(i, j).toTypeName)
+ .suchThat(.hasFlag(MODULE));
if (result == NoSymbol)
throw new FatalError((if (module) "object " else "class ") + fullname + " not found.");
result
@@ -103,20 +105,20 @@ abstract class Definitions: SymbolTable {
private def newClass(owner: Symbol, name: Name, parents: List[Type]): Symbol = {
val clazz = owner.newClass(Position.NOPOS, name.toTypeName);
clazz.setInfo(ClassInfoType(parents, new Scope(), clazz));
- owner.info.members.enter(clazz);
+ owner.info.decls.enter(clazz);
clazz
}
private def newAlias(owner: Symbol, name: Name, alias: Type): Symbol = {
val tpsym = owner.newAliasType(Position.NOPOS, name.toTypeName);
tpsym.setInfo(alias);
- owner.info.members.enter(tpsym);
+ owner.info.decls.enter(tpsym);
tpsym
}
private def newMethod(owner: Symbol, name: Name): Symbol = {
val msym = owner.newMethod(Position.NOPOS, name);
- owner.info.members.enter(msym);
+ owner.info.decls.enter(msym);
msym
}
diff --git a/sources/scala/tools/nsc/symtab/Flags.scala b/sources/scala/tools/nsc/symtab/Flags.scala
index 73e3e54d1c..cfa93b8709 100644
--- a/sources/scala/tools/nsc/symtab/Flags.scala
+++ b/sources/scala/tools/nsc/symtab/Flags.scala
@@ -1,3 +1,8 @@
+/* NSC -- new scala compiler
+ * Copyright 2005 LAMP/EPFL
+ * @author Martin Odersky
+ */
+// $Id$
package scala.tools.nsc.symtab;
object Flags {
@@ -53,8 +58,9 @@ object Flags {
val INTERFACE = 0x100000000l; // symbol is an interface
val IS_ERROR = 0x200000000l; // symbol is an error symbol
+ val OVERLOADED = 0x400000000l; // symbol is overloaded
- val TRANS_FLAG = 0x400000000l; // transient flag guaranteed to be reset after each phase.
+ val TRANS_FLAG = 0x1000000000l; // transient flag guaranteed to be reset after each phase.
val LIFTED = TRANS_FLAG; // transient flag for lambdalift
val INCONSTRUCTOR = TRANS_FLAG; // transient flag for analyzer
@@ -66,7 +72,8 @@ object Flags {
/** 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;
+ COVARIANT | CONTRAVARIANT | SYNTHETIC | STABLE | ACCESSOR | PARAMACCESSOR | LOCAL |
+ IS_ERROR | OVERLOADED;
/** Module flags inherited by their module-class */
val MODULE2CLASSFLAGS = ACCESSFLAGS | PACKAGE;
diff --git a/sources/scala/tools/nsc/symtab/InfoTransformers.scala b/sources/scala/tools/nsc/symtab/InfoTransformers.scala
index fb32abc7b7..d74a099537 100644
--- a/sources/scala/tools/nsc/symtab/InfoTransformers.scala
+++ b/sources/scala/tools/nsc/symtab/InfoTransformers.scala
@@ -1,3 +1,8 @@
+/* NSC -- new scala compiler
+ * Copyright 2005 LAMP/EPFL
+ * @author Martin Odersky
+ */
+// $Id$
package scala.tools.nsc.symtab;
abstract class InfoTransformers: SymbolTable {
diff --git a/sources/scala/tools/nsc/symtab/Names.scala b/sources/scala/tools/nsc/symtab/Names.scala
index 0c5226c1c3..f381d46da8 100755
--- a/sources/scala/tools/nsc/symtab/Names.scala
+++ b/sources/scala/tools/nsc/symtab/Names.scala
@@ -1,3 +1,8 @@
+/* NSC -- new scala compiler
+ * Copyright 2005 LAMP/EPFL
+ * @author Martin Odersky
+ */
+// $Id$
package scala.tools.nsc.symtab;
import scala.tools.nsc.util.NameTransformer;
diff --git a/sources/scala/tools/nsc/symtab/Scopes.scala b/sources/scala/tools/nsc/symtab/Scopes.scala
index 6d47ec74dd..b3663d01e6 100755
--- a/sources/scala/tools/nsc/symtab/Scopes.scala
+++ b/sources/scala/tools/nsc/symtab/Scopes.scala
@@ -1,3 +1,8 @@
+/* NSC -- new scala compiler
+ * Copyright 2005 LAMP/EPFL
+ * @author Martin Odersky
+ */
+// $Id$
package scala.tools.nsc.symtab;
abstract class Scopes: SymbolTable {
@@ -23,23 +28,6 @@ abstract class Scopes: SymbolTable {
object NoScopeEntry extends ScopeEntry(NoSymbol, null);
- private val emptyIterator: Iterator[ScopeEntry] = Iterator.empty;
-
- private class EntryIterator(init: ScopeEntry, godeep: boolean) extends Iterator[ScopeEntry] {
- private var e: ScopeEntry = init;
- val owner = init.owner;
- def hasNext: boolean = e != null && (godeep || e.owner == owner)
- def next: ScopeEntry = {
- val result = e;
- if (e != null)
- if (hashtable != null)
- do { e = e.tail } while (e != null && e.sym.name != name)
- else
- do { e = e.next } while (e != null && e.sym.name != name);
- result
- }
- }
-
class Scope(initElems: ScopeEntry) {
var elems: ScopeEntry = initElems;
@@ -74,9 +62,9 @@ abstract class Scopes: SymbolTable {
}
}
- def this(members: List[Symbol]) = {
+ def this(decls: List[Symbol]) = {
this();
- members foreach enter
+ decls foreach enter
}
/** Returns a new scope with the same content as this one. */
@@ -157,9 +145,13 @@ abstract class Scopes: SymbolTable {
}
/** remove symbol */
- def unlink(sym: Symbol): unit =
- for (val e <- lookupAllEntries(sym.name, true))
+ def unlink(sym: Symbol): unit = {
+ var e = lookupEntry(sym.name);
+ while (e != null) {
if (e.sym == sym) unlink(e);
+ e = lookupNextEntry(e)
+ }
+ }
/** lookup a symbol
*/
@@ -182,20 +174,16 @@ abstract class Scopes: SymbolTable {
e
}
- /** Iterates through all symbol entries matching given name.
- * Iteration is from last declared to first declared.
- */
- def lookupAllEntries(name: Name, godeep: boolean): Iterator[ScopeEntry] = {
- val e = lookupEntry(name);
- if (e == null) emptyIterator else new EntryIterator(e, godeep);
+ /** lookup next entry with same name as this one */
+ def lookupNextEntry(entry: ScopeEntry): ScopeEntry = {
+ var e = entry;
+ if (hashtable != null)
+ do { e = e.tail } while (e != null && e.sym.name != entry.sym.name)
+ else
+ do { e = e.next } while (e != null && e.sym.name != entry.sym.name);
+ e
}
- /** Iterates through all symbols matching given name.
- * Iteration is from last declared to first declared.
- */
- def lookupAll(name: Name, godeep: boolean): Iterator[Symbol] =
- lookupAllEntries(name, godeep) map (.sym);
-
/** Return all symbols as a list in the order they were entered in this scope.
*/
def toList: List[Symbol] = {
@@ -210,6 +198,10 @@ abstract class Scopes: SymbolTable {
elemsCache
}
+ /** Return all symbols as an interator in the order they were entered in this scope.
+ */
+ def elements: Iterator[Symbol] = toList.elements;
+
override def toString(): String =
toList.map(.defString).mkString("{\n ", ";\n ", "\n}");
}
diff --git a/sources/scala/tools/nsc/symtab/StdNames.scala b/sources/scala/tools/nsc/symtab/StdNames.scala
index fe8fc3a12d..f9897eac9d 100755
--- a/sources/scala/tools/nsc/symtab/StdNames.scala
+++ b/sources/scala/tools/nsc/symtab/StdNames.scala
@@ -1,3 +1,8 @@
+/* NSC -- new scala compiler
+ * Copyright 2005 LAMP/EPFL
+ * @author Martin Odersky
+ */
+// $Id$
package scala.tools.nsc.symtab;
import scala.tools.nsc.util.NameTransformer;
@@ -25,6 +30,7 @@ abstract class StdNames: SymbolTable {
val NOSYMBOL = newTermName("<none>");
val EMPTY = newTermName("");
+ val ANYNAME = newTermName("<anyname>");
val WILDCARD = newTermName("_");
val WILDCARD_STAR = newTermName("_*");
val COMPOUND_NAME = newTermName("<ct>");
diff --git a/sources/scala/tools/nsc/symtab/SymbolLoaders.scala b/sources/scala/tools/nsc/symtab/SymbolLoaders.scala
index 0a5d16c801..c47c464b24 100755
--- a/sources/scala/tools/nsc/symtab/SymbolLoaders.scala
+++ b/sources/scala/tools/nsc/symtab/SymbolLoaders.scala
@@ -1,3 +1,8 @@
+/* NSC -- new scala compiler
+ * Copyright 2005 LAMP/EPFL
+ * @author Martin Odersky
+ */
+// $Id$
package scala.tools.nsc.symtab;
import java.io.IOException;
diff --git a/sources/scala/tools/nsc/symtab/SymbolTable.scala b/sources/scala/tools/nsc/symtab/SymbolTable.scala
index 1a0ce88b67..59bb30b1a6 100755
--- a/sources/scala/tools/nsc/symtab/SymbolTable.scala
+++ b/sources/scala/tools/nsc/symtab/SymbolTable.scala
@@ -1,3 +1,8 @@
+/* NSC -- new scala compiler
+ * Copyright 2005 LAMP/EPFL
+ * @author Martin Odersky
+ */
+// $Id$
package scala.tools.nsc.symtab;
import util._;
diff --git a/sources/scala/tools/nsc/symtab/Symbols.scala b/sources/scala/tools/nsc/symtab/Symbols.scala
index 95030b2519..cc4cfbe72c 100755
--- a/sources/scala/tools/nsc/symtab/Symbols.scala
+++ b/sources/scala/tools/nsc/symtab/Symbols.scala
@@ -1,3 +1,8 @@
+/* NSC -- new scala compiler
+ * Copyright 2005 LAMP/EPFL
+ * @author Martin Odersky
+ */
+// $Id$
package scala.tools.nsc.symtab;
import scala.tools.util.Position;
@@ -50,6 +55,11 @@ abstract class Symbols: SymbolTable {
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 =
+ newValue(alternatives.head.pos, alternatives.head.name)
+ .setFlag(OVERLOADED)
+ .setInfo(OverloadedType(pre, alternatives));
+
final def newErrorValue(name: Name) =
newValue(pos, name).setFlag(SYNTHETIC | IS_ERROR).setInfo(ErrorType);
final def newAliasType(pos: int, name: Name) =
@@ -69,7 +79,8 @@ abstract class Symbols: SymbolTable {
clazz.setInfo(ClassInfoType(List(), new ErrorScope(this), clazz));
clazz
}
-
+ final def newErrorSymbol(name: Name) =
+ if (name.isTypeName) newErrorClass(name) else newErrorValue(name);
// Tests ----------------------------------------------------------------------
@@ -270,6 +281,14 @@ abstract class Symbols: SymbolTable {
/** The type parameters of this symbol */
def typeParams: List[Symbol] = rawInfo.typeParams;
+ /** Reset symbol to initial state
+ */
+ def reset(completer: Type): unit = {
+ resetFlags;
+ pos = Position.NOPOS;
+ infos = null;
+ setInfo(completer)
+ }
// Comparisons ----------------------------------------------------------------
/** A total ordering between symbols that refines the class
@@ -302,37 +321,14 @@ abstract class Symbols: SymbolTable {
// Overloaded Alternatives ---------------------------------------------------------
- /** All overloaded alternatives of this symbol */
- def alternatives: Iterator[Symbol] =
- Iterator.fromValues(this);
-
- private def findUnique(alts: Iterator[Symbol], p: Symbol => boolean): Symbol = {
- if (alts.hasNext) {
- val alt = alts.next;
- if (p(alt)) {
- while (alts.hasNext) assert(!p(alts.next));
- alt
- } else findUnique(alts, p)
- } else NoSymbol
- }
+ def alternatives: List[Symbol] =
+ if (hasFlag(OVERLOADED)) info.asInstanceOf[OverloadedType].alternatives
+ else List(this);
- /** The unique alternative whose type at given prefix `pre' matches `tp'
- * or NoSymbol, if no such alternatives exist.
- */
- final def matching(pre: Type, tp: Type): Symbol =
- findUnique(alternatives, alt => pre.memberType(alt).matches(tp));
-
- final def withFlag(mask: long): Symbol =
- findUnique(alternatives, .hasFlag(mask));
-
- /** Reset symbol to initial state
- */
- def reset(completer: Type): unit = {
- resetFlags;
- pos = Position.NOPOS;
- infos = null;
- setInfo(completer)
- }
+ def suchThat(cond: Symbol => boolean): Symbol =
+ if (hasFlag(OVERLOADED)) uniqueSymbolIn(alternatives.elements, cond)
+ else if (cond(this)) this
+ else NoSymbol;
// Cloneing -------------------------------------------------------------------
@@ -357,12 +353,7 @@ abstract class Symbols: SymbolTable {
def enclMethod: Symbol = if (isMethod) this else owner.enclMethod;
/** The primary constructor of a class */
- def primaryConstructor: Symbol = {
- var constr: Symbol = NoSymbol;
- val syms = info.members.lookupAll(nme.CONSTRUCTOR, true);
- while (syms.hasNext) constr = syms.next;
- constr
- }
+ def primaryConstructor: Symbol = info.decl(nme.CONSTRUCTOR).alternatives.head;
/** The self symbol of a class with explicit self type, or else the symbol itself.
*/
@@ -380,7 +371,7 @@ abstract class Symbols: SymbolTable {
/** Return every accessor of a primary constructor parameter in this case class */
final def caseFieldAccessors: List[Symbol] = {
assert(isClass && hasFlag(CASE));
- info.members.toList.filter(sym => sym.isMethod && sym.hasFlag(PARAMACCESSOR))
+ info.decls.toList.filter(sym => sym.isMethod && sym.hasFlag(PARAMACCESSOR))
}
/** The symbol accessed by this accessor function.
@@ -389,30 +380,26 @@ abstract class Symbols: SymbolTable {
assert((rawflags & ACCESSOR) != 0);
val name1 = if (name.endsWith(nme._EQ)) name.subName(0, name.length - nme._EQ.length)
else name;
- owner.info.lookup(name1.toString() + "$")
+ owner.info.decl(name1.toString() + "$")
}
/** The class with the same name in the same package as this module or
* case class factory
*/
final def linkedClass: Symbol = {
- if (!owner.isPackageClass) NoSymbol
- else {
- val clazz = owner.info.lookup(name.toTypeName);
- if (clazz.rawInfo == NoType) NoSymbol else clazz
- }
+ if (owner.isPackageClass)
+ owner.info.decl(name.toTypeName).suchThat(sym => sym.rawInfo != NoType)
+ else NoSymbol;
}
/** The module or case class factory with the same name in the same
* package as this class.
*/
- final def linkedModule: Symbol = {
- if (!owner.isPackageClass) NoSymbol
- else {
- val module = owner.info.lookup(name.toTermName).withFlag(MODULE);
- if (module.rawInfo == NoType) NoSymbol else module
- }
- }
+ final def linkedModule: Symbol =
+ if (owner.isPackageClass)
+ owner.info.decl(name.toTermName).suchThat(
+ sym => (sym hasFlag MODULE) && (sym.rawInfo != NoType));
+ else NoSymbol;
/** The module corresponding to this module class (note that this
* is not updated when a module is cloned).
@@ -425,11 +412,13 @@ abstract class Symbols: SymbolTable {
/** The symbol overridden by this symbol in given base class */
final def overriddenSymbol(base: Symbol): Symbol =
- base.info.lookupNonPrivate(name).matching(owner.thisType, info);
+ base.info.nonPrivateDecl(name).suchThat(sym =>
+ sym.isType || (owner.thisType.memberType(sym) matches tpe));
/** The symbol overriding this symbol in given subclass */
final def overridingSymbol(base: Symbol): Symbol =
- base.info.lookupNonPrivate(name).matching(base.thisType, base.tpe.memberType(this));
+ base.info.nonPrivateDecl(name).suchThat(sym =>
+ sym.isType || (base.thisType.memberType(sym) matches base.thisType.memberType(this)));
// ToString -------------------------------------------------------------------
@@ -562,9 +551,6 @@ abstract class Symbols: SymbolTable {
/** A class for term symbols */
class TermSymbol(initOwner: Symbol, initPos: int, initName: Name) extends Symbol(initOwner, initPos, initName) {
override def isTerm = true;
- override def alternatives: Iterator[Symbol] =
- if (owner.isClass) owner.info.members.lookupAll(name, true)
- else super.alternatives;
def cloneSymbolImpl(owner: Symbol): Symbol =
new TermSymbol(owner, pos, name);
}
@@ -651,8 +637,8 @@ abstract class Symbols: SymbolTable {
override def enclClass: Symbol = this;
override def enclMethod: Symbol = this;
override def owner: Symbol = throw new Error();
+ override def alternatives: List[Symbol] = List();
override def reset(completer: Type): unit = {}
- override def alternatives: Iterator[Symbol] = Iterator.empty[Symbol];
def cloneSymbolImpl(owner: Symbol): Symbol = throw new Error();
}
@@ -661,4 +647,16 @@ abstract class Symbols: SymbolTable {
/** A class for type histories */
private class TypeHistory(val start: Phase, val info: Type, val prev: TypeHistory);
+
+
+ /** Return unique element in list of symbols satisfying condition,
+ * or NoSymbol if no element satisfies condition,
+ * pre: at most one element satisfies condition.
+ */
+ def uniqueSymbolIn(syms: Iterator[Symbol], cond: Symbol => boolean): Symbol =
+ if (syms.hasNext) {
+ val sym = syms.next;
+ if (cond(sym)) { assert(!syms.exists(cond)); sym }
+ else uniqueSymbolIn(syms, cond)
+ } else NoSymbol;
}
diff --git a/sources/scala/tools/nsc/symtab/Types.scala b/sources/scala/tools/nsc/symtab/Types.scala
index 705ca7dc72..7f8688f3bc 100755
--- a/sources/scala/tools/nsc/symtab/Types.scala
+++ b/sources/scala/tools/nsc/symtab/Types.scala
@@ -1,3 +1,8 @@
+/* NSC -- new scala compiler
+ * Copyright 2005 LAMP/EPFL
+ * @author Martin Odersky
+ */
+// $Id$
package scala.tools.nsc.symtab;
import scala.tools.util.Position;
@@ -10,8 +15,6 @@ abstract class Types: SymbolTable {
val emptyTypeArray = new Array[Type](0);
- val emptySymbolIterator = Iterator.empty[Symbol];
-
/** The base class for all types */
trait Type {
@@ -30,7 +33,7 @@ abstract class Types: SymbolTable {
/** Map to a this type which is a subtype of this type.
*/
def narrow: Type = {
- val reftpe = refinedType(this, commonOwner(this), EmptyScope);
+ val reftpe = refinedType(List(this), commonOwner(this), EmptyScope);
ThisType(reftpe.symbol);
}
@@ -85,49 +88,46 @@ abstract class Types: SymbolTable {
/** Does this type denote a stable reference (i.e. singleton type)? */
def isStable: boolean = false;
- /** For a classtype or refined type, its members;
+ /** For a classtype or refined type, its defined or declared members;
* inherited by subtypes and typerefs.
* The empty scope for all other types */
- def members: Scope = EmptyScope;
-
- /** An iterator that enumerates all members of this type and its base types
- * Members of any type precede members of its base types in the ordering
- * Members of parents of a type are enumerated right to left. */
- def rawMembersIterator: Iterator[Symbol] = emptySymbolIterator;
-
- /** An iterator that enumerates all members of this type
- * (defined or inherited).
- * Defined members of a type precede members inherited from its base types
- * in the ordering.
- * Members of parents of a type are enumerated right to left. */
- def allPublicMembersIterator: Iterator[Symbol] =
- for (val sym <- rawMembersIterator;
- !sym.hasFlag(PRIVATE) && (lookup(sym.name).alternatives contains sym))
- yield sym;
-
- /** The member with given name of this type, NoSymbol if none exists */
- def lookup(name: Name): Symbol = lookupExclude(name, 0);
-
- /** The non-private member with given name of this type,
- * NoSymbol if none exists. */
- def lookupNonPrivate(name: Name): Symbol = lookupExclude(name, PRIVATE);
-
- protected def lookupExclude(name: Name, excludeFlags: int): Symbol = {
- val buf = new ListBuffer;
- appendMembers(name, buf, excludeFlags | DEFERRED);
- appendMembers(name, buf, excludeFlags);
- if (buf.length == 0) NoSymbol
- else if (buf.length == 1) buf(0)
- else overloadedSymbol(this, buf.elements.toList)
- }
+ def decls: Scope = EmptyScope;
+
+ /** The defined or declared members with name `name' in this type;
+ * an OverloadedSymbol if several exist, NoSymbol if none exist.
+ * Alternatives of overloaded symbol appear in the order they are declared.
+ */
+ def decl(name: Name): Symbol = findDecl(name, 0);
- protected def appendMembers(name: Name, buf: List[Buffer], excludeFlags: int): unit;
+ /** The non-orivate defined or declared members with name `name' in this type;
+ * an OverloadedSymbol if several exist, NoSymbol if none exist.
+ * Alternatives of overloaded symbol appear in the order they are declared.
+ */
+ def nonPrivateDecl(name: Name): Symbol = findDecl(name, PRIVATE);
+
+ /** A list of all members of this type (defined or inherited)
+ * Members appear in linearization order of their owners.
+ * Members with the same owner appear in reverse order of their declarations.
+ */
+ def members: List[Symbol] = findMember(nme.ANYNAME, 0).alternatives;
+
+ /** A list of all non-private members of this type (defined or inherited) */
+ def nonPrivateMembers: List[Symbol] = findMember(nme.ANYNAME, PRIVATE).alternatives;
+
+ /** The member with given name,
+ * an OverloadedSymbol if several exist, NoSymbol if none exist */
+ def member(name: Name): Symbol = findMember(name, 0);
+
+ /** The non-private member with given name,
+ * an OverloadedSymbol if several exist, NoSymbol if none exist */
+ def nonPrivateMember(name: Name): Symbol = findMember(name, PRIVATE);
/** The least type instance of given class which is a supertype
* of this type */
def baseType(clazz: Symbol): Type = NoType;
- /** This type as seen from prefix `pre' and class `clazz'. This means:
+ /** This type as seen from prefix `
+ pre' and class `clazz'. This means:
* Replace all thistypes of `clazz' or one of its subclasses by `pre'
* and instantiate all parameters by arguments of `pre'.
* Proceed analogously for thistypes referring to outer classes. */
@@ -263,6 +263,69 @@ abstract class Types: SymbolTable {
/** If this is a lazy type, assign a new type to `sym'. */
def complete(sym: Symbol): unit = {}
+
+ private def findDecl(name: Name, excludedFlags: int): Symbol = {
+ var alts: List[Symbol] = List();
+ var sym: Symbol = NoSymbol;
+ var e = decls.lookupEntry(name);
+ while (e != null) {
+ if ((e.sym.rawflags & excludedFlags) == 0) {
+ if (sym == NoSymbol) sym = e.sym
+ else {
+ if (alts.isEmpty) alts = List(sym);
+ alts = e.sym :: alts
+ }
+ }
+ e = decls.lookupNextEntry(e)
+ }
+ if (alts.isEmpty) sym
+ else baseClasses.head.newOverloaded(this, alts)
+ }
+
+ protected def findMember(name: Name, excludedFlags: int): Symbol = {
+ var members: Scope = null;
+ var member: Symbol = NoSymbol;
+ var excluded = excludedFlags | DEFERRED;
+ var continue = true;
+ while (continue) {
+ continue = false;
+ var bcs = baseClasses;
+ while (!bcs.isEmpty) {
+ val decls = bcs.head.info.decls;
+ bcs = 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;
+ if (excl == 0) {
+ if (name.isTypeName)
+ return sym
+ else if (member == NoSymbol)
+ member = sym
+ else if (members == null &&
+ !(member.name == sym.name &&
+ (memberType(member) matches memberType(sym))))
+ members = new Scope(List(member, sym))
+ else {
+ var prevEntry = members lookupEntry sym.name;
+ while (prevEntry != null &&
+ !(memberType(prevEntry.sym) matches memberType(sym)))
+ prevEntry = members lookupNextEntry prevEntry;
+ if (prevEntry == null)
+ members enter sym
+ }
+ } else if (excl == DEFERRED) {
+ continue = true;
+ }
+ entry = if (name == nme.ANYNAME) entry.next else decls lookupNextEntry entry
+ } // while (entry != null)
+ excluded = excluded | PRIVATE
+ } // while (!bcs.isEmpty)
+ excluded = excludedFlags
+ } // while (continue)
+ if (members == null) member
+ else baseClasses.head.newOverloaded(this, members.toList)
+ }
}
// Subclasses ------------------------------------------------------------
@@ -273,10 +336,7 @@ abstract class Types: SymbolTable {
abstract trait SubType extends Type {
protected def supertype: Type;
override def parents: List[Type] = supertype.parents;
- override def members: Scope = supertype.members;
- override def rawMembersIterator: Iterator[Symbol] = supertype.rawMembersIterator;
- override def appendMembers(name: Name, buf: List[Buffer], excludeFlags: int): unit =
- supertype.appendMembers(name, bug, excludeFlags);
+ override def decls: Scope = supertype.decls;
override def baseType(clazz: Symbol): Type = supertype.baseType(clazz);
override def closure: Array[Type] = supertype.closure;
override def baseClasses: List[Symbol] = supertype.baseClasses;
@@ -296,9 +356,9 @@ abstract class Types: SymbolTable {
/** An object representing an erroneous type */
case object ErrorType extends Type {
- override def members: Scope = new ErrorScope(NoSymbol);
- override def appendMembers(name: Name, buf: List[Buffer], excludeFlags: int): unit =
- buf += (members lookup name);
+ // todo see whether we can do without
+ override def decls: Scope = new ErrorScope(NoSymbol);
+ override def findMember(name: Name, excludedFlags: int): Symbol = decls lookup name;
override def baseType(clazz: Symbol): Type = this;
override def toString(): String = "<error>";
override def narrow: Type = this;
@@ -364,18 +424,7 @@ abstract class Types: SymbolTable {
*/
abstract class CompoundType extends Type {
override val parents: List[Type];
- override val members: Scope;
-
- override def appendMembers(name: Name, scope: Scope, buf: List[Buffer], excludeFlags: int): unit = {
- for (val sym <- scope.lookupAll(name, false)) {
- if ((sym.rawflags & excludeFlags) == 0)
- if (buf.length == 0 ||
- !buf.elements.exists(m => memberType(m) matches memberType(sym)))
- buf += sym
- }
- for (val bc <- baseClasses)
- baseType(bc).appendMembers(name, buf, excludeFlags | PRIVATE)
- }
+ override val decls: Scope;
private var closureCache: Array[Type] = _;
private var baseClassCache: List[Symbol] = _;
@@ -402,13 +451,13 @@ abstract class Types: SymbolTable {
override def baseClasses: List[Symbol] = {
def computeBaseClasses: List[Symbol] =
- if (parents.isEmpty) List()
+ if (parents.isEmpty) List(symbol)
else {
var bcs: List[Symbol] = parents.head.baseClasses;
- val mixins = parents.tail map (.symbol);
- def isNew(limit: List[Symbol])(clazz: Symbol): boolean = {
+ val mixins = parents.tail;
+ def isNew(limit: List[Type])(clazz: Symbol): boolean = {
var ms = mixins;
- while (!(ms eq limit) && !(ms.head.isSubClass clazz)) ms = ms.tail;
+ while (!(ms eq limit) && !(ms.head.symbol isSubClass clazz)) ms = ms.tail;
ms eq limit
}
var ms = mixins;
@@ -424,7 +473,7 @@ abstract class Types: SymbolTable {
baseClassCache = null;
baseClassCache = computeBaseClasses;
}
- if (baseClassCache = null)
+ if (baseClassCache == null)
throw new TypeError("illegal cyclic reference involving " + symbol);
baseClassCache
}
@@ -436,33 +485,28 @@ abstract class Types: SymbolTable {
override def narrow: Type = symbol.thisType;
- override def rawMembersIterator: Iterator[Symbol] =
- scope.toList.elements append
- (for (val parent <- parents.reverse.elements;
- val sym <- parent.rawMembersIterator) yield sym);
-
override def erasure: Type =
if (parents.isEmpty) this else parents.head.erasure;
override def toString(): String =
- parents.mkString("", " with ", "") + members.toString()
+ parents.mkString("", " with ", "") + decls.toString()
}
/** A class representing intersection types with refinements of the form
- * <parents_0> with ... with <parents_n> { members }
+ * <parents_0> with ... with <parents_n> { decls }
* Cannot be created directly;
* one should always use `refinedType' for creation.
*/
abstract case class RefinedType(override val parents: List[Type],
- override val members: Scope) extends CompoundType;
+ override val decls: Scope) extends CompoundType;
/** A class representing a class info
*/
case class ClassInfoType(override val parents: List[Type],
- override val members: Scope,
+ override val decls: Scope,
override val symbol: Symbol) extends CompoundType;
- class PackageClassInfoType(defs: Members, clazz: Symbol) extends ClassInfoType(List(), defs, clazz);
+ class PackageClassInfoType(decls: Scope, clazz: Symbol) extends ClassInfoType(List(), decls, clazz);
/** A class representing a constant type */
case class ConstantType(base: Type, value: Any)
@@ -504,13 +548,7 @@ abstract class Types: SymbolTable {
override def typeParams: List[Symbol] =
if (args.isEmpty) symbol.typeParams else List();
- override def members: Scope = sym.info.members;
-
- override def rawMembersIterator: Iterator[Symbol] =
- sym.info.rawMembersIterator;
-
- override def appendMembers(name: Name, buf: List[Buffer], excludeFlags: int): unit =
- sym.info.appendMembers(name, buf, excludeFlags);
+ override def decls: Scope = sym.info.decls;
override def baseType(clazz: Symbol): Type =
if (sym == clazz) this
@@ -627,7 +665,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 lookupNonPrivate sym.name;
+ val rebind = pre.nonPrivateMember(sym.name).suchThat(.isStable);
if (rebind == NoSymbol) sym else rebind
} else sym
}
@@ -657,9 +695,9 @@ abstract class Types: SymbolTable {
}
/** the canonical creator for a refined type with a given scope */
- def refinedType(parents: List[Type], owner: Symbol, members: Scope): RefinedType = {
+ def refinedType(parents: List[Type], owner: Symbol, decls: Scope): RefinedType = {
val clazz = owner.newRefinementClass(Position.NOPOS);
- val result = new RefinedType(parents, members) {
+ val result = new RefinedType(parents, decls) {
override def symbol: Symbol = clazz
}
clazz.setInfo(result);
@@ -674,7 +712,7 @@ abstract class Types: SymbolTable {
* replaced by the type itself. */
def intersectionType(tps: List[Type]): Type = tps match {
case List(tp) => tp
- case _ => refinedType(tps, commonOnwer(tps))
+ case _ => refinedType(tps, commonOwner(tps))
}
/** A creator for type applications */
@@ -685,12 +723,6 @@ abstract class Types: SymbolTable {
case ErrorType => tycon
}
- def overloadedSymbol(pre: Type, alternatives: List[Symbol]): Symbol = {
- pre.symbol.newValue(alternatives.head.pos, alternatives.head.name)
- .setFlag(OVERLOADED)
- .setInfo(OverloadedType(pre, alternatives))
- }
-
// Helper Classes ---------------------------------------------------------
/** A class expressing upper and lower bounds constraints
@@ -741,8 +773,8 @@ abstract class Types: SymbolTable {
val result = refinedType(parents1, tp.symbol.owner);
val syms1 = refinement1.toList;
for (val sym <- syms1)
- result.members.enter(sym.cloneSymbol(result.symbol));
- val syms2 = result.members.toList;
+ result.decls.enter(sym.cloneSymbol(result.symbol));
+ val syms2 = result.decls.toList;
val resultThis = ThisType(result.symbol);
for (val sym <- syms2)
sym.setInfo(sym.info.substSym(syms1, syms2).substThis(tp.symbol, resultThis));
@@ -1060,7 +1092,7 @@ abstract class Types: SymbolTable {
if (constr1.inst != NoType) constr1.inst <:< tp2
else { constr1.hibounds = tp2 :: constr1.hibounds; true }
case Pair(_, RefinedType(parents2, ref2)) =>
- parents2 forall (tp1.<:<) && (ref2.toList forall (tp1 specializes))
+ (parents2 forall tp1.<:<) && (ref2.toList forall tp1.specializes)
case Pair(RefinedType(parents1, ref1), _) =>
parents1 exists (.<:<(tp2))
case Pair(ThisType(_), _)
@@ -1088,7 +1120,7 @@ abstract class Types: SymbolTable {
def specializesSym(tp: Type, sym: Symbol): boolean =
tp.symbol == AllClass ||
tp.symbol == AllRefClass && (sym.owner isSubClass AnyRefClass) ||
- (tp.lookupNonPrivate(sym.name).alternatives exists
+ (tp.nonPrivateMember(sym.name).alternatives exists
(alt => sym == alt || specializesSym(tp.narrow, alt, ThisType(sym.owner), sym)));
/** Does member `sym1' of `tp1' have a stronger type than member `sym2' of `tp2'? */
@@ -1116,6 +1148,7 @@ abstract class Types: SymbolTable {
!phase.exactMatch || tp1 =:= tp2
}
+ /** Prepend type `tp' to closure `cl' */
private def addClosure(tp: Type, cl: Array[Type]): Array[Type] = {
val cl1 = new Array[Type](cl.length + 1);
cl1(0) = tp;
@@ -1259,8 +1292,8 @@ abstract class Types: SymbolTable {
def lubsym(proto: Symbol): Symbol = {
val prototp = lubThisType.memberInfo(proto);
val syms = narrowts map (t =>
- t.lookup(proto.name)
- .matching(NoPrefix, prototp.substThis(lubThisType.symbol, t)));
+ t.nonPrivateMember(proto.name).suchThat(sym =>
+ sym.tpe matches prototp.substThis(lubThisType.symbol, t)));
val symtypes = List.map2(narrowts, syms)
((t, sym) => t.memberInfo(sym).substThis(t.symbol, lubThisType));
if (syms contains NoSymbol)
@@ -1276,18 +1309,16 @@ abstract class Types: SymbolTable {
.setInfo(lubBounds(symtypes map (.bounds)))
}
}
- def refines(tp: Type, sym: Symbol) = {
- val sym1 = tp.lookupNonPrivate(sym.name);
- (sym1 != NoSymbol) &&
- (sym1.alternatives forall (
- alt => !specializesSym(lubThisType, sym, tp, alt)))
+ def refines(tp: Type, sym: Symbol): boolean = {
+ val syms = tp.nonPrivateMember(sym.name).alternatives;
+ !syms.isEmpty && (syms forall (alt => !specializesSym(lubThisType, sym, tp, alt)))
}
- for (val sym <- lubBase.allPublicMembersIterator)
+ for (val sym <- lubBase.nonPrivateMembers)
// add a refinement symbol for all non-class members of lubBase
// which are refined by every type in ts.
if (!sym.isClass && (narrowts forall (t => refines(t, sym))))
- addMember(lubThisType, lubType.members, lubsym(sym));
- if (lubType.members.isEmpty) lubBase else lubType;
+ addMember(lubThisType, lubType, lubsym(sym));
+ if (lubType.decls.isEmpty) lubBase else lubType;
}
limitRecursion(ts, "least upper", lub0);
}
@@ -1311,9 +1342,10 @@ abstract class Types: SymbolTable {
val glbThisType = glbType.symbol.thisType;
def glbsym(proto: Symbol): Symbol = {
val prototp = glbThisType.memberInfo(proto);
- val syms = for (val t <- ts;
- val alt <- List.fromIterator(t.lookup(proto.name).alternatives);
- glbThisType.memberInfo(alt) matches prototp) yield alt;
+ val syms = for (
+ val t <- ts;
+ val alt <- t.nonPrivateMember(proto.name).alternatives;
+ glbThisType.memberInfo(alt) matches prototp) yield alt;
val symtypes = syms map glbThisType.memberInfo;
assert(!symtypes.isEmpty);
proto.cloneSymbol.setInfo(
@@ -1340,10 +1372,10 @@ abstract class Types: SymbolTable {
result
})
}
- for (val t <- ts; val sym <- t.allPublicMembersIterator)
+ for (val t <- ts; val sym <- t.nonPrivateMembers)
if (!(sym.isClass || (glbThisType specializes sym)))
- addMember(glbThisType, glbType.members, glbsym(sym));
- if (glbType.members.isEmpty) glbBase else glbType;
+ addMember(glbThisType, glbType, glbsym(sym));
+ if (glbType.decls.isEmpty) glbBase else glbType;
} catch {
case _: MalformedClosure =>
if (ts forall (t => t <:< AnyRefClass.tpe)) AllRefClass.tpe
@@ -1403,15 +1435,15 @@ abstract class Types: SymbolTable {
}
}
- /** Make symbol `sym' a member of scope `members' where `thistp' is the narrowed
+ /** Make symbol `sym' a member of scope `tp.decls' where `thistp' is the narrowed
* owner type of the scope */
- private def addMember(thistp: Type, members: Scope, sym: Symbol): unit = {
+ private def addMember(thistp: Type, tp: Type, sym: Symbol): unit = {
if (!(thistp specializes sym)) {
if (sym.isTerm)
- for (val alt <- members.lookup(sym.name).alternatives)
+ for (val alt <- tp.nonPrivateDecl(sym.name).alternatives)
if (specializesSym(thistp, sym, thistp, alt))
- members.unlink(alt);
- members.enter(sym)
+ tp.decls unlink alt;
+ tp.decls enter sym
}
}
diff --git a/sources/scala/tools/nsc/symtab/classfile/ClassfileConstants.scala b/sources/scala/tools/nsc/symtab/classfile/ClassfileConstants.scala
index 433ae327b8..dbda7bcc20 100644
--- a/sources/scala/tools/nsc/symtab/classfile/ClassfileConstants.scala
+++ b/sources/scala/tools/nsc/symtab/classfile/ClassfileConstants.scala
@@ -1,11 +1,8 @@
-/* ____ ____ ____ ____ ______ *\
-** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala **
-** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL **
-** /_____/\____/\___/\____/____/ **
-** **
-** $Id$
-\* */
-
+/* NSC -- new scala compiler
+ * Copyright 2005 LAMP/EPFL
+ * @author Martin Odersky
+ */
+// $Id$
package scala.tools.nsc.symtab.classfile;
object ClassfileConstants {
diff --git a/sources/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/sources/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
index 08a909c781..3531115583 100755
--- a/sources/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
+++ b/sources/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
@@ -1,11 +1,8 @@
-/* ____ ____ ____ ____ ______ *\
-** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala **
-** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL **
-** /_____/\____/\___/\____/____/ **
-** **
-** $Id$
-\* */
-
+/* NSC -- new scala compiler
+ * Copyright 2005 LAMP/EPFL
+ * @author Martin Odersky
+ */
+// $Id$
package scala.tools.nsc.symtab.classfile;
import scala.tools.util._;
@@ -22,8 +19,8 @@ abstract class ClassfileParser {
private var in: AbstractFileReader = _; // the class file
private var clazz: Symbol = _; // the class symbol containing dynamic members
private var statics: Symbol = _; // the module class symbol containing static members
- private var classMembers: Scope = _; // the scope of all dynamic members
- private var staticMembers: Scope = _; // the scope of all static members
+ private var instanceDefs: Scope = _; // the scope of all instance definitions
+ private var staticDefs: Scope = _; // the scope of all static definitions
private var pool: ConstantPool = _; // the classfile's constant pool
private var isScala: boolean = _; // does class file describe a scala class?
private var hasMeta: boolean = _; // does class file contain jaco meta attribute?s
@@ -227,10 +224,10 @@ abstract class ClassfileParser {
val parents = superType ::
(for (val i <- List.range(0, ifaceCount))
yield pool.getSuperClass(in.nextChar()).tpe);
- classMembers = new Scope();
- staticMembers = new Scope();
- val classInfo = ClassInfoType(parents, classMembers, clazz);
- val staticInfo = ClassInfoType(List(), staticMembers, statics);
+ instanceDefs = new Scope();
+ staticDefs = new Scope();
+ val classInfo = ClassInfoType(parents, instanceDefs, clazz);
+ val staticInfo = ClassInfoType(List(), staticDefs, statics);
val curbp = in.bp;
skipMembers(); // fields
@@ -365,7 +362,7 @@ abstract class ClassfileParser {
if ((flags & JAVA_ACC_STATIC) != 0) statics else clazz;
private def getScope(flags: int): Scope =
- if ((flags & JAVA_ACC_STATIC) != 0) staticMembers else classMembers;
+ if ((flags & JAVA_ACC_STATIC) != 0) staticDefs else instanceDefs;
private def transFlags(flags: int): long = {
var res = 0l;
diff --git a/sources/scala/tools/nsc/symtab/classfile/MetaParser.scala b/sources/scala/tools/nsc/symtab/classfile/MetaParser.scala
index 861fa7d853..e123de3434 100755
--- a/sources/scala/tools/nsc/symtab/classfile/MetaParser.scala
+++ b/sources/scala/tools/nsc/symtab/classfile/MetaParser.scala
@@ -1,5 +1,8 @@
-/** $Id: MetaParser.scala
-*/
+/* NSC -- new scala compiler
+ * Copyright 2005 LAMP/EPFL
+ * @author Martin Odersky
+ */
+// $Id$
package scala.tools.nsc.symtab.classfile;
import java.util.{StringTokenizer, NoSuchElementException}
@@ -110,8 +113,8 @@ abstract class MetaParser{
nextToken(); tps append parseType()
} while (token == "with");
ownertype match {
- case ClassInfoType(parents, defs, clazz) =>
- ClassInfoType(tps.toList, defs, clazz)
+ case ClassInfoType(parents, decls, clazz) =>
+ ClassInfoType(tps.toList, decls, clazz)
}
} else ownertype
}
diff --git a/sources/scala/tools/nsc/symtab/classfile/Pickle.scala b/sources/scala/tools/nsc/symtab/classfile/Pickle.scala
index 37ba9cf47e..e7f1271761 100644
--- a/sources/scala/tools/nsc/symtab/classfile/Pickle.scala
+++ b/sources/scala/tools/nsc/symtab/classfile/Pickle.scala
@@ -1,3 +1,8 @@
+/* NSC -- new scala compiler
+ * Copyright 2005 LAMP/EPFL
+ * @author Martin Odersky
+ */
+// $Id$
package scala.tools.nsc.symtab.classfile;
/***************************************************
diff --git a/sources/scala/tools/nsc/symtab/classfile/UnPickle.scala b/sources/scala/tools/nsc/symtab/classfile/UnPickle.scala
index 07ab81ff67..0a5ca5511c 100755
--- a/sources/scala/tools/nsc/symtab/classfile/UnPickle.scala
+++ b/sources/scala/tools/nsc/symtab/classfile/UnPickle.scala
@@ -1,5 +1,8 @@
-//import scalac.{symtab => scalac_symtab}
-
+/* NSC -- new scala compiler
+ * Copyright 2005 LAMP/EPFL
+ * @author Martin Odersky
+ */
+// $Id$
package scala.tools.nsc.symtab.classfile {
//import scalac_symtab.Modifiers;
@@ -134,9 +137,9 @@ abstract class UnPickle {
assert(tag != EXTref);
global.definitions.RootClass
} else if (tag == EXTMODCLASSref) {
- owner.info.lookup(name).moduleClass
+ owner.info.decl(name).moduleClass
} else {
- owner.info.lookup(name)
+ owner.info.decl(name)
}
entries(i) = sym;
if (sym == NoSymbol)
@@ -230,7 +233,7 @@ abstract class UnPickle {
def enterSymbol(sym: Symbol): unit =
if (sym.owner.isClass && !sym.isModuleClass) {
if (settings.debug.value) global.log("entering " + sym + ":" + sym.tpe + " in " + sym.owner);//debug
- val scope = sym.owner.info.members;
+ val scope = sym.owner.info.decls;
val other = scope.lookup(sym.name);
if (other != sym) {
sym.info match {
diff --git a/sources/scala/tools/nsc/typechecker/Analyzer.scala b/sources/scala/tools/nsc/typechecker/Analyzer.scala
index d519a895d8..fe01281247 100644
--- a/sources/scala/tools/nsc/typechecker/Analyzer.scala
+++ b/sources/scala/tools/nsc/typechecker/Analyzer.scala
@@ -1,3 +1,8 @@
+/* NSC -- new scala compiler
+ * Copyright 2005 LAMP/EPFL
+ * @author Martin Odersky
+ */
+// $Id$
package scala.tools.nsc.typechecker;
import scala.tools.util.Position;
diff --git a/sources/scala/tools/nsc/typechecker/Contexts.scala b/sources/scala/tools/nsc/typechecker/Contexts.scala
new file mode 100755
index 0000000000..78112ad604
--- /dev/null
+++ b/sources/scala/tools/nsc/typechecker/Contexts.scala
@@ -0,0 +1,98 @@
+/* NSC -- new scala compiler
+ * Copyright 2005 LAMP/EPFL
+ * @author Martin Odersky
+ */
+// $Id$
+package scala.tools.nsc.typechecker;
+
+import scala.tools.util.Position;
+
+class Contexts: Analyzer {
+ import global._;
+
+ val NoContext = new Context();
+
+ val startContext = {
+ import definitions._;
+ var sc = NoContext.make(EmptyTree, RootClass, RootClass.info.decls);
+ def addImport(pkg: Symbol): unit = {
+ sc = sc.make(sc.tree, sc.owner, new Scope(sc.scope));
+ val impTree = Import(gen.mkGlobalRef(pkg), List(Pair(nme.WILDCARD, null)));
+ impTree.setSymbol(NoSymbol.newImport(Position.NOPOS)).setType(ImportType(impTree));
+ sc.scope.enter(impTree.symbol)
+ }
+ if (!settings.noimports.value) {
+ addImport(JavaLangPackage);
+ addImport(ScalaPackage);
+ if (!settings.nopredefs.value)
+ addImport(PredefModule);
+ }
+ sc
+ }
+
+ class Context {
+ var unit: CompilationUnit = _;
+ var tree: Tree = _; // Tree associated with this context
+ var owner: Symbol = _; // The current owner
+ var scope: Scope = _; // The current scope
+ var outer: Context = _; // The next outer context
+ var enclClass: Context = this; // The next outer context whose tree
+ // is a class template
+ var variance: int = _; // Variance relative to enclosing class.
+ var constructorClass: Symbol = _; // Class for auxiliary constructor
+ var depth: int = 0;
+ val imports: List[Tree] = List();
+
+ def make(unit: CompilationUnit, tree: Tree, owner: Symbol, scope: Scope): Context = {
+ val c = new Context();
+ c.unit = unit;
+ c.tree = tree;
+ c.owner = owner;
+ c.scope = scope;
+ c.enclClass = if ((tree.isInstanceOf[Template] ||
+ tree.isInstanceOf[IntersectionTypeTree]) &&
+ tree != this.tree) c
+ else this.enclClass;
+ c.variance = this.variance;
+ c.constructorClass = this.constructorClass;
+ c.depth = this.depth + 1;
+ c.outer = this;
+ c
+ }
+
+ def make(unit: CompilationUnit): Context =
+ make(unit, EmptyTree, this.owner, new Scope(this.owner.info.decls));
+
+ def make(tree: Tree, owner: Symbol, scope: Scope): Context =
+ make(this.unit, tree, owner, scope);
+
+ def makeNewScope(tree: Tree, owner: Symbol): Context =
+ make(tree, owner, new Scope(this.scope));
+
+ def make(tree: Tree, owner: Symbol): Context =
+ make(tree, owner, this.scope);
+
+ def make(tree: Tree): Context =
+ make(tree, this.owner);
+
+ def outerContext(clazz: Symbol): Context = {
+ var c = this;
+ while (c != NoContext && c.owner != clazz) c = c.outer.enclClass;
+ c
+ }
+
+ def isLocal(): boolean = tree match {
+ case Block(_,_) => true
+ case PackageDef(_, _) => false
+ case EmptyTree => false
+ case _ => outer.isLocal()
+ }
+
+ override def toString(): String = {
+ if (this == NoContext) "NoContext";
+ else tree.toString() + "\n:: " + outer.toString()
+ }
+ }
+}
+
+
diff --git a/sources/scala/tools/nsc/typechecker/DeSugarizePhase.scala b/sources/scala/tools/nsc/typechecker/DeSugarizePhase.scala
new file mode 100755
index 0000000000..01c1789435
--- /dev/null
+++ b/sources/scala/tools/nsc/typechecker/DeSugarizePhase.scala
@@ -0,0 +1,219 @@
+/* NSC -- new scala compiler
+ * Copyright 2005 LAMP/EPFL
+ * @author Martin Odersky
+ */
+// $Id$
+package scala.tools.nsc.typechecker;
+
+import symtab.Flags._;
+import scala.collection.mutable.ListBuffer;
+
+/** Performs the following context-free rewritings:
+ * (1) Places all pattern variables in Bind nodes. In a pattern, for identifiers `x':
+ * x => x @ _
+ * x:T => x @ (_ : T)
+ *
+ * (2) Removes pattern definitions (PatDef's) as follows:
+ * If pattern is a simple (typed) identifier:
+ * val x = e ==> val x = e
+ * val x: T = e ==> val x: T = e
+ *
+ * if there are no variables in pattern
+ * val p = e ==> e.match (case p => ())
+ *
+ * if there is exactly one variable in pattern
+ * val x_1 = e.match (case p => (x_1))
+ *
+ * if there is more than one variable in pattern
+ * val p = e ==> private synthetic val t$ = e.match (case p => (x_1, ..., x_N))
+ * val x_1 = t$._1
+ * ...
+ * val x_N = t$._N
+ *
+ * (3) Removes function types as follows:
+ * (argtpes) => restpe ==> scala.Function_n[argtpes, restpe]
+ *
+ * (4) Wraps naked case definitions in a match as follows:
+ * { cases } ==> (x => x.match {cases}), except when already argument to match
+ */
+abstract class DeSugarizePhase(prev: Phase) extends StdPhase(prev) {
+ import global._;
+ import posAssigner.atPos;
+
+ def name = "desugarize";
+ def apply(unit: CompilationUnit): unit =
+ unit.body = new DeSugarizer(unit).transformTrees(unit.body);
+
+ class DeSugarizer(unit: CompilationUnit) extends Transformer {
+
+ /** introduce fresh variable of the form "ds$56"
+ */
+ private def getvar: Name = unit.fresh.newName("ds$");
+
+ /** in patterns x => x @ _
+ * x:T => x @ (_ : T)
+ */
+ object patvarTransformer extends Transformer {
+ override def transform(tree: Tree): Tree = tree match {
+ case Ident(name) if (treeInfo.isVariableName(name) && name != nme.WILDCARD) =>
+ atPos(tree.pos)(Bind(name, Ident(nme.WILDCARD)))
+ case Typed(id @ Ident(name), tpt) =>
+ Bind(name, atPos(tree.pos)(Typed(Ident(nme.WILDCARD), tpt))) setPos id.pos
+ case Apply(fn @ Apply(_, _), args) =>
+ copy.Apply(tree, transform(fn), transformTrees(args))
+ case Apply(fn, args) =>
+ copy.Apply(tree, fn, transformTrees(args))
+ case Sequence(_) | Alternative(_) | Bind(_, _) | Typed(_, _) =>
+ super.transform(tree)
+ case _ =>
+ tree
+ }
+ }
+
+ /** Traverse pattern and collect all variable names in buffer */
+ object getvarTraverser extends Traverser {
+ val buf = new ListBuffer[Name];
+ def init: Traverser = { buf.clear; this }
+ override def traverse(tree: Tree): unit = tree match {
+ case Bind(name, tpe) =>
+ if (buf.elements forall (name !=)) buf += name;
+ traverse(tpe)
+ case _ => super.traverse(tree)
+ }
+ }
+
+ /** Returns list of all pattern variables without duplicates */
+ private def getVariables(tree: Tree): List[Name] = {
+ getvarTraverser.init.traverse(tree);
+ getvarTraverser.buf.toList
+ }
+
+ /** Expand patdefs */
+ private def transformStat(tree: Tree): List[Tree] = {
+ def rebox(defs: List[Tree], boxf: Tree => Tree): List[Tree] = defs match {
+ case List(stat) => List(if (stat.isDef) boxf(stat) else stat);
+ case stat :: stats => stat :: (stats map boxf)
+ }
+ def mkTuple(trees: List[Tree]): Tree = trees match {
+ case List() => Literal(())
+ case List(tree) => tree
+ case _ => Apply(Select(Ident(nme.scala), newTermName("Tuple" + trees.length)), trees)
+ }
+ tree match {
+ // pattern definitions:
+ // val x = e ==> val x = e
+ case PatDef(mods, Ident(name), rhs) =>
+ List(atPos(tree.pos)(ValDef(mods, name, EmptyTypeTree(), rhs)))
+
+ // val (x @ _) = e ==> val x = e
+ case PatDef(mods, Bind(name, Ident(nme.WILDCARD)), rhs) =>
+ List(atPos(tree.pos)(ValDef(mods, name, EmptyTypeTree(), rhs)))
+
+ // val x: T = e ==> val x: T = e
+ case PatDef(mods, Typed(Ident(name), tpt), rhs) =>
+ List(atPos(tree.pos)(ValDef(mods, name, tpt, rhs)))
+
+ // val x @ (_: T) = e ==> val x: T = e
+ case PatDef(mods, Bind(name, Typed(Ident(nme.WILDCARD), tpt)), rhs) =>
+ List(atPos(tree.pos)(ValDef(mods, name, tpt, rhs)))
+
+ // in case there are no variables in pattern
+ // val p = e ==> e.match (case p => ())
+ //
+ // in case there is exactly one variable in pattern
+ // val x_1 = e.match (case p => (x_1))
+ //
+ // in case there are more variables in pattern
+ // val p = e ==> private synthetic val t$ = e.match (case p => (x_1, ..., x_N))
+ // val x_1 = t$._1
+ // ...
+ // val x_N = t$._N
+ case PatDef(mods, pat, rhs) =>
+ val vars = getVariables(pat);
+ val matchExpr = atPos(pat.pos) {
+ Apply(
+ Select(rhs, nme._match),
+ List(Visitor(List(CaseDef(pat, EmptyTree, mkTuple(vars map Ident))))))
+ }
+ vars match {
+ case List() =>
+ List(matchExpr)
+ case List(vname) =>
+ List(ValDef(mods, vname, EmptyTypeTree(), matchExpr))
+ case _ =>
+ val tmp = getvar;
+ val firstDef = ValDef(PRIVATE | LOCAL | SYNTHETIC,
+ tmp, EmptyTypeTree(), matchExpr);
+ var cnt = 0;
+ val restDefs = for (val v <- vars) yield {
+ cnt = cnt + 1;
+ val selector = newTermName("_" + cnt);
+ ValDef(mods, v, EmptyTypeTree(), Select(Ident(tmp), selector))
+ }
+ firstDef :: restDefs
+ } map atPos(tree.pos)
+
+ case DocDef(comment, defn) =>
+ rebox(transformStat(defn), t => DocDef(comment, t))
+
+ case Attributed(attribute, defn) =>
+ rebox(transformStat(defn), t => Attributed(attribute, t))
+
+ case _ =>
+ List(tree)
+ }
+ }
+
+ /** Expand patdefs in list of statements */
+ private def transformStats(trees: List[Tree]): List[Tree] = {
+ def isPatDef(tree: Tree): boolean = tree match {
+ case PatDef(_, _, _) => true
+ case DocDef(_, defn) => isPatDef(defn)
+ case Attributed(_, defn) => isPatDef(defn)
+ case _ => false
+ }
+ if (trees exists isPatDef) trees flatMap transformStat else trees
+ }
+
+ /** desugarize tree */
+ override def transform(tree: Tree): Tree = tree match {
+ // (argtpes) => restpe ==> scala.Function_n[argtpes, restpe]
+ case FunctionTypeTree(argtpes, restpe) =>
+ atPos(tree.pos) (
+ AppliedTypeTree(
+ Select(Ident(nme.scala), newTypeName("Function" + argtpes.length)),
+ transformTrees(argtpes) ::: List(transform(restpe))))
+
+ // { cases } ==> (x => x.match {cases}), except when already argument to match
+ case Apply(s @ Select(x, nme._match), List(v @ Visitor(cases))) =>
+ copy.Apply(tree,
+ copy.Select(s, transform(x), nme._match),
+ List(copy.Visitor(v, transformCaseDefs(cases))))
+
+ case Apply(Ident(nme._match), List(v @ Visitor(cases))) =>
+ copy.Apply(tree,
+ Select(This(nme.EMPTY.toTypeName), nme._match),
+ List(copy.Visitor(v, transformCaseDefs(cases))))
+
+ case Visitor(cases) =>
+ val x = getvar;
+ atPos(tree.pos)(
+ Function(
+ List(ValDef(PARAM, x, EmptyTypeTree(), EmptyTree)),
+ Apply(Select(Ident(x), nme._match), List(super.transform(tree)))))
+
+ case CaseDef(pat, guard, body) =>
+ copy.CaseDef(tree, transform(patvarTransformer.transform(pat)),
+ transform(guard), transform(body))
+
+ case PatDef(mods, pat, rhs) =>
+ copy.PatDef(tree, mods, transform(patvarTransformer.transform(pat)), transform(rhs))
+
+ case Template(parents, body) =>
+ copy.Template(tree, transformTrees(parents), transformStats(transformTrees(body)))
+
+ case Block(stats, expr) =>
+ copy.Block(tree, transformStats(transformTrees(stats)), transform(expr))
+ }
+ }
+}
diff --git a/sources/scala/tools/nsc/typechecker/Namers.scala b/sources/scala/tools/nsc/typechecker/Namers.scala
new file mode 100755
index 0000000000..1215c5ddfb
--- /dev/null
+++ b/sources/scala/tools/nsc/typechecker/Namers.scala
@@ -0,0 +1,166 @@
+/* NSC -- new scala compiler
+ * Copyright 2005 LAMP/EPFL
+ * @author Martin Odersky
+ */
+// $Id$
+package scala.tools.nsc.typechecker;
+
+import scala.tools.util.Position;
+import symtab.Flags._;
+
+/** Methods to create symbols and to enter them into scopes. */
+trait Namers: Analyzer {
+ import global._;
+
+ class NamerPhase(prev: Phase) extends StdPhase(prev) {
+ def name = "namer";
+ val global: Namers.this.global.type = Namers.this.global;
+ def apply(unit: CompilationUnit): unit =
+ new Namer(startContext.make(unit)).enterSyms(unit.body);
+ }
+
+ class Namer(context: Context) {
+
+ val typer = new Typer(context);
+
+ 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()));
+
+ private def updatePosFlags(sym: Symbol, pos: int, mods: int): Symbol = {
+ val sym1 = if (sym.isExternal && !sym.isPackage) sym
+ else { doubleDefError(pos, sym); sym.cloneSymbol }
+ sym1.pos = pos;
+ val oldflags = sym1.rawflags & (INITIALIZED | LOCKED);
+ val newflags = mods & ~(INITIALIZED | LOCKED);
+ sym1.rawflags = oldflags | newflags;
+ if (sym1.isModule)
+ updatePosFlags(sym1.moduleClass, pos, (mods & MODULE2CLASSFLAGS) | MODULE | FINAL);
+ sym1
+ }
+
+ private def enterInScope(pos: int, sym: Symbol): Symbol = {
+ if (!(sym.isMethod && sym.owner.isClass)) {
+ val prev = context.scope.lookupEntry(sym.name);
+ if (prev != null && prev.owner == context.scope && !prev.sym.isMethod)
+ doubleDefError(pos, prev.sym);
+ }
+ context.scope enter sym;
+ sym
+ }
+
+ private def enterPackageSymbol(pos: int, name: Name): Symbol = {
+ val p: Symbol = context.scope.lookup(name);
+ if (p.isPackage && context.scope == p.owner.info.decls) {
+ p.pos = pos; p.moduleClass.pos = pos; p
+ } else {
+ enterInScope(pos, context.owner.newPackage(pos, name))
+ }
+ }
+
+ private def enterClassSymbol(pos: int, mods: int, name: Name): Symbol = {
+ val c: Symbol = context.scope.lookup(name);
+ if (c.isType && context.scope == c.owner.info.decls) {
+ updatePosFlags(c, pos, mods)
+ } else {
+ enterInScope(pos, context.owner.newClass(pos, name).setFlag(mods))
+ }
+ }
+
+ private def enterModuleSymbol(pos: int, mods: int, name: Name): Symbol = {
+ val m: Symbol = context.scope.lookup(name);
+ if (m.isModule && context.scope == m.owner.info.decls) {
+ updatePosFlags(m, pos, mods)
+ } else {
+ val newm = context.owner.newModule(pos, name);
+ newm.setFlag(mods);
+ newm.moduleClass.setFlag(mods);
+ enterInScope(pos, newm)
+ }
+ }
+
+ private def enterCaseFactorySymbol(pos: int, mods: int, name: Name): Symbol = {
+ val m: Symbol = context.scope.lookup(name);
+ if (m.isModule && context.scope == m.owner.info.decls) {
+ updatePosFlags(m, pos, mods)
+ } else {
+ enterInScope(pos, context.owner.newMethod(pos, name).setFlag(mods))
+ }
+ }
+
+ def enterSyms(trees: List[Tree]): unit =
+ for (val tree <- trees) enterSym(tree);
+
+ def enterSym(tree: Tree): Symbol = {
+
+ def finishWith(tparams: List[AbsTypeDef]) = {
+ val ltype = typer.typeCompleter(tree);
+ def makeParam(tparam: AbsTypeDef): Symbol =
+ tree.symbol.newTypeParameter(tparam.pos, tparam.name);
+ tree.symbol.setInfo(
+ if (tparams.isEmpty) ltype
+ else new LazyPolyType(tparams map makeParam, ltype))
+ }
+ def finish = finishWith(List());
+
+ if (tree.symbol != null) tree.symbol
+ else {
+ val owner = context.owner;
+ tree match {
+ case PackageDef(name, stats) =>
+ tree.symbol = enterPackageSymbol(tree.pos, name);
+ val namer = new Namer(
+ context.make(tree, tree.symbol.moduleClass, tree.symbol.info.decls));
+ stats map namer.enterSym;
+ tree.symbol
+ case ClassDef(mods, name, tparams, _, _) =>
+ if ((mods & (CASE | ABSTRACT)) == CASE) { // enter case factory method.
+ tree.symbol = enterCaseFactorySymbol(
+ tree.pos, mods & ACCESSFLAGS | CASE, name.toTermName);
+ finishWith(tparams);
+ }
+ tree.symbol = enterClassSymbol(tree.pos, mods, name);
+ val constr = tree.symbol.newConstructor(tree.pos)
+ .setFlag(tree.symbol.rawflags & CONSTRFLAGS)
+ .setInfo(typer.typeCompleter(tree));
+ tree.symbol.info.decls enter constr;
+ finishWith(tparams)
+ case ModuleDef(mods, name, _, _) =>
+ tree.symbol = enterModuleSymbol(tree.pos, mods, name);
+ tree.symbol.moduleClass.setInfo(typer.typeCompleter(tree));
+ finish
+ case ValDef(mods, name, tp, rhs) =>
+ tree.symbol = enterInScope(tree.pos, owner.newValue(tree.pos, name).setFlag(mods));
+ finish
+ case DefDef(mods, nme.CONSTRUCTOR, tparams, vparams, tp, rhs) =>
+ if (!(owner.isClass && context.scope == owner.info.decls) ||
+ owner.isModuleClass || owner.isAnonymousClass || owner.isRefinementClass)
+ context.unit.error(tree.pos, "constructor definition not allowed here");
+ tree.symbol = enterInScope(tree.pos, owner.newConstructor(tree.pos))
+ .setFlag(mods | owner.rawflags & CONSTRFLAGS);
+ finishWith(tparams)
+ case DefDef(mods, name, tparams, _, _, _) =>
+ tree.symbol = enterInScope(tree.pos, owner.newMethod(tree.pos, name)).setFlag(mods);
+ finishWith(tparams)
+ case AbsTypeDef(mods, name, _, _) =>
+ tree.symbol = enterInScope(tree.pos, owner.newAbstractType(tree.pos, name));
+ finish
+ case AliasTypeDef(mods, name, tparams, _) =>
+ tree.symbol = enterInScope(tree.pos, owner.newAliasType(tree.pos, name));
+ finishWith(tparams)
+ case Attributed(_, defn) =>
+ enterSym(defn)
+ case DocDef(_, defn) =>
+ enterSym(defn)
+ case Import(expr, selectors) =>
+ tree.symbol = NoSymbol.newImport(tree.pos);
+ finish
+ case _ =>
+ NoSymbol
+ }
+ }
+ }
+ }
+}
+
diff --git a/sources/scala/tools/nsc/typechecker/TypeCheckers.scala b/sources/scala/tools/nsc/typechecker/TypeCheckers.scala
new file mode 100755
index 0000000000..01f0e26f03
--- /dev/null
+++ b/sources/scala/tools/nsc/typechecker/TypeCheckers.scala
@@ -0,0 +1,246 @@
+/* NSC -- new scala compiler
+ * Copyright 2005 LAMP/EPFL
+ * @author Martin Odersky
+ */
+// $Id$
+package scala.tools.nsc.typechecker;
+
+import scala.tools.util.Position;
+
+/** Methods to create symbols and to enter them into scopes. */
+trait TypeCheckers: Analyzer {
+ import symtab.Flags._;
+ import global._;
+
+ class TypeCheckPhase(prev: Phase) extends StdPhase(prev) {
+ def name = "typechecker";
+ val global: TypeCheckers.this.global.type = TypeCheckers.this.global;
+ def apply(unit: CompilationUnit): unit =
+ unit.body = new TypeChecker(startContext.make(unit)).transformTrees(unit.body);
+ }
+
+ class TypeChecker(context: Context) extends Transformer {
+
+ import global._;
+ import context.unit;
+
+ def error(pos: int, msg: String) = unit.error(pos, msg);
+
+ def reportTypeError(pos: int, ex: TypeError): unit = {
+ if (settings.debug.value) ex.printStackTrace();
+ ex match {
+ case CyclicReference(sym, info: TypeCompleter) =>
+ info.tree match {
+ case ValDef(_, _, EmptyTypeTree(), _) =>
+ error(pos, "recursive " + sym + " needs type")
+ case DefDef(_, _, _, _, EmptyTypeTree(), _) =>
+ error(pos, "recursive " + sym + " needs result type")
+ case _ =>
+ error(pos, ex.getMessage())
+ }
+ case _ =>
+ error(pos, ex.getMessage())
+ }
+ }
+
+ def reenterValueParams(tree: Tree): unit = tree match {
+ case DefDef(_, _, _, vparamss, _, _) =>
+ for (val vparams <- vparamss; val vparam <- vparams) context.scope enter vparam.symbol
+ }
+
+ def checkStable(tree: Tree): Tree = tree;
+ def checkNoEscape(pos: int, tpe: Type): Type = tpe;
+
+ def transformConstr(tree: Tree): Tree = tree;
+ def transformExpr(tree: Tree): Tree = tree;
+ def transformType(tree: Tree): Tree = tree;
+
+ abstract class ResolveError extends TermSymbol(NoSymbol, Position.NOPOS, nme.EMPTY) {
+ setFlag(IS_ERROR);
+ def msg(qual: Tree, name: Name): String;
+ }
+
+ object NotFoundError extends ResolveError {
+ def msg(qual: Tree, name: Name) = name.decode + " is not a member of " + qual;
+ }
+
+ object NotAccessibleError extends TermSymbol(NoSymbol, Position.NOPOS, nme.EMPTY) {
+ def msg(qual: Tree, name: Name) = name.decode + " is not accessible in " + qual;
+ }
+
+ def transform(tree: Tree, mode: int, pt: Type): Tree = {
+
+ def stabilize(tree: Tree, pre: Type): Tree = tree;
+
+ /** Attribute an identifier consisting of a simple name or an outer reference.
+ * @param tree The tree representing the identifier.
+ * @param name The name of the identifier.
+ * Transformations: (1) Prefix class members with this.
+ * (2) Change imported symbols to selections
+ */
+ def transformIdent(name: Name): Tree = {
+ def ambiguousError(msg: String) =
+ unit.error(tree.pos, "reference to " + name + " is ambiguous;\n" + msg);
+ def importTree(imp: Symbol) =
+ imp.info.asInstanceOf[ImportType].tree;
+ def importedSymbol(imp: Symbol) =
+ treeInfo.importedSymbol(importTree(imp), name);
+ def isExplicitImport(imp: Symbol) =
+ treeInfo.isExplicitImport(importTree(imp), name);
+ //System.out.println("transforming " + name);//DEBUG
+
+ // Compute values of the following 4 variables,
+ // except that `pre' is only set for directly inherited symbols.
+ // Also detect double imports.
+ var sym: Symbol = NoSymbol; // the directly found symbol
+ var sym1: Symbol = NoSymbol; // the imported symbol
+ var pre: Type = null; // if symbols are class members, their prefix type
+ var impSym = NoSymbol; // if symbols are imported, the import symbol from
+ // which they were imported.
+ var cx: Context = context;
+ while (sym == NoSymbol && cx != NoContext) {
+ val symEntry = cx.scope.lookupEntry(name);
+ var impEntry = cx.scope.lookupEntry(nme.IMPORT);
+ while (impEntry != null) {
+ var impSym1 = impEntry.sym;
+ impEntry = cx.scope.lookupNextEntry(impEntry);
+ sym1 = importedSymbol(impSym1);
+ if (sym1 != NoSymbol) { // check whether shadowed by sym, reset to NoSymbol if yes.
+ if (symEntry != null) {
+ var impEntry1 = symEntry.owner.lookupEntry(nme.IMPORT);
+ while (impEntry1 != null && sym1 != NoSymbol) {
+ if (impEntry1.sym == impSym1) sym1 = NoSymbol;
+ // directly found takes precedence
+ impEntry1 = symEntry.owner.lookupNextEntry(impEntry1);
+ }
+ }
+ }
+ if (sym1 != NoSymbol) { // check for ambiguous imports
+ var impSym2: Symbol = NoSymbol; // alternative import symbol
+ var sym2: Symbol = NoSymbol; // alternative imported symbol
+ def ambiguousImportError = ambiguousError(
+ "it is imported twice in the same scope by\n" +
+ importTree(impSym1) + "\nand " + importTree(impSym2));
+ while (impEntry != null) {
+ impSym2 = impEntry.sym;
+ impEntry = cx.scope.lookupNextEntry(impEntry);
+ if (impSym2.owner == impSym1.owner) {
+ sym2 = importedSymbol(impSym2);
+ if (sym2 != NoSymbol) {
+ if (isExplicitImport(impSym2)) {
+ if (isExplicitImport(impSym1)) ambiguousImportError;
+ sym1 = sym2;
+ impSym1 = impSym2;
+ }
+ if (isExplicitImport(impSym1)) sym2 = NoSymbol;
+ }
+ }
+ }
+ if (sym2 != NoSymbol) ambiguousImportError
+ }
+ }
+ if (symEntry != null) sym = symEntry.sym;
+ cx = cx.enclClass;
+ if (cx != NoContext) {
+ pre = cx.owner.thisType;
+ if (sym == NoSymbol) sym = pre.member(name);
+ cx = cx.outer;
+ }
+ }
+
+ // detect ambiguous definition/import,
+ // update `sym' to be the final resolved symbol,
+ // update `pre' to be `sym's prefix type in case it is a class member,
+ // and compute value of:
+ var qual: Tree = EmptyTree; // the qualififier tree if transformed tree is a select
+ if (sym != NoSymbol) {
+ if (sym1 != NoSymbol)
+ ambiguousError(
+ "it is both defined in " + sym.owner +
+ " and imported subsequently by \n" + importTree(impSym));
+ else if (sym.owner.isClass && !sym.owner.isPackageClass)
+ qual = gen.This(tree.pos, pre.symbol);
+ } else {
+ if (sym1 != NoSymbol) {
+ sym = sym1;
+ qual = importTree(impSym).expr.duplicate;
+ pre = qual.tpe;
+ } else {
+ error(tree.pos, "not found: " + name.decode);
+ sym = context.owner.newErrorSymbol(name);
+ }
+ }
+ val symtype = pre.memberType(sym);
+ if (symtype == NoType) error(tree.pos, "not found: " + name.decode);
+ if (qual == EmptyTree) stabilize(tree.setSymbol(sym).setType(symtype), pre)
+ else transform(Select(qual, name) setPos tree.pos, mode, pt)
+ }
+ tree//for now
+ }
+ }
+}
+
+/*
+ def resolveSymbol(pos: int, qual: Tree, name: Name): Symbol = {
+ def chekFeasible(sym: Symbol): Symbol = {
+
+
+ var best: Symbol = notFoundError;
+ var multiple = false;
+ var alts = pre.lookupAll(name);
+ while (alts.hasNext) {
+ val alt = checkFeasible(alts.next);
+ if (!improves(best, alt)) {
+ multiple = !best.isError;
+ best = alt;
+ }
+ }
+ if (multiple) {
+ alts = pre.lookupAll(name);
+ while (alts.hasNext) {
+ val alt = checkFeasible(alts.next);
+ if (!improves(best, alt)) {
+ error(pos,
+ "ambiguous reference to overloaded definition,\n" +
+ "both " + sym1 + ": " + pre.memberType(sym1) + "\n" +
+ "and " + sym2 + ": " + pre.memberTyoe(sym2) + "\nmatch" +
+ context.resolveContext);
+ }
+ }
+ }
+ best match {
+ case err: ResolveError => error(pos, err.msg);
+ case _ => best
+ }
+ }
+
+ /** Attribute a selection where `tree' is `qual.name'.
+ * `qual' is already attributed.
+ */
+ def transformSelect(tree: Tree, qual0: Tree, name: Name): Tree = {
+ val qual = qual0;
+ var uninst: List[Symbol] = List();
+ qual.tpe match {
+ case PolyType(tparams, restpe) =>
+ qual = mkTypeApply(qual, tparams, restype, tparams map (.tpe));
+ uninst = tparams;
+ case _ =>
+ }
+ val sym = resolveSymbol(qual, name);
+ // if (sym == NoSymbol) try to insert view.
+ if (!uninst.isEmpty) {
+ def polymorphize(tp: Type): Type = tp match {
+ case PolyType(tparams, restpe) => PolyType(tparams, polymorphize(restpe))
+ case _ => PolyType(uninst, tp)
+ }
+ symtype = polymorphize(symtype);
+ }
+ //System.out.println(qual.getType() + ".member: " + sym + ":" + symtype);//DEBUG
+ val tree1: Tree = tree match {
+ case Select(_, _) => copy.Select(tree, sym, qua);
+ case SelectFromType(_, _) => copy.SelectFromType(tree, sym, qual)
+ }
+ mkStable(tree1.setType(symtype), qualtype)
+ }
+
+*/
diff --git a/sources/scala/tools/nsc/typechecker/Typers.scala b/sources/scala/tools/nsc/typechecker/Typers.scala
new file mode 100755
index 0000000000..e14628ab90
--- /dev/null
+++ b/sources/scala/tools/nsc/typechecker/Typers.scala
@@ -0,0 +1,217 @@
+/* NSC -- new scala compiler
+ * Copyright 2005 LAMP/EPFL
+ * @author Martin Odersky
+ */
+// $Id$
+package scala.tools.nsc.typechecker;
+
+import scala.tools.util.Position;
+
+/** Methods to create symbols and to enter them into scopes. */
+trait Typers: Analyzer {
+ import symtab.Flags;
+ import symtab.Flags._;
+ import global._;
+
+ abstract class TypeCompleter(val tree: Tree) extends LazyType;
+
+ class Typer(context: Context) {
+ import context.unit;
+
+ val typechecker = new TypeChecker(context);
+
+ def typeCompleter(tree: Tree) = new TypeCompleter(tree) {
+ override def complete(sym: Symbol): unit = {
+ if (settings.debug.value) log("defining " + sym);
+ sym.setInfo(typeSig(tree));
+ if (settings.debug.value) log("defined " + sym);
+ validate(sym);
+ }
+ }
+
+ def selfTypeCompleter(tree: Tree) = new TypeCompleter(tree) {
+ override def complete(sym: Symbol): unit =
+ sym.setInfo(typechecker.transformType(tree).tpe)
+ }
+
+ private def constrType(constr: Tree): Type = constr match {
+ case Apply(fn, args) =>
+ val ctp = constrType(fn);
+ if (ctp.typeParams.isEmpty) ctp else typechecker.transformConstr(constr).tpe
+ case _ => typechecker.transformType(constr).tpe
+ }
+
+ private def deconstIfNotFinal(sym: Symbol, tpe: Type): Type =
+ if (sym.isVariable || !sym.hasFlag(FINAL)) tpe.deconst else tpe;
+
+ 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 enterValueParam(param: ValDef): Symbol = {
+ param.symbol = owner.newValueParameter(param.pos, param.name)
+ .setInfo(typeCompleter(param));
+ context.scope enter param.symbol;
+ param.symbol
+ }
+ vparamss.map(.map(enterValueParam))
+ }
+
+ /** A creator for polytypes. If tparams is empty, simply returns result type */
+ private def makePolyType(tparams: List[Symbol], tpe: Type): Type =
+ if (tparams.isEmpty) tpe
+ else
+ PolyType(tparams, tpe match {
+ case PolyType(List(), tpe1) => tpe1
+ case _ => tpe
+ });
+
+ private def templateSig(clazz: Symbol, templ: Template): Type = {
+ // determine parent types
+ val parents = templ.parents map constrType;
+ if (!parents.isEmpty && parents.head.symbol.hasFlag(INTERFACE)
+ && parents.head.symbol.hasFlag(JAVA))
+ unit.error(templ.parents.head.pos, "cannot extend a Java interface");
+
+ // enter all members
+ val decls = new Scope();
+ new Namer(context.make(templ, clazz, decls)).enterSyms(templ.body);
+ ClassInfoType(parents, decls, clazz)
+ }
+
+ private def classSig(clazz: Symbol,
+ tparams: List[AbsTypeDef],
+ tpt: Tree, impl: Template): Type = {
+ val tparamSyms = enterTypeParams(clazz, tparams);
+ if (!tpt.isEmpty) clazz.typeOfThis = selfTypeCompleter(tpt);
+ val constrTree = treeInfo.firstConstructor(impl.body);
+ val constr = new Namer(context).enterSym(constrTree).initialize;
+ typechecker.reenterValueParams(constrTree);
+ makePolyType(tparamSyms, templateSig(clazz, impl))
+ }
+
+ private def methodSig(meth: Symbol,
+ tparams: List[AbsTypeDef], vparamss: List[List[ValDef]],
+ tpt: Tree, rhs: Tree): Type = {
+ val tparamSyms = enterTypeParams(meth, tparams);
+ val vparamSymss = enterValueParams(meth, vparamss);
+ val restype =
+ typechecker.checkNoEscape(tpt.pos,
+ deconstIfNotFinal(meth,
+ if (meth.name == nme.CONSTRUCTOR) context.enclClass.owner.tpe
+ else if (tpt.tpe != null) tpt.tpe
+ else if (tpt.isEmpty) { tpt.tpe = typechecker.transformExpr(rhs).tpe; tpt.tpe }
+ else typechecker.transformType(tpt).tpe));
+ def mkMethodType(vparams: List[Symbol], restpe: Type) =
+ MethodType(vparams map (.tpe), restpe);
+ makePolyType(
+ tparamSyms,
+ if (vparamSymss.isEmpty) PolyType(List(), restype)
+ else (vparamSymss :\ restype)(mkMethodType))
+ }
+
+ private def aliasTypeSig(tpsym: Symbol, tparams: List[AbsTypeDef], rhs: Tree): Type =
+ makePolyType(enterTypeParams(tpsym, tparams), typechecker.transformType(rhs).tpe);
+
+ private def typeSig(tree: Tree): Type =
+ try {
+ val sym: Symbol = tree.symbol;
+ tree match {
+ case ClassDef(_, _, tparams, tpt, impl) =>
+ new Typer(context.makeNewScope(tree, sym)).classSig(sym, tparams, tpt, impl)
+
+ case ModuleDef(_, _, tpt, impl) =>
+ val clazz = sym.moduleClass;
+ clazz.setInfo(new Typer(context.make(tree, clazz)).templateSig(clazz, impl));
+ if (tpt.isEmpty) { tpt.tpe = clazz.tpe; tpt.tpe }
+ else typechecker.transformType(tpt).tpe
+
+ case DefDef(_, _, tparams, vparamss, tpt, rhs) =>
+ new Typer(context.makeNewScope(tree, sym))
+ .methodSig(sym, tparams, vparamss, tpt, rhs)
+
+ case ValDef(_, _, tpt, rhs) =>
+ deconstIfNotFinal(sym,
+ if (tpt.tpe != null) tpt.tpe
+ else if (tpt.isEmpty)
+ if (rhs.isEmpty) {
+ unit.error(tpt.pos, "missing parameter type");
+ ErrorType
+ } else {
+ tpt.tpe = new TypeChecker(context.make(tree, sym))
+ .transformExpr(rhs).tpe;
+ tpt.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).tpe, typechecker.transformType(hi).tpe);
+
+ case imptree @ Import(expr, selectors) =>
+ val expr1 = typechecker.transformExpr(expr);
+ val base = expr1.tpe;
+ typechecker.checkStable(expr1);
+ for (val Pair(from, to) <- selectors) {
+ if (from != nme.WILDCARD && base != ErrorType &&
+ base.member(from) == NoSymbol && base.member(from.toTypeName) == NoSymbol)
+ unit.error(tree.pos, from.decode + " is not a member of " + expr);
+ if (to != null && to != nme.WILDCARD && (selectors exists (p => p._2 == to)))
+ unit.error(tree.pos, to.decode + " appears twice as a target of a renaming");
+ }
+ ImportType(imptree)
+ }
+ } catch {
+ case ex: TypeError =>
+ typechecker.reportTypeError(tree.pos, ex);
+ ErrorType
+ }
+
+ /** Check that symbol's definition is well-formed. This means:
+ * - no conflicting modifiers
+ * - `abstract' modifier only for classes
+ * - `override' modifier never for classes
+ * - `def' modifier never for parameters of case classes
+ * - declarations only in traits or abstract classes
+ * - todo: in desugarize: replace ABSTRACT OVERRIDE with ABSOVERRIDE
+ */
+ def validate(sym: Symbol): unit = {
+ def checkNoConflict(flag1: int, flag2: int): unit =
+ if (sym.hasFlag(flag1) && sym.hasFlag(flag2))
+ unit.error(sym.pos,
+ if (flag1 == DEFERRED)
+ "abstract member may not have " + Flags.flagsToString(flag2) + " modifier";
+ else
+ "illegal combination of modifiers: " +
+ Flags.flagsToString(flag1) + " and " + Flags.flagsToString(flag2));
+ if (sym.hasFlag(ABSTRACT) && !sym.isClass)
+ unit.error(sym.pos, "`abstract' modifier can be used only for classes; " +
+ "\nit should be omitted for abstract members");
+ if (sym.hasFlag(OVERRIDE | ABSOVERRIDE) && sym.isClass)
+ unit.error(sym.pos, "`override' modifier not allowed for classes");
+ if (sym.info.symbol == definitions.FunctionClass(0) &&
+ sym.isValueParameter && sym.owner.isClass && sym.owner.hasFlag(CASE))
+ unit.error(sym.pos, "pass-by-name arguments not allowed for case class parameters");
+ if ((sym.flags & DEFERRED) != 0) {
+ if (!sym.owner.isClass || sym.owner.isModuleClass || sym.owner.isAnonymousClass) {
+ unit.error(sym.pos,
+ "only classes can have declared but undefined members" +
+ (if (!sym.isVariable) ""
+ else "\n(Note that variables need to be initialized to be defined)"));
+ sym.resetFlag(DEFERRED);
+ }
+ }
+ checkNoConflict(DEFERRED, PRIVATE);
+ checkNoConflict(FINAL, SEALED);
+ if (!sym.hasFlag(MODULE)) checkNoConflict(FINAL, PRIVATE);
+ checkNoConflict(PRIVATE, PROTECTED);
+ checkNoConflict(PRIVATE, OVERRIDE);
+ checkNoConflict(DEFERRED, FINAL);
+ }
+ }
+}
diff --git a/sources/scala/tools/nsc/util/CharArrayReader.scala b/sources/scala/tools/nsc/util/CharArrayReader.scala
index c8202aaa7a..3cb70e6565 100644
--- a/sources/scala/tools/nsc/util/CharArrayReader.scala
+++ b/sources/scala/tools/nsc/util/CharArrayReader.scala
@@ -1,3 +1,8 @@
+/* NSC -- new scala compiler
+ * Copyright 2005 LAMP/EPFL
+ * @author Martin Odersky
+ */
+// $Id$
package scala.tools.nsc.util;
import scala.tools.util.SourceFile.{LF, FF, CR, SU}
diff --git a/sources/scala/tools/nsc/util/FreshNameCreator.scala b/sources/scala/tools/nsc/util/FreshNameCreator.scala
index ece9f8e05d..8215941256 100644
--- a/sources/scala/tools/nsc/util/FreshNameCreator.scala
+++ b/sources/scala/tools/nsc/util/FreshNameCreator.scala
@@ -1,3 +1,8 @@
+/* NSC -- new scala compiler
+ * Copyright 2005 LAMP/EPFL
+ * @author Martin Odersky
+ */
+// $Id$
package scala.tools.nsc.util;
import scala.collection.mutable.HashMap;
diff --git a/sources/scala/tools/nsc/util/NameTransformer.scala b/sources/scala/tools/nsc/util/NameTransformer.scala
index 21f89f3a01..709bd00a84 100755
--- a/sources/scala/tools/nsc/util/NameTransformer.scala
+++ b/sources/scala/tools/nsc/util/NameTransformer.scala
@@ -1,3 +1,8 @@
+/* NSC -- new scala compiler
+ * Copyright 2005 LAMP/EPFL
+ * @author Martin Odersky
+ */
+// $Id$
package scala.tools.nsc.util;
object NameTransformer {