summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sources/scala/$colon$colon.scala24
-rw-r--r--sources/scala/List.scala18
-rw-r--r--sources/scala/Nil.scala24
-rw-r--r--sources/scala/runtime/matching/Address.scala2
-rw-r--r--sources/scala/tools/nsc/CompilerCommand.scala17
-rwxr-xr-xsources/scala/tools/nsc/Global.scala30
-rwxr-xr-xsources/scala/tools/nsc/Main.scala26
-rw-r--r--sources/scala/tools/nsc/Settings.scala1
-rwxr-xr-xsources/scala/tools/nsc/ast/TreeGen.scala59
-rw-r--r--sources/scala/tools/nsc/ast/Trees.scala214
-rwxr-xr-xsources/scala/tools/nsc/symtab/Definitions.scala7
-rwxr-xr-xsources/scala/tools/nsc/symtab/SymbolLoaders.scala6
-rwxr-xr-xsources/scala/tools/nsc/symtab/Symbols.scala32
-rwxr-xr-xsources/scala/tools/nsc/symtab/Types.scala12
-rwxr-xr-xsources/scala/tools/nsc/symtab/classfile/ClassfileParser.scala2
-rwxr-xr-xsources/scala/tools/nsc/symtab/classfile/MetaParser.scala1
-rwxr-xr-xsources/scala/tools/nsc/symtab/classfile/UnPickler.scala12
-rw-r--r--sources/scala/tools/nsc/transform/SampleTransform.scala45
-rw-r--r--sources/scala/tools/nsc/transform/Transform.scala24
-rw-r--r--sources/scala/tools/nsc/transmatch/TransMatcher.scala2
-rw-r--r--sources/scala/tools/nsc/typechecker/Analyzer.scala5
-rwxr-xr-xsources/scala/tools/nsc/typechecker/ConstantFolder.scala11
-rwxr-xr-xsources/scala/tools/nsc/typechecker/Infer.scala3
-rwxr-xr-xsources/scala/tools/nsc/typechecker/Namers.scala29
-rw-r--r--sources/scala/tools/nsc/typechecker/TreeCheckers.scala7
-rwxr-xr-xsources/scala/tools/nsc/typechecker/Typers.scala446
-rwxr-xr-xsources/scala/tools/nsc/typechecker/Variances.scala17
-rw-r--r--test/files/dis/List.check2
28 files changed, 667 insertions, 411 deletions
diff --git a/sources/scala/$colon$colon.scala b/sources/scala/$colon$colon.scala
deleted file mode 100644
index f9bc4debd9..0000000000
--- a/sources/scala/$colon$colon.scala
+++ /dev/null
@@ -1,24 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-** $Id$
-\* */
-
-package scala;
-
-import Predef._;
-
-/** A non empty list characterized by a head and a tail.
- *
- * @author Martin Odersky
- * @version 1.0, 15/07/2003
- */
-final case class ::[+b](hd: b, tl: List[b]) extends List[b] with java.io.Serializable {
- private val serialVersionUID = 0 - 8476791151983527571L;
- def isEmpty: boolean = false;
- def head: b = hd;
- def tail: List[b] = tl;
-}
diff --git a/sources/scala/List.scala b/sources/scala/List.scala
index fa89d33c93..aeacd2f88f 100644
--- a/sources/scala/List.scala
+++ b/sources/scala/List.scala
@@ -147,6 +147,17 @@ object List {
* @return the list of substrings
*/
def fromString(str: String, separator: Char): List[String] = {
+ var words: List[String] = List();
+ var pos = str.length();
+ while (pos > 0) {
+ val pos1 = str.lastIndexOf(separator, pos - 1);
+ if (pos1 + 1 < pos)
+ words = str.substring(pos1 + 1, pos) :: words;
+ pos = pos1
+ }
+ words
+ }
+/*
var res: List[String] = Nil;
var start = 0;
var end = str.indexOf(separator);
@@ -159,7 +170,7 @@ object List {
}
res.reverse
}
-
+*/
/** Returns the given string as a list of characters.
*
* @param str the string to convert.
@@ -288,7 +299,7 @@ object List {
* @author Martin Odersky and others
* @version 1.0, 16/07/2003
*/
-/*sealed*/ trait List[+a] extends Seq[a] { // todo make sealed once we figure out how to build
+sealed trait List[+a] extends Seq[a] { // todo make sealed once we figure out how to build
/** Returns true if the list does not contain any elements.
* @return true, iff the list is empty.
@@ -873,7 +884,7 @@ object List {
else head :: tail.removeDuplicates
}
}
-/*
+
/** The empty list.
*
* @author Martin Odersky
@@ -897,4 +908,3 @@ final case class ::[+b](hd: b, tl: List[b]) extends List[b] with java.io.Seriali
def head: b = hd;
def tail: List[b] = tl;
}
-*/
diff --git a/sources/scala/Nil.scala b/sources/scala/Nil.scala
deleted file mode 100644
index 608982d3d4..0000000000
--- a/sources/scala/Nil.scala
+++ /dev/null
@@ -1,24 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-** $Id$
-\* */
-
-package scala;
-
-import Predef._;
-
-/** The empty list.
- *
- * @author Martin Odersky
- * @version 1.0, 15/07/2003
- */
-case object Nil extends List[All] with java.io.Serializable {
- private val serialVersionUID = 0 - 8256821097970055419L;
- def isEmpty = true;
- def head: All = error("head of empty list");
- def tail: List[All] = error("tail of empty list");
-}
diff --git a/sources/scala/runtime/matching/Address.scala b/sources/scala/runtime/matching/Address.scala
index 2e4c409fd8..3f548e402f 100644
--- a/sources/scala/runtime/matching/Address.scala
+++ b/sources/scala/runtime/matching/Address.scala
@@ -4,7 +4,7 @@ object Address {
def empty = new Address();
}
-import List.list2ordered;
+//import List.list2ordered;
/** Address holds the path in reverse Dewey notation
*/
diff --git a/sources/scala/tools/nsc/CompilerCommand.scala b/sources/scala/tools/nsc/CompilerCommand.scala
index fdea5cf424..09faa06317 100644
--- a/sources/scala/tools/nsc/CompilerCommand.scala
+++ b/sources/scala/tools/nsc/CompilerCommand.scala
@@ -8,7 +8,7 @@ package scala.tools.nsc;
import scala.tools.util.Reporter;
/** A class representing command line info for scalac */
-class CompilerCommand(arguments: Array[String], error: String => unit) {
+class CompilerCommand(arguments: List[String], error: String => unit, interactive: boolean) {
private var fs: List[String] = List();
/** All files to compile */
@@ -39,16 +39,21 @@ class CompilerCommand(arguments: Array[String], error: String => unit) {
}
// initialization
- var args = List.fromArray(arguments);
+ var args = arguments;
var ok = true;
while (!args.isEmpty && ok) {
val args0 = args;
if (args.head.startsWith("-")) {
- for (val setting <- settings.allSettings)
- args = setting.tryToSet(args);
- if (args eq args0) {
- error("unknown option: '" + args.head + "'");
+ if (interactive) {
+ error("no options can be given in interactive mode");
ok = false
+ } else {
+ for (val setting <- settings.allSettings)
+ args = setting.tryToSet(args);
+ if (args eq args0) {
+ error("unknown option: '" + args.head + "'");
+ ok = false
+ }
}
} else if (args.head.endsWith(".scala")) {
fs = args.head :: fs;
diff --git a/sources/scala/tools/nsc/Global.scala b/sources/scala/tools/nsc/Global.scala
index c8b7973684..0f8e785d8c 100755
--- a/sources/scala/tools/nsc/Global.scala
+++ b/sources/scala/tools/nsc/Global.scala
@@ -17,6 +17,7 @@ import ast._;
import ast.parser._;
import typechecker._;
import transmatch._;
+import transform._;
class Global(val settings: Settings, val reporter: Reporter) extends SymbolTable with Trees with CompilationUnits {
@@ -51,6 +52,10 @@ class Global(val settings: Settings, val reporter: Reporter) extends SymbolTable
val copy = new LazyTreeCopier();
+ object variance extends Variances {
+ val global: Global.this.type = Global.this
+ }
+
type AttrInfo = Pair[Type, List[Any]];
val attributes = new HashMap[Symbol, List[AttrInfo]];
@@ -118,7 +123,7 @@ class Global(val settings: Settings, val reporter: Reporter) extends SymbolTable
getSourceFile(f)
}
- private object loaders extends SymbolLoaders {
+ object loaders extends SymbolLoaders {
val global: Global.this.type = Global.this
}
@@ -136,24 +141,25 @@ class Global(val settings: Settings, val reporter: Reporter) extends SymbolTable
object analyzer extends Analyzer {
val global: Global.this.type = Global.this;
}
+ val infer = new analyzer.Inferencer(analyzer.NoContext);
object transmatcher extends TransMatcher {
val global: Global.this.type = Global.this;
}
- val infer = new analyzer.Inferencer(analyzer.NoContext);
+ object sampleTransform extends SampleTransform {
+ val global: Global.this.type = Global.this;
+ }
val namerPhase = new analyzer.NamerPhase(parserPhase);
val typeCheckPhase = new analyzer.TypeCheckPhase(namerPhase);
-
- val transMatchPhase = new transmatcher.TransMatchPhase(typeCheckPhase);
-
val picklePhase = new pickler.PicklePhase(typeCheckPhase);
-
+ val transMatchPhase = new transmatcher.TransMatchPhase(picklePhase);
+ val samplePhase = new sampleTransform.Phase(transMatchPhase);
/*
object icode extends ICode {
- val global: Global.this.type = Global.this
+ val symtab: Global.this.type = Global.this
}
val codegenPhase = new icode.CodeGenPhase(erasurePhase)
@@ -163,12 +169,14 @@ class Global(val settings: Settings, val reporter: Reporter) extends SymbolTable
}
*/
- val terminalPhase = new StdPhase(picklePhase) {
- def name = "terminal";
+ val terminalPhase = new StdPhase(samplePhase) {
val global: Global.this.type = Global.this;
+ def name = "terminal";
def apply(unit: CompilationUnit): unit = {}
}
+
+
// Units and how to compile them -------------------------------------
private var unitbuf = new ListBuffer[CompilationUnit];
@@ -212,12 +220,14 @@ class Global(val settings: Settings, val reporter: Reporter) extends SymbolTable
if (settings.Xshowobj.value != "") showDef(newTermName(settings.Xshowobj.value), true);
if (reporter.errors() == 0) {
- for (val Pair(sym, pickled) <- symData.elements.toList)
+ for (val Pair(sym, pickled) <- symData.elements.toList) {
+ sym.pos = Position.NOPOS;
if (symData contains sym) {
symData -= sym;
symData -= sym.linkedSym;
writeSymblFile(sym, pickled)
}
+ }
} else {
for (val Pair(sym, file) <- symSource.elements)
sym.reset(new loaders.SourcefileLoader(file));
diff --git a/sources/scala/tools/nsc/Main.scala b/sources/scala/tools/nsc/Main.scala
index e51ea4e91d..b761e609cc 100755
--- a/sources/scala/tools/nsc/Main.scala
+++ b/sources/scala/tools/nsc/Main.scala
@@ -5,6 +5,7 @@
// $Id$
package scala.tools.nsc;
+import java.io._;
import scala.tools.util.{Position, Reporter, ConsoleReporter}
/** The main class for NSC, a compiler for the programming
@@ -17,6 +18,7 @@ object Main {
val VERSION: String =
System.getProperty("scala.version", "unknown version");
val versionMsg = PRODUCT + " " + VERSION + " -- (c) 2002-04 LAMP/EPFL";
+ val prompt = "\nnsc> ";
private var reporter: ConsoleReporter = _;
@@ -24,18 +26,36 @@ object Main {
reporter.error(new Position(PRODUCT),
msg + "\n " + PRODUCT + " -help gives more information");
+ def interactive(compiler: Global): unit = {
+ val in = new BufferedReader(new InputStreamReader(System.in));
+ System.out.print(prompt);
+ var line = in.readLine();
+ while (line.length() > 0) {
+ val args = List.fromString(line, ' ');
+ val command = new CompilerCommand(args, error, true);
+ compiler.compile(command.files);
+ System.out.print(prompt);
+ line = in.readLine();
+ }
+ }
+
def process(args: Array[String]): unit = {
reporter = new ConsoleReporter();
- val command = new CompilerCommand(args, error);
+ val command = new CompilerCommand(List.fromArray(args), error, false);
reporter.prompt(command.settings.prompt.value);
if (command.settings.version.value)
reporter.info(null, versionMsg, true)
- else if (command.settings.help.value || command.files.isEmpty)
+ else if (command.settings.help.value)
reporter.info(null, command.usageMsg, true)
else {
try {
val compiler = new Global(command.settings, reporter);
- compiler.compile(command.files);
+ if (command.settings.interactive.value)
+ interactive(compiler);
+ else if (command.files.isEmpty)
+ reporter.info(null, command.usageMsg, true)
+ else
+ compiler.compile(command.files);
} catch {
case ex @ FatalError(msg) =>
if (command.settings.debug.value)
diff --git a/sources/scala/tools/nsc/Settings.scala b/sources/scala/tools/nsc/Settings.scala
index a65c34f057..88b05013dd 100644
--- a/sources/scala/tools/nsc/Settings.scala
+++ b/sources/scala/tools/nsc/Settings.scala
@@ -28,6 +28,7 @@ class Settings(error: String => unit) {
val target = ChoiceSetting ("-target", "Specify which backend to use", List("jvm", "msil"), "jvm");
val debug = BooleanSetting("-debug", "Output debugging messages");
val explaintypes = BooleanSetting("-explaintypes", "Explain type errors in more detail");
+ val interactive = BooleanSetting("-interactive", "Interactive mode");
val uniqid = BooleanSetting("-uniqid", "Print identifiers with unique names (debugging option)");
val printtypes = BooleanSetting("-printtypes", "Print tree types (debugging option)");
val prompt = BooleanSetting("-prompt", "Display a prompt after each error (debugging option)");
diff --git a/sources/scala/tools/nsc/ast/TreeGen.scala b/sources/scala/tools/nsc/ast/TreeGen.scala
index 06aca77217..4f4550fae1 100755
--- a/sources/scala/tools/nsc/ast/TreeGen.scala
+++ b/sources/scala/tools/nsc/ast/TreeGen.scala
@@ -26,9 +26,8 @@ abstract class TreeGen {
case SingleType(pre, sym) =>
val qual = mkStableRef(pre, sym);
qual.tpe match {
- case MethodType(params, _) =>
- assert(params.isEmpty, qual.tpe);
- Apply(qual, List());
+ case MethodType(List(), restpe) =>
+ Apply(qual, List()) setType restpe
case _ =>
qual
}
@@ -59,62 +58,20 @@ abstract class TreeGen {
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 This(sym: Symbol): Tree =
+ global.This(sym.name) setSymbol sym setType atPhase(phase.next)(sym.thisType);
def Ident(sym: Symbol) = {
assert(sym.isTerm);
sym.setFlag(ACCESSED);
- global.Ident(sym.name) setSymbol sym setType sym.tpe;
+ global.Ident(sym.name) setSymbol sym setType atPhase(phase.next)(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)
- setSymbol sym setType NoType
- }
- def ValDef(sym: Symbol): ValDef = ValDef(sym, EmptyTree);
-
- def AbsTypeDef(sym: Symbol) = atPos(sym.pos) {
- global.AbsTypeDef(flags2mods(sym.flags), sym.name,
- TypeTree(sym.info.bounds.lo), TypeTree(sym.info.bounds.hi))
- setSymbol sym setType NoType
- }
-
- 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))
- setSymbol sym setType NoType
- }
- mk(List(), List(), sym.tpe)
+ val result = global.Select(qual, sym.name) setSymbol sym;
+ if (qual.tpe != null) result setType atPhase(phase.next)(qual.tpe.memberType(sym));
+ result
}
}
diff --git a/sources/scala/tools/nsc/ast/Trees.scala b/sources/scala/tools/nsc/ast/Trees.scala
index d0db368a81..1e03eab863 100644
--- a/sources/scala/tools/nsc/ast/Trees.scala
+++ b/sources/scala/tools/nsc/ast/Trees.scala
@@ -8,6 +8,7 @@ package scala.tools.nsc.ast;
import java.io.StringWriter;
import java.io.PrintWriter;
import scala.tools.util.Position;
+import symtab.Flags._;
abstract class Trees: Global {
@@ -42,8 +43,7 @@ abstract class Trees: Global {
case _ => false
}
- def duplicate: Tree =
- new Transformer(new StrictTreeCopier) transform this;
+ def duplicate: Tree = duplicator transform this;
def copyAttrs(tree: Tree): this.type = {
pos = tree.pos;
@@ -70,6 +70,20 @@ abstract class Trees: Global {
override def isType = true;
}
+// ----- auxiliary objects and methods ------------------------------
+
+ private val duplicator = new Transformer {
+ override val copy = new StrictTreeCopier;
+ }
+
+ private def syntheticParams(owner: Symbol, formals: List[Type]): List[Symbol] = {
+ var cnt = 0;
+ def freshName = { cnt = cnt + 1; newTermName("x$" + cnt) }
+ formals map owner.newValueParameter(owner.pos, freshName).setInfo
+ }
+
+// ----- tree node alternatives --------------------------------------
+
/** The empty tree */
case object EmptyTree extends TermTree {
tpe = NoType;
@@ -80,10 +94,25 @@ abstract class Trees: Global {
case class PackageDef(name: Name, stats: List[Tree])
extends DefTree;
+ def PackageDef(sym: Symbol, stats: List[Tree]): PackageDef =
+ PackageDef(sym.name, stats) setSymbol sym;
+
+
/** Class definition */
case class ClassDef(mods: int, name: Name, tparams: List[AbsTypeDef], tpt: Tree, impl: Template)
extends DefTree;
+ def ClassDef(sym: Symbol, impl: Template): ClassDef =
+ posAssigner.atPos(sym.pos) {
+ atPhase(phase.next) {
+ ClassDef(flags2mods(sym.flags),
+ sym.name,
+ sym.typeParams map AbsTypeDef,
+ TypeTree(sym.typeOfThis),
+ impl)
+ }
+ }
+
/** Singleton object definition */
case class ModuleDef(mods: int, name: Name, impl: Template)
extends DefTree;
@@ -92,25 +121,80 @@ abstract class Trees: Global {
case class ValDef(mods: int, name: Name, tpt: Tree, rhs: Tree)
extends DefTree;
+ def ValDef(sym: Symbol, rhs: Tree): ValDef =
+ posAssigner.atPos(sym.pos) {
+ atPhase(phase.next) {
+ ValDef(flags2mods(sym.flags), sym.name, TypeTree(sym.tpe), rhs) setSymbol sym
+ }
+ }
+
+ def ValDef(sym: Symbol): ValDef = ValDef(sym, EmptyTree);
+
/** Method definition */
case class DefDef(mods: int, name: Name, tparams: List[AbsTypeDef],
vparamss: List[List[ValDef]], tpt: Tree, rhs: Tree)
extends DefTree;
+ def DefDef(sym: Symbol, rhs: List[List[Symbol]] => Tree): DefDef =
+ posAssigner.atPos(sym.pos) {
+ atPhase(phase.next) {
+ 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) =>
+ mk(tparams, vparamss ::: List(syntheticParams(sym, formals)), restpe)
+ case _ =>
+ DefDef(
+ flags2mods(sym.flags),
+ sym.name,
+ tparams map AbsTypeDef,
+ vparamss map (.map(ValDef)),
+ TypeTree(tpe),
+ rhs(vparamss)) setSymbol sym
+ }
+ mk(List(), List(), sym.tpe)
+ }
+ }
+
/** Abstract type or type parameter */
case class AbsTypeDef(mods: int, name: Name, lo: Tree, hi: Tree)
extends DefTree;
+ def AbsTypeDef(sym: Symbol): AbsTypeDef =
+ posAssigner.atPos(sym.pos) {
+ atPhase(phase.next) {
+ AbsTypeDef(flags2mods(sym.flags), sym.name,
+ TypeTree(sym.info.bounds.lo), TypeTree(sym.info.bounds.hi))
+ }
+ }
+
/** Type alias */
- case class AliasTypeDef(mods: int, name: Name, tparams: List[AbsTypeDef],
- rhs: Tree)
+ case class AliasTypeDef(mods: int, name: Name, tparams: List[AbsTypeDef], rhs: Tree)
extends DefTree;
+ def AliasTypeDef(sym: Symbol, rhs: Tree): AliasTypeDef =
+ posAssigner.atPos(sym.pos) {
+ atPhase(phase.next) {
+ AliasTypeDef(flags2mods(sym.flags), sym.name, sym.typeParams map AbsTypeDef, rhs)
+ }
+ }
+
/** Labelled expression - the symbols in the array (must be Idents!)
* are those the label takes as argument */
- case class LabelDef(name: Name, params: List[Ident], rhs: Tree)
+ case class LabelDef(name: Name, params: List[ValDef], rhs: Tree)
extends DefTree with TermTree;
+ def LabelDef(sym: Symbol, rhs: List[Symbol] => Tree): LabelDef =
+ posAssigner.atPos(sym.pos) {
+ atPhase(phase.next) {
+ sym.tpe match {
+ case MethodType(formals, _) =>
+ val params = syntheticParams(sym, formals);
+ LabelDef(sym.name, params map ValDef, rhs(params)) setSymbol sym
+ }
+ }
+ }
+
/** Import clause */
case class Import(expr: Tree, selectors: List[Pair[Name, Name]])
extends SymTree;
@@ -208,10 +292,14 @@ abstract class Trees: Global {
case class Super(qual: Name, mixin: Name)
extends TermTree with SymTree;
+ def Super(sym: Symbol, mixin: Name): Tree = Super(sym.name, mixin) setSymbol sym;
+
/** Self reference */
case class This(qual: Name)
extends TermTree with SymTree;
+ def This(sym: Symbol): Tree = This(sym.name) setSymbol sym;
+
/** Designator */
case class Select(qualifier: Tree, selector: Name)
extends SymTree {
@@ -219,6 +307,11 @@ abstract class Trees: Global {
override def isType = selector.isTypeName;
}
+ def Select(qualifier: Tree, sym: Symbol): Select = {
+ sym.setFlag(ACCESSED);
+ Select(qualifier, sym.name) setSymbol sym
+ }
+
/** Identifier */
case class Ident(name: Name)
extends SymTree {
@@ -226,6 +319,12 @@ abstract class Trees: Global {
override def isType = name.isTypeName;
}
+ def Ident(sym: Symbol): Ident = {
+ sym.setFlag(ACCESSED);
+ Ident(sym.name) setSymbol sym
+ }
+
+
/** Literal */
case class Literal(value: Any)
extends TermTree {
@@ -238,6 +337,9 @@ abstract class Trees: Global {
override def isEmpty = tpe == null || tpe == NoType;
}
+ def TypeTree(tp: Type): TypeTree = TypeTree() setType tp;
+
+
/** Singleton type, eliminated by RefCheck */
case class SingletonTypeTree(ref: Tree)
extends TypTree;
@@ -307,7 +409,7 @@ abstract class Trees: Global {
def DefDef(tree: Tree, mods: int, name: Name, tparams: List[AbsTypeDef], vparamss: List[List[ValDef]], tpt: Tree, rhs: Tree): DefDef;
def AbsTypeDef(tree: Tree, mods: int, name: Name, lo: Tree, hi: Tree): AbsTypeDef;
def AliasTypeDef(tree: Tree, mods: int, name: Name, tparams: List[AbsTypeDef], rhs: Tree): AliasTypeDef;
- def LabelDef(tree: Tree, name: Name, params: List[Ident], rhs: Tree): LabelDef;
+ def LabelDef(tree: Tree, name: Name, params: List[ValDef], rhs: Tree): LabelDef;
def Import(tree: Tree, expr: Tree, selectors: List[Pair[Name, Name]]): Import;
def Attributed(tree: Tree, attribute: Tree, definition: Tree): Attributed;
def DocDef(tree: Tree, comment: String, definition: Tree): DocDef;
@@ -355,7 +457,7 @@ abstract class Trees: Global {
new AbsTypeDef(mods, name, lo, hi).copyAttrs(tree);
def AliasTypeDef(tree: Tree, mods: int, name: Name, tparams: List[AbsTypeDef], rhs: Tree) =
new AliasTypeDef(mods, name, tparams, rhs).copyAttrs(tree);
- def LabelDef(tree: Tree, name: Name, params: List[Ident], rhs: Tree) =
+ def LabelDef(tree: Tree, name: Name, params: List[ValDef], rhs: Tree) =
new LabelDef(name, params, rhs).copyAttrs(tree);
def Import(tree: Tree, expr: Tree, selectors: List[Pair[Name, Name]]) =
new Import(expr, selectors).copyAttrs(tree);
@@ -456,7 +558,7 @@ abstract class Trees: Global {
if (mods0 == mods && (name0 == name) && (tparams0 == tparams) && (rhs0 == rhs)) => t
case _ => copy.AliasTypeDef(tree, mods, name, tparams, rhs)
}
- def LabelDef(tree: Tree, name: Name, params: List[Ident], rhs: Tree) = tree match {
+ def LabelDef(tree: Tree, name: Name, params: List[ValDef], rhs: Tree) = tree match {
case t @ LabelDef(name0, params0, rhs0)
if ((name0 == name) && (params0 == params) && (rhs0 == rhs)) => t
case _ => copy.LabelDef(tree, name, params, rhs)
@@ -612,27 +714,43 @@ abstract class Trees: Global {
}
}
- class Transformer(val copy: TreeCopier) {
- def this() = this(new LazyTreeCopier);
+ abstract class Transformer {
+ val copy: TreeCopier = new LazyTreeCopier;
+ protected var currentOwner: Symbol = definitions.RootClass;
def transform(tree: Tree): Tree = tree match {
case EmptyTree =>
tree
- case ClassDef(mods, name, tparams, tpt, impl) =>
- copy.ClassDef(tree, mods, name, transformAbsTypeDefs(tparams), transform(tpt), transformTemplate(impl))
case PackageDef(name, stats) =>
- copy.PackageDef(tree, name, transformTrees(stats))
+ atOwner(tree.symbol.moduleClass) {
+ copy.PackageDef(tree, name, transformTrees(stats))
+ }
+ case ClassDef(mods, name, tparams, tpt, impl) =>
+ atOwner(tree.symbol) {
+ copy.ClassDef(tree, mods, name, transformAbsTypeDefs(tparams), transform(tpt), transformTemplate(impl))
+ }
case ModuleDef(mods, name, impl) =>
- copy.ModuleDef(tree, mods, name, transformTemplate(impl))
+ atOwner(tree.symbol.moduleClass) {
+ copy.ModuleDef(tree, mods, name, transformTemplate(impl))
+ }
case ValDef(mods, name, tpt, rhs) =>
- copy.ValDef(tree, mods, name, transform(tpt), transform(rhs))
+ atOwner(tree.symbol) {
+ copy.ValDef(tree, mods, name, transform(tpt), transform(rhs))
+ }
case DefDef(mods, name, tparams, vparamss, tpt, rhs) =>
- copy.DefDef(tree, mods, name, transformAbsTypeDefs(tparams), transformValDefss(vparamss), transform(tpt), transform(rhs))
+ atOwner(tree.symbol) {
+ copy.DefDef(
+ tree, mods, name, transformAbsTypeDefs(tparams), transformValDefss(vparamss), transform(tpt), transform(rhs))
+ }
case AbsTypeDef(mods, name, lo, hi) =>
- copy.AbsTypeDef(tree, mods, name, transform(lo), transform(hi))
+ atOwner(tree.symbol) {
+ copy.AbsTypeDef(tree, mods, name, transform(lo), transform(hi))
+ }
case AliasTypeDef(mods, name, tparams, rhs) =>
- copy.AliasTypeDef(tree, mods, name, transformAbsTypeDefs(tparams), transform(rhs))
+ atOwner(tree.symbol) {
+ copy.AliasTypeDef(tree, mods, name, transformAbsTypeDefs(tparams), transform(rhs))
+ }
case LabelDef(name, params, rhs) =>
- copy.LabelDef(tree, name, transformIdents(params), transform(rhs))
+ copy.LabelDef(tree, name, transformValDefs(params), transform(rhs))
case Import(expr, selectors) =>
copy.Import(tree, transform(expr), selectors)
case Attributed(attribute, definition) =>
@@ -640,7 +758,7 @@ abstract class Trees: Global {
case DocDef(comment, definition) =>
copy.DocDef(tree, comment, transform(definition))
case Template(parents, body) =>
- copy.Template(tree, transformTrees(parents), transformTrees(body))
+ copy.Template(tree, transformTrees(parents), transformStats(body, tree.symbol))
case Block(stats, expr) =>
copy.Block(tree, transformTrees(stats), transform(expr))
case CaseDef(pat, guard, body) =>
@@ -709,24 +827,52 @@ abstract class Trees: Global {
List.mapConserve(trees)(tree => transform(tree).asInstanceOf[CaseDef]);
def transformIdents(trees: List[Ident]): List[Ident] =
List.mapConserve(trees)(tree => transform(tree).asInstanceOf[Ident]);
+ def transformStats(stats: List[Tree], exprOwner: Symbol): List[Tree] =
+ List.mapConserve(stats)(stat =>
+ if (exprOwner != currentOwner && (!stat.isDef || stat.isInstanceOf[LabelDef]))
+ atOwner(exprOwner)(transform(stat))
+ else transform(stat));
+
+ def atOwner[A](owner: Symbol)(trans: A): A = {
+ val prevOwner = currentOwner;
+ currentOwner = owner;
+ val result = trans;
+ currentOwner = prevOwner;
+ result
+ }
}
class Traverser {
+ protected var currentOwner: Symbol = definitions.RootClass;
def traverse(tree: Tree): unit = tree match {
case ClassDef(mods, name, tparams, tpt, impl) =>
- traverseTrees(tparams); traverse(tpt); traverse(impl)
+ atOwner(tree.symbol.moduleClass) {
+ traverseTrees(tparams); traverse(tpt); traverse(impl)
+ }
case PackageDef(name, stats) =>
- traverseTrees(stats)
+ atOwner(tree.symbol) {
+ traverseTrees(stats)
+ }
case ModuleDef(mods, name, impl) =>
- traverse(impl)
+ atOwner(tree.symbol.moduleClass) {
+ traverse(impl)
+ }
case ValDef(mods, name, tpt, rhs) =>
- traverse(tpt); traverse(rhs)
+ atOwner(tree.symbol) {
+ traverse(tpt); traverse(rhs)
+ }
case DefDef(mods, name, tparams, vparamss, tpt, rhs) =>
- traverseTrees(tparams); traverseTreess(vparamss); traverse(tpt); traverse(rhs)
+ atOwner(tree.symbol) {
+ traverseTrees(tparams); traverseTreess(vparamss); traverse(tpt); traverse(rhs)
+ }
case AbsTypeDef(mods, name, lo, hi) =>
- traverse(lo); traverse(hi);
+ atOwner(tree.symbol) {
+ traverse(lo); traverse(hi);
+ }
case AliasTypeDef(mods, name, tparams, rhs) =>
- traverseTrees(tparams); traverse(rhs)
+ atOwner(tree.symbol) {
+ traverseTrees(tparams); traverse(rhs)
+ }
case LabelDef(name, params, rhs) =>
traverseTrees(params); traverse(rhs)
case Import(expr, selectors) =>
@@ -736,7 +882,7 @@ abstract class Trees: Global {
case DocDef(comment, definition) =>
traverse(definition)
case Template(parents, body) =>
- traverseTrees(parents); traverseTrees(body)
+ traverseTrees(parents); traverseStats(body, tree.symbol)
case Block(stats, expr) =>
traverseTrees(stats); traverse(expr)
case CaseDef(pat, guard, body) =>
@@ -787,6 +933,18 @@ abstract class Trees: Global {
trees foreach traverse;
def traverseTreess(treess: List[List[Tree]]): unit =
treess foreach traverseTrees;
+ def traverseStats(stats: List[Tree], exprOwner: Symbol): unit =
+ stats foreach (stat =>
+ if (exprOwner != currentOwner && (!stat.isDef || stat.isInstanceOf[LabelDef]))
+ atOwner(exprOwner)(traverse(stat))
+ else traverse(stat));
+
+ def atOwner(owner: Symbol)(traverse: unit): unit = {
+ val prevOwner = currentOwner;
+ currentOwner = owner;
+ traverse;
+ currentOwner = prevOwner;
+ }
}
final class TreeList {
diff --git a/sources/scala/tools/nsc/symtab/Definitions.scala b/sources/scala/tools/nsc/symtab/Definitions.scala
index 9b51dfe620..ecbf977d50 100755
--- a/sources/scala/tools/nsc/symtab/Definitions.scala
+++ b/sources/scala/tools/nsc/symtab/Definitions.scala
@@ -59,8 +59,6 @@ abstract class Definitions: SymbolTable {
var PredefModule: Symbol = _;
var ConsoleModule: Symbol = _;
var MatchErrorModule: Symbol = _;
- var NilModule: Symbol = _;
- var ConsClass: Symbol = _;
var RepeatedParamClass: Symbol = _;
var ByNameParamClass: Symbol = _;
@@ -82,6 +80,9 @@ abstract class Definitions: SymbolTable {
def seqType(arg: Type) =
typeRef(SeqClass.typeConstructor.prefix, SeqClass, List(arg));
+// def NilModule: Symbol = getModule("scala.Nil");
+// def ConsClass: Symbol = getClass("scala.$colon$colon");
+
// members of class scala.Any
var Any_== : Symbol = _;
var Any_!= : Symbol = _;
@@ -222,8 +223,6 @@ abstract class Definitions: SymbolTable {
PredefModule = getModule("scala.Predef");
ConsoleModule = getModule("scala.Console");
MatchErrorModule = getModule("scala.MatchError");
- NilModule = getModule("scala.Nil");
- ConsClass = getClass("scala.$colon$colon");
RepeatedParamClass = newCovariantPolyClass(
ScalaPackageClass, nme.REPEATED_PARAM_CLASS_NAME,
tparam => typeRef(SeqClass.typeConstructor.prefix, SeqClass, List(tparam.typeConstructor)));
diff --git a/sources/scala/tools/nsc/symtab/SymbolLoaders.scala b/sources/scala/tools/nsc/symtab/SymbolLoaders.scala
index b10fcabdf0..3229024b2f 100755
--- a/sources/scala/tools/nsc/symtab/SymbolLoaders.scala
+++ b/sources/scala/tools/nsc/symtab/SymbolLoaders.scala
@@ -62,9 +62,11 @@ abstract class SymbolLoaders {
override def load(root: Symbol): unit = complete(root);
private def initRoot(root: Symbol): unit = {
- if (root.rawInfo == this)
+ if (root.rawInfo == this) {
root.setInfo(if (ok) NoType else ErrorType);
- if (root.isModule) initRoot(root.moduleClass);
+ if (root.isModule)
+ root.moduleClass.setInfo(if (ok) NoType else ErrorType)
+ }
if (root.isClass && !root.isModuleClass) root.rawInfo.load(root)
}
}
diff --git a/sources/scala/tools/nsc/symtab/Symbols.scala b/sources/scala/tools/nsc/symtab/Symbols.scala
index 07d5b0f12f..000c7785f5 100755
--- a/sources/scala/tools/nsc/symtab/Symbols.scala
+++ b/sources/scala/tools/nsc/symtab/Symbols.scala
@@ -155,6 +155,14 @@ abstract class Symbols: SymbolTable {
/** Symbol was preloaded from package */
final def isExternal: boolean = pos == Position.NOPOS;
+ /** A a member of class `base' is incomplete if (1) it is declared deferred or
+ * (2) it is abstract override and its super symbol in `base' is nonexistent or inclomplete.
+ */
+ final def isIncompleteIn(base: Symbol): boolean =
+ (this == NoSymbol) ||
+ (this hasFlag DEFERRED) ||
+ (this hasFlag ABSOVERRIDE) && isIncompleteIn(superSymbol(base));
+
/** The variance of this symbol as an integer */
final def variance: int =
if (hasFlag(COVARIANT)) 1
@@ -293,6 +301,7 @@ abstract class Symbols: SymbolTable {
infos = null;
setInfo(completer)
}
+
// Comparisons ----------------------------------------------------------------
/** A total ordering between symbols that refines the class
@@ -417,6 +426,10 @@ abstract class Symbols: SymbolTable {
sym => (sym hasFlag MODULE) && (sym.rawInfo != NoType));
else NoSymbol;
+ /** The top-level class containing this symbol */
+ def toplevelClass: Symbol =
+ if (isClass && owner.isPackageClass) this else owner.toplevelClass;
+
/** For a module its linked class, for a class its linked module or case factory otherwise */
final def linkedSym: Symbol =
if (isTerm) linkedClass
@@ -443,6 +456,20 @@ abstract class Symbols: SymbolTable {
base.info.nonPrivateDecl(name).suchThat(sym =>
sym.isType || (base.thisType.memberType(sym) matches base.thisType.memberType(this)));
+ /** The symbol accessed by a super in the definition of `this' when seen from
+ * class `base'. This symbol is always concrete.
+ * pre: `this.owner' is in the base class sequence of `base'.
+ */
+ final def superSymbol(base: Symbol): Symbol = {
+ var bcs = base.info.baseClasses.dropWhile(.!=(owner)).tail;
+ var sym: Symbol = NoSymbol;
+ while (!bcs.isEmpty && sym == NoSymbol) {
+ sym = overriddenSymbol(bcs.head).suchThat(sym => !(sym hasFlag DEFERRED));;
+ bcs = bcs.tail
+ }
+ sym
+ }
+
// ToString -------------------------------------------------------------------
/** A tag which (in the ideal case) uniquely identifies class symbols */
@@ -554,8 +581,8 @@ abstract class Symbols: SymbolTable {
/** String representation of symbol's variance */
private def varianceString: String =
- if (variance > 0) "+"
- else if (variance < 0) "-"
+ if (variance == 1) "+"
+ else if (variance == -1) "-"
else "";
/** String representation of symbol's definition */
@@ -682,6 +709,7 @@ abstract class Symbols: SymbolTable {
super.setInfo(NoType);
override def setInfo(info: Type): this.type = { assert(info == NoType); this }
override def enclClass: Symbol = this;
+ override def toplevelClass: Symbol = this;
override def enclMethod: Symbol = this;
override def owner: Symbol = throw new Error();
override def alternatives: List[Symbol] = List();
diff --git a/sources/scala/tools/nsc/symtab/Types.scala b/sources/scala/tools/nsc/symtab/Types.scala
index 0c05ae7027..2d18105e0c 100755
--- a/sources/scala/tools/nsc/symtab/Types.scala
+++ b/sources/scala/tools/nsc/symtab/Types.scala
@@ -63,13 +63,6 @@ abstract class Types: SymbolTable {
* identity for all other types */
def deconst: Type = this;
- /** Map a parameterless method type to its result type
- * identity for all other types */
- def derefDef: Type = this match {
- case PolyType(List(), restp) => restp
- case _ => this
- }
-
/** For a TypeBounds type, itself;
* for a reference denoting an abstract type, its bounds,
* for all other types, a TypeBounds type all of whose bounds are this type.
@@ -319,7 +312,7 @@ abstract class Types: SymbolTable {
else baseClasses.head.newOverloaded(this, alts)
}
- protected def findMember(name: Name, excludedFlags: int, requiredFlags: int): Symbol = {
+ def findMember(name: Name, excludedFlags: int, requiredFlags: int): Symbol = {
//System.out.println("find member " + name.decode + " in " + this.baseClasses);//DEBUG
var members: Scope = null;
var member: Symbol = NoSymbol;
@@ -471,6 +464,9 @@ abstract class Types: SymbolTable {
protected def supertype: Type = hi;
override def bounds: TypeBounds = this;
def containsType(that: Type) = lo <:< that && that <:< hi;
+ override def toString() =
+ (if (lo.symbol != AllClass) " >: " + lo else "") +
+ (if (hi.symbol != AnyClass) " <: " + hi else "");
}
/** A common base class for intersection types and class types
diff --git a/sources/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/sources/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
index e5ea1c434a..15aa4237f9 100755
--- a/sources/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
+++ b/sources/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
@@ -244,8 +244,8 @@ abstract class ClassfileParser {
clazz.setFlag(sflags);
if (!hasMeta) {
clazz.setInfo(classInfo);
- statics.setInfo(staticInfo);
}
+ statics.setInfo(staticInfo);
staticModule.setInfo(statics.tpe);
in.bp = curbp;
val fieldCount = in.nextChar();
diff --git a/sources/scala/tools/nsc/symtab/classfile/MetaParser.scala b/sources/scala/tools/nsc/symtab/classfile/MetaParser.scala
index b2fdbe0dc8..e125e9326a 100755
--- a/sources/scala/tools/nsc/symtab/classfile/MetaParser.scala
+++ b/sources/scala/tools/nsc/symtab/classfile/MetaParser.scala
@@ -148,7 +148,6 @@ abstract class MetaParser{
else owner.owner.tpe
}
owner.setInfo(parse());
- System.out.println("constr " + owner + " = " + owner.info);
assert(token == ";")
}
}
diff --git a/sources/scala/tools/nsc/symtab/classfile/UnPickler.scala b/sources/scala/tools/nsc/symtab/classfile/UnPickler.scala
index b35cc61a47..70d555bd2f 100755
--- a/sources/scala/tools/nsc/symtab/classfile/UnPickler.scala
+++ b/sources/scala/tools/nsc/symtab/classfile/UnPickler.scala
@@ -102,14 +102,16 @@ abstract class UnPickler {
case ALIASsym =>
sym = owner.newAliasType(Position.NOPOS, name);
case CLASSsym =>
- sym = if ((flags & MODULE) == 0 &&
- name == classRoot.name && owner == classRoot.owner) classRoot
- else owner.newClass(Position.NOPOS, name);
+ sym =
+ if (name == classRoot.name && owner == classRoot.owner)
+ if ((flags & MODULE) != 0) moduleRoot.moduleClass else classRoot
+ else owner.newClass(Position.NOPOS, name);
if (readIndex != end) sym.typeOfThis = new LazyTypeRef(readNat())
case MODULEsym =>
val mclazz = at(inforef, readType).symbol.asInstanceOf[ClassSymbol];
- sym = if (name == moduleRoot.name && owner == moduleRoot.owner) moduleRoot
- else owner.newModule(Position.NOPOS, name, mclazz)
+ sym =
+ if (name == moduleRoot.name && owner == moduleRoot.owner) moduleRoot
+ else owner.newModule(Position.NOPOS, name, mclazz)
case VALsym =>
sym = if (name == moduleRoot.name && owner == moduleRoot.owner) moduleRoot.resetFlag(MODULE)
else owner.newValue(Position.NOPOS, name)
diff --git a/sources/scala/tools/nsc/transform/SampleTransform.scala b/sources/scala/tools/nsc/transform/SampleTransform.scala
new file mode 100644
index 0000000000..75595ebaca
--- /dev/null
+++ b/sources/scala/tools/nsc/transform/SampleTransform.scala
@@ -0,0 +1,45 @@
+/* NSC -- new scala compiler
+ * Copyright 2005 LAMP/EPFL
+ * @author
+ */
+// $Id$
+package scala.tools.nsc.transform;
+
+/** A sample transform.
+ */
+abstract class SampleTransform extends Transform {
+ // inherits abstract value `global' and class `Phase' from Transform
+
+ import global._; // the global environment
+ import definitions._; // standard classes and methods
+ import typer.typed; // methods to type trees
+ import posAssigner.atPos; // for filling in tree positions
+
+ /** the following two members override abstract members in Transform */
+ protected val phaseName: String = "sample-phase";
+ protected def newTransformer: Transformer = new SampleTransformer;
+
+ class SampleTransformer extends Transformer {
+
+ override def transform(tree: Tree): Tree = {
+ val tree1 = super.transform(tree); // transformers always maintain `currentOwner'.
+ tree1 match {
+ case Block(List(), expr) => // a simple optimization
+ expr
+ case Block(defs, sup @ Super(qual, mix)) => // A hypthothetic transformation, which replaces
+ // {super} by {super.sample}
+ copy.Block( // `copy' is the usual lazy tree copier
+ tree1, defs,
+ typed( // `typed' assigns types to its tree argument
+ atPos(tree1.pos)( // `atPos' fills in position of its tree argument
+ Select( // The `Select' factory method is defined in class `Trees'
+ sup,
+ currentOwner.newValue( // creates a new term symbol owned by `currentowner'
+ tree1.pos,
+ newTermName("sample")))))) // The standard term name creator
+ case _ =>
+ tree1
+ }
+ }
+ }
+}
diff --git a/sources/scala/tools/nsc/transform/Transform.scala b/sources/scala/tools/nsc/transform/Transform.scala
new file mode 100644
index 0000000000..49b46d92f5
--- /dev/null
+++ b/sources/scala/tools/nsc/transform/Transform.scala
@@ -0,0 +1,24 @@
+/* NSC -- new scala compiler
+ * Copyright 2005 LAMP/EPFL
+ * @author
+ */
+// $Id$
+package scala.tools.nsc.transform;
+
+/** A sample transform.
+ */
+abstract class Transform {
+
+ val global: Global;
+
+ protected val phaseName: String;
+ protected def newTransformer: global.Transformer;
+
+ class Phase(prev: scala.tools.nsc.Phase) extends StdPhase(prev) {
+ val global: Transform.this.global.type = Transform.this.global;
+ def name: String = phaseName;
+ def apply(unit: global.CompilationUnit): unit =
+ unit.body = newTransformer.transform(unit.body);
+ }
+}
+
diff --git a/sources/scala/tools/nsc/transmatch/TransMatcher.scala b/sources/scala/tools/nsc/transmatch/TransMatcher.scala
index d384afb845..1fb887b734 100644
--- a/sources/scala/tools/nsc/transmatch/TransMatcher.scala
+++ b/sources/scala/tools/nsc/transmatch/TransMatcher.scala
@@ -24,7 +24,7 @@ abstract class TransMatcher {
def newTransMatcher = new TransMatch();
- class TransMatch extends Transformer(copy) {
+ class TransMatch extends Transformer {
override def transform(tree: Tree) = tree match {
case _ => super.transform(tree);
}
diff --git a/sources/scala/tools/nsc/typechecker/Analyzer.scala b/sources/scala/tools/nsc/typechecker/Analyzer.scala
index e5797fc377..18de3855b8 100644
--- a/sources/scala/tools/nsc/typechecker/Analyzer.scala
+++ b/sources/scala/tools/nsc/typechecker/Analyzer.scala
@@ -14,7 +14,8 @@ abstract class Analyzer
with Namers
with Typers
with Infer
- with Variances
- with EtaExpansion {
+ with EtaExpansion
+ {
val global: Global;
}
+
diff --git a/sources/scala/tools/nsc/typechecker/ConstantFolder.scala b/sources/scala/tools/nsc/typechecker/ConstantFolder.scala
index 8fcac5ad5f..3a78775393 100755
--- a/sources/scala/tools/nsc/typechecker/ConstantFolder.scala
+++ b/sources/scala/tools/nsc/typechecker/ConstantFolder.scala
@@ -21,15 +21,14 @@ abstract class ConstantFolder {
});
/** If tree is a constant value that can be converted to type `pt', perform the conversion */
- def apply(tree: Tree, pt: Type): Tree = fold(tree, tree match {
- case Literal(value) => foldTyped(value, pt)
+ def apply(tree: Tree, pt: Type): Tree = fold(tree, tree.tpe match {
+ case ConstantType(base, value) => foldTyped(value, pt)
case _ => NoValue
});
- def fold(tree: Tree, value: Any): Tree =
- if (value != NoValue && value != ()) {
- copy.Literal(tree, value) setType ConstantType(literalType(value), value)
- } else tree;
+ private def fold(tree: Tree, value: Any): Tree =
+ if (value != NoValue && value != ()) tree setType ConstantType(literalType(value), value)
+ else tree;
private def foldUnop(op: Name, value: Any): Any = Pair(op, value) match {
case Pair(nme.ZNOT, x: boolean) => !x
diff --git a/sources/scala/tools/nsc/typechecker/Infer.scala b/sources/scala/tools/nsc/typechecker/Infer.scala
index 4ce8d7f8d8..6807223bba 100755
--- a/sources/scala/tools/nsc/typechecker/Infer.scala
+++ b/sources/scala/tools/nsc/typechecker/Infer.scala
@@ -9,6 +9,7 @@ abstract class Infer: Analyzer {
import symtab.Flags._;
import global._;
import definitions._;
+ import variance.{varianceInType, varianceInTypes};
import posAssigner.atPos;
import util.ListBuffer;
@@ -527,7 +528,7 @@ abstract class Infer: Analyzer {
if (settings.debug.value) System.out.println("infer method alt " + tree.symbol + " with alternatives " + (alts map pre.memberType) + ", argtpes = " + argtpes + ", pt = " + pt);//debug
val alts1 = alts filter (alt => isApplicable(undetparams, pre.memberType(alt), argtpes, pt));
def improves(sym1: Symbol, sym2: Symbol) = {
- sym2 == NoSymbol ||
+ sym2 == NoSymbol || sym2.isError ||
((sym1.owner isSubClass sym2.owner) &&
specializes(pre.memberType(sym1), pre.memberType(sym2)))
}
diff --git a/sources/scala/tools/nsc/typechecker/Namers.scala b/sources/scala/tools/nsc/typechecker/Namers.scala
index 5c26880563..2ca9c8813c 100755
--- a/sources/scala/tools/nsc/typechecker/Namers.scala
+++ b/sources/scala/tools/nsc/typechecker/Namers.scala
@@ -14,8 +14,8 @@ 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 name = "namer";
def apply(unit: CompilationUnit): unit =
new Namer(startContext.make(unit)).enterSym(unit.body);
}
@@ -49,6 +49,9 @@ trait Namers: Analyzer {
sym.flags = oldflags | newflags;
if (sym.isModule)
updatePosFlags(sym.moduleClass, pos, (mods & ModuleToClassFlags) | MODULE | FINAL);
+ if (sym.owner.isPackageClass && sym.linkedSym.rawInfo.isInstanceOf[loaders.SymbolLoader])
+ // pre-set linked symbol to NoType, in case it is not loaded together with this symbol.
+ sym.linkedSym.setInfo(NoType);
sym
}
@@ -77,7 +80,7 @@ trait Namers: Analyzer {
private def enterClassSymbol(pos: int, mods: int, name: Name): Symbol = {
val c: Symbol = context.scope.lookup(name);
if (c.isType && c.isExternal && context.scope == c.owner.info.decls) {
- updatePosFlags(c, pos, mods)
+ updatePosFlags(c, pos, mods);
} else {
enterInScope(context.owner.newClass(pos, name).setFlag(mods))
}
@@ -85,7 +88,7 @@ trait Namers: Analyzer {
private def enterModuleSymbol(pos: int, mods: int, name: Name): Symbol = {
val m: Symbol = context.scope.lookup(name);
- if (m.isModule && !m.isPackage && m.isExternal && (context.scope == m.owner.info.decls)) {
+ if (m.isTerm && !m.isPackage && m.isExternal && (context.scope == m.owner.info.decls)) {
updatePosFlags(m, pos, mods)
} else {
val newm = context.owner.newModule(pos, name);
@@ -97,8 +100,7 @@ trait Namers: Analyzer {
private def enterCaseFactorySymbol(pos: int, mods: int, name: Name): Symbol = {
val m: Symbol = context.scope.lookup(name);
- if (m.isModule && !m.isPackage && m.isExternal && context.scope == m.owner.info.decls) {
- m.resetFlag(MODULE);
+ if (m.isTerm && !m.isPackage && m.isExternal && context.scope == m.owner.info.decls) {
updatePosFlags(m, pos, mods)
} else {
enterInScope(context.owner.newMethod(pos, name).setFlag(mods))
@@ -225,7 +227,7 @@ trait Namers: Analyzer {
def selfTypeCompleter(tree: Tree) = new TypeCompleter(tree) {
override def complete(sym: Symbol): unit = {
- sym.setInfo(typer.transformType(tree).tpe);
+ sym.setInfo(typer.typedType(tree).tpe);
}
}
@@ -285,9 +287,9 @@ trait Namers: Analyzer {
val restype = deconstIfNotFinal(meth,
if (tpt.isEmpty) {
tpt.tpe = if (meth.name == nme.CONSTRUCTOR) context.enclClass.owner.tpe
- else typer.transformExpr(rhs).tpe;
+ else typer.typed(rhs).tpe;
tpt.tpe
- } else typer.transformType(tpt).tpe);
+ } else typer.typedType(tpt).tpe);
def mkMethodType(vparams: List[Symbol], restpe: Type) = {
val formals = vparams map (.tpe);
if (!vparams.isEmpty && vparams.head.hasFlag(IMPLICIT)) {
@@ -303,7 +305,7 @@ trait Namers: Analyzer {
}
private def aliasTypeSig(tpsym: Symbol, tparams: List[AbsTypeDef], rhs: Tree): Type =
- makePolyType(typer.reenterTypeParams(tparams), typer.transformType(rhs).tpe);
+ makePolyType(typer.reenterTypeParams(tparams), typer.typedType(rhs).tpe);
private def typeSig(tree: Tree): Type =
try {
@@ -327,20 +329,19 @@ trait Namers: Analyzer {
context.error(tpt.pos, "missing parameter type");
ErrorType
} else {
- tpt.tpe = newTyper(context.make(tree, sym))
- .transformExpr(rhs).tpe;
+ tpt.tpe = newTyper(context.make(tree, sym)).typed(rhs).tpe;
tpt.tpe
}
- else typer.transformType(tpt).tpe)
+ else typer.typedType(tpt).tpe)
case AliasTypeDef(_, _, tparams, rhs) =>
new Namer(context.makeNewScope(tree, sym)).aliasTypeSig(sym, tparams, rhs)
case AbsTypeDef(_, _, lo, hi) =>
- TypeBounds(typer.transformType(lo).tpe, typer.transformType(hi).tpe);
+ TypeBounds(typer.typedType(lo).tpe, typer.typedType(hi).tpe);
case Import(expr, selectors) =>
- val expr1 = typer.transformQualExpr(expr);
+ val expr1 = typer.typedQualifier(expr);
val base = expr1.tpe;
typer.checkStable(expr1);
def checkSelectors(selectors: List[Pair[Name, Name]]): unit = selectors match {
diff --git a/sources/scala/tools/nsc/typechecker/TreeCheckers.scala b/sources/scala/tools/nsc/typechecker/TreeCheckers.scala
index 907275bc2d..741cfa4ca1 100644
--- a/sources/scala/tools/nsc/typechecker/TreeCheckers.scala
+++ b/sources/scala/tools/nsc/typechecker/TreeCheckers.scala
@@ -26,7 +26,7 @@ abstract class TreeCheckers extends Analyzer {
tpeOfTree.clear;
val checker = new TreeChecker(context);
checker.precheck.traverse(unit.body);
- checker.transformExpr(unit.body);
+ checker.typed(unit.body);
checker.postcheck.traverse(unit.body);
reporter.prompt(curPrompt);
}
@@ -37,7 +37,7 @@ abstract class TreeCheckers extends Analyzer {
import infer._;
- override def transform(tree: Tree, mode: int, pt: Type): Tree = {
+ override def typed(tree: Tree, mode: int, pt: Type): Tree = {
//System.out.println("**** checking " + tree);//debug
tree match {
case EmptyTree | TypeTree() =>
@@ -47,13 +47,14 @@ abstract class TreeCheckers extends Analyzer {
tpeOfTree.update(tree, tree.tpe);
tree.tpe = null
}
- val newtree = super.transform(tree, mode, pt);
+ val newtree = super.typed(tree, mode, pt);
if (newtree ne tree)
error(tree.pos, "trees differ\n old: " + tree + " [" + tree.getClass() + "]\n new: " +
newtree + " [" + newtree.getClass() + "]");
}
tree
}
+ override def typed(tree: Tree) = super.typed(tree); // doto remove for new compiler
object precheck extends Traverser {
override def traverse(tree: Tree): unit = {
diff --git a/sources/scala/tools/nsc/typechecker/Typers.scala b/sources/scala/tools/nsc/typechecker/Typers.scala
index 559d5c83be..a413a75476 100755
--- a/sources/scala/tools/nsc/typechecker/Typers.scala
+++ b/sources/scala/tools/nsc/typechecker/Typers.scala
@@ -24,7 +24,7 @@ abstract class Typers: Analyzer {
def name = "typer";
val global: Typers.this.global.type = Typers.this.global;
def apply(unit: CompilationUnit): unit =
- unit.body = newTyper(startContext.make(unit)).transformExpr(unit.body)
+ unit.body = newTyper(startContext.make(unit)).typed(unit.body)
}
def newTyper(context: Context): Typer = new Typer(context);
@@ -60,34 +60,34 @@ abstract class Typers: Analyzer {
namerCache
}
- var context = context0;
+ private var context = context0;
/** Mode constants
- */
- private val NOmode = 0x000;
- private val EXPRmode = 0x001; // these 3 modes are mutually exclusive.
- private val PATTERNmode = 0x002;
- private val TYPEmode = 0x004;
+ */
+ val NOmode = 0x000;
+ val EXPRmode = 0x001; // these 3 modes are mutually exclusive.
+ val PATTERNmode = 0x002;
+ val TYPEmode = 0x004;
- private val INCONSTRmode = 0x008; // orthogonal to above. When set we are
- // in the body of a constructor
+ val INCONSTRmode = 0x008; // orthogonal to above. When set we are
+ // in the body of a constructor
- private val FUNmode = 0x10; // orthogonal to above. When set
- // we are looking for a method or constructor
+ val FUNmode = 0x10; // orthogonal to above. When set
+ // we are looking for a method or constructor
- private val POLYmode = 0x020; // orthogonal to above. When set
- // expression types can be polymorphic.
+ val POLYmode = 0x020; // orthogonal to above. When set
+ // expression types can be polymorphic.
- private val QUALmode = 0x040; // orthogonal to above. When set
- // expressions may be packages and
- // Java statics modules.
+ val QUALmode = 0x040; // orthogonal to above. When set
+ // 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.
+ val TAPPmode = 0x080; // Set for the function/type constructor part
+ // of a type application. When set we do not
+ // decompose PolyTypes.
- private val SUPERCONSTRmode = 0x100;// Set for the `super' in a superclass constructor call
- // super.<init>
+ val SUPERCONSTRmode = 0x100; // Set for the `super' in a superclass constructor call
+ // super.<init>
private val stickyModes: int = EXPRmode | PATTERNmode | TYPEmode;
@@ -234,10 +234,8 @@ abstract class Typers: Analyzer {
*/
// def adapt(tree: Tree, mode: int, pt: Type): Tree = {
private def adapt(tree: Tree, mode: int, pt: Type): Tree = tree.tpe match {
- case ConstantType(base, value) if (constfold.fold(tree, value) != tree) => // (0)
- adapt(constfold.fold(tree, value), mode, pt)
- case PolyType(List(), restp @ ConstantType(base, value)) => // (0)
- adapt(constfold.fold(tree, value), mode, pt)
+ case ct @ ConstantType(base, value) if (ct <:< pt) => // (0)
+ copy.Literal(tree, value)
case OverloadedType(pre, alts) if ((mode & FUNmode) == 0) => // (1)
inferExprAlternative(tree, pt);
adapt(tree, mode, pt)
@@ -255,11 +253,11 @@ abstract class Typers: Analyzer {
context.undetparams = context.undetparams ::: tparams1;
adapt(tree1 setType restpe.substSym(tparams, tparams1), mode, pt)
case mt: ImplicitMethodType if ((mode & (EXPRmode | FUNmode)) == EXPRmode) => // (4.1)
- transform(applyImplicitArgs(tree), mode, pt)
+ typed(applyImplicitArgs(tree), mode, pt)
case mt: MethodType if ((mode & (EXPRmode | FUNmode)) == EXPRmode &&
isCompatible(tree.tpe, pt)) => // (4.2)
if (tree.symbol.isConstructor) errorTree(tree, "missing arguments for " + tree.symbol)
- else transform(etaExpand(tree), mode, pt)
+ else typed(etaExpand(tree), mode, pt)
case _ =>
if (tree.isType) {
val clazz = tree.tpe.symbol;
@@ -299,37 +297,34 @@ abstract class Typers: Analyzer {
} else if ((mode & (EXPRmode | FUNmode)) == (EXPRmode | FUNmode) &&
((mode & TAPPmode) == 0 || tree.tpe.typeParams.isEmpty) &&
tree.tpe.member(nme.apply).filter(m => m.tpe.paramSectionCount > 0) != NoSymbol) { // (8)
- transform(Select(tree, nme.apply) setPos tree.pos, mode, pt)
+ typed(Select(tree, nme.apply) setPos tree.pos, mode, pt)
} else if (!context.undetparams.isEmpty & (mode & POLYmode) == 0) { // (9)
val tparams = context.undetparams;
context.undetparams = List();
inferExprInstance(tree, tparams, pt);
tree
} else if (tree.tpe <:< pt) {
- tree
+ tree
} else {
val tree1 = constfold(tree, pt); // (10) (11)
- if (tree1 != tree) adapt(tree1, mode, pt);
+ if (tree1.tpe <:< pt) adapt(tree1, mode, pt)
else {
if ((mode & (EXPRmode | FUNmode)) == EXPRmode) {
- assert(pt != null);
- assert(tree1.tpe != null, tree1);
pt match {
case TypeRef(_, sym, _) =>
// note: was if (pt.symbol == UnitClass) but this leads to a potentially
// infinite expansion if pt is constant type ()
- if (sym == UnitClass && tree1.tpe <:< AnyClass.tpe) // (12)
- return transform(atPos(tree.pos)(Block(List(tree), Literal(()))), mode, pt)
+ if (sym == UnitClass && tree.tpe <:< AnyClass.tpe) // (12)
+ return typed(atPos(tree.pos)(Block(List(tree), Literal(()))), mode, pt)
case _ =>
}
if (context.reportGeneralErrors) { // (13); the condition prevents chains of views
val coercion = inferView(tree.pos, tree.tpe, pt, true);
if (coercion != EmptyTree)
- return transform(Apply(coercion, List(tree)) setPos tree.pos, mode, pt);
+ return typed(Apply(coercion, List(tree)) setPos tree.pos, mode, pt);
}
}
System.out.println(tree);
- System.out.println(constfold(tree));
typeErrorTree(tree, tree.tpe, pt)
}
}
@@ -343,18 +338,18 @@ abstract class Typers: Analyzer {
namer.enterValueParams(context.owner, vparamss);
val newTree = New(supertpt) setType
PolyType(tparams, appliedType(supertpt.tpe, tparams map (.tpe)));
- val tree = transformExpr(atPos(supertpt.pos)(Apply(Select(newTree, nme.CONSTRUCTOR), superargs)));
+ val tree = typed(atPos(supertpt.pos)(Apply(Select(newTree, nme.CONSTRUCTOR), superargs)));
if (settings.debug.value) System.out.println("superconstr " + tree + " co = " + context.owner);//debug
tree.tpe
}
def parentTypes(templ: Template): List[Tree] = {
- var supertpt = transform(templ.parents.head, TYPEmode | FUNmode, WildcardType);
- var mixins = templ.parents.tail map transformType;
+ var supertpt = typedTypeConstructor(templ.parents.head);
+ var mixins = templ.parents.tail map typedType;
// If first parent is trait, make it first mixin and add its superclass as first parent
- if (supertpt.tpe.symbol != null && supertpt.tpe.symbol.initialize.isTrait) {
- mixins = transformType(supertpt) :: mixins;
- supertpt = gen.TypeTree(supertpt.tpe.parents.head) setPos supertpt.pos;
+ while (supertpt.tpe.symbol != null && supertpt.tpe.symbol.initialize.isTrait) {
+ mixins = typedType(supertpt) :: mixins;
+ supertpt = TypeTree(supertpt.tpe.parents.head) setPos supertpt.pos;
}
if (supertpt.hasSymbol) {
val tparams = supertpt.symbol.typeParams;
@@ -362,7 +357,7 @@ abstract class Typers: Analyzer {
val constr @ DefDef(_, _, _, vparamss, _, Apply(_, superargs)) =
treeInfo.firstConstructor(templ.body);
val outercontext = context.outer.outer;
- supertpt = gen.TypeTree(
+ supertpt = TypeTree(
newTyper(context.outer.outer.makeNewScope(constr, context.outer.outer.owner))
.completeSuperType(
supertpt,
@@ -426,20 +421,20 @@ abstract class Typers: Analyzer {
}
}
- def transformClassDef(cdef: ClassDef): Tree = {
+ def typedClassDef(cdef: ClassDef): Tree = {
val clazz = cdef.symbol;
reenterTypeParams(cdef.tparams);
- val tparams1 = List.mapConserve(cdef.tparams)(transformAbsTypeDef);
- val tpt1 = checkNoEscaping.privates(clazz.thisSym, transformType(cdef.tpt));
+ val tparams1 = List.mapConserve(cdef.tparams)(typedAbsTypeDef);
+ val tpt1 = checkNoEscaping.privates(clazz.thisSym, typedType(cdef.tpt));
val impl1 = newTyper(context.make(cdef.impl, clazz, new Scope()))
- .transformTemplate(cdef.impl);
+ .typedTemplate(cdef.impl);
copy.ClassDef(cdef, cdef.mods, cdef.name, tparams1, tpt1, impl1) setType NoType
}
- def transformModuleDef(mdef: ModuleDef): Tree = {
+ def typedModuleDef(mdef: ModuleDef): Tree = {
val clazz = mdef.symbol.moduleClass;
val impl1 = newTyper(context.make(mdef.impl, clazz, new Scope()))
- .transformTemplate(mdef.impl);
+ .typedTemplate(mdef.impl);
copy.ModuleDef(mdef, mdef.mods, mdef.name, impl1) setType NoType
}
@@ -450,7 +445,7 @@ abstract class Typers: Analyzer {
val sym = vdef.symbol;
val getter = sym.owner.info.decls.lookup(name).suchThat(.hasFlag(ACCESSOR));
val result = atPos(vdef.pos)(
- gen.DefDef(getter, vparamss =>
+ DefDef(getter, vparamss =>
if ((mods & DEFERRED) != 0) EmptyTree
else stabilize(gen.mkRef(sym), sym.owner.thisType, EXPRmode, sym.tpe)));
checkNoEscaping.privates(result.symbol, result.tpt);
@@ -460,9 +455,9 @@ abstract class Typers: Analyzer {
val sym = vdef.symbol;
val setter = sym.owner.info.decls.lookup(nme.SETTER_NAME(name)).suchThat(.hasFlag(ACCESSOR));
atPos(vdef.pos)(
- gen.DefDef(setter, vparamss =>
+ DefDef(setter, vparamss =>
if ((mods & DEFERRED) != 0) EmptyTree
- else transformExpr(Assign(gen.mkRef(getter.symbol), gen.mkRef(vparamss.head.head)))))
+ else typed(Assign(gen.mkRef(getter.symbol), gen.mkRef(vparamss.head.head)))))
}
val gs = if ((mods & MUTABLE) != 0) List(getter, setter) else List(getter);
if ((mods & DEFERRED) != 0) gs else vdef :: gs
@@ -474,7 +469,7 @@ abstract class Typers: Analyzer {
List(stat)
}
- def transformTemplate(templ: Template): Template = {
+ def typedTemplate(templ: Template): Template = {
if (templ.symbol == NoSymbol)
templ setSymbol context.owner.newLocalDummy(templ.pos);
val parents1 = parentTypes(templ);
@@ -484,27 +479,27 @@ abstract class Typers: Analyzer {
else context.owner.typeOfThis;
validateParentClasses(parents1, selfType);
val body1 = templ.body flatMap addGetterSetter;
- val body2 = transformStats(body1, templ.symbol);
+ val body2 = typedStats(body1, templ.symbol);
copy.Template(templ, parents1, body2) setType context.owner.tpe
}
- def transformValDef(vdef: ValDef): ValDef = {
+ def typedValDef(vdef: ValDef): ValDef = {
val sym = vdef.symbol;
- var tpt1 = checkNoEscaping.privates(sym, transformType(vdef.tpt));
+ var tpt1 = checkNoEscaping.privates(sym, typedType(vdef.tpt));
val rhs1 =
if (vdef.rhs.isEmpty) vdef.rhs
- else newTyper(context.make(vdef, sym)).transform(vdef.rhs, EXPRmode, tpt1.tpe);
+ else newTyper(context.make(vdef, sym)).typed(vdef.rhs, tpt1.tpe);
copy.ValDef(vdef, vdef.mods, vdef.name, tpt1, rhs1) setType NoType
}
- def transformDefDef(ddef: DefDef): DefDef = {
+ def typedDefDef(ddef: DefDef): DefDef = {
val meth = ddef.symbol;
reenterTypeParams(ddef.tparams);
reenterValueParams(ddef.vparamss);
- val tparams1 = List.mapConserve(ddef.tparams)(transformAbsTypeDef);
+ val tparams1 = List.mapConserve(ddef.tparams)(typedAbsTypeDef);
val vparamss1 = List.mapConserve(ddef.vparamss)(vparams1 =>
- List.mapConserve(vparams1)(transformValDef));
- var tpt1 = checkNoEscaping.privates(meth, transformType(ddef.tpt));
+ List.mapConserve(vparams1)(typedValDef));
+ var tpt1 = checkNoEscaping.privates(meth, typedType(ddef.tpt));
val rhs1 =
if (ddef.name == nme.CONSTRUCTOR) {
if (!meth.hasFlag(SYNTHETIC) &&
@@ -514,48 +509,48 @@ abstract class Typers: Analyzer {
meth.owner.isRefinementClass))
error(ddef.pos, "constructor definition not allowed here " + meth.owner);//debug
context.enclClass.owner.setFlag(INCONSTRUCTOR);
- val result = transform(ddef.rhs, EXPRmode | INCONSTRmode, UnitClass.tpe);
+ val result = typed(ddef.rhs, EXPRmode | INCONSTRmode, UnitClass.tpe);
context.enclClass.owner.resetFlag(INCONSTRUCTOR);
result
} else {
- transform(ddef.rhs, EXPRmode, tpt1.tpe);
+ typed(ddef.rhs, tpt1.tpe);
}
copy.DefDef(ddef, ddef.mods, ddef.name, tparams1, vparamss1, tpt1, rhs1) setType NoType
}
- def transformAbsTypeDef(tdef: AbsTypeDef): AbsTypeDef = {
- val lo1 = checkNoEscaping.privates(tdef.symbol, transformType(tdef.lo));
- val hi1 = checkNoEscaping.privates(tdef.symbol, transformType(tdef.hi));
+ def typedAbsTypeDef(tdef: AbsTypeDef): AbsTypeDef = {
+ val lo1 = checkNoEscaping.privates(tdef.symbol, typedType(tdef.lo));
+ val hi1 = checkNoEscaping.privates(tdef.symbol, typedType(tdef.hi));
copy.AbsTypeDef(tdef, tdef.mods, tdef.name, lo1, hi1) setType NoType
}
- def transformAliasTypeDef(tdef: AliasTypeDef): AliasTypeDef = {
+ def typedAliasTypeDef(tdef: AliasTypeDef): AliasTypeDef = {
reenterTypeParams(tdef.tparams);
- val tparams1 = List.mapConserve(tdef.tparams)(transformAbsTypeDef);
- val rhs1 = checkNoEscaping.privates(tdef.symbol, transformType(tdef.rhs));
+ val tparams1 = List.mapConserve(tdef.tparams)(typedAbsTypeDef);
+ val rhs1 = checkNoEscaping.privates(tdef.symbol, typedType(tdef.rhs));
copy.AliasTypeDef(tdef, tdef.mods, tdef.name, tparams1, rhs1) setType NoType
}
- def transformLabelDef(ldef: LabelDef): LabelDef = {
+ def typedLabelDef(ldef: LabelDef): LabelDef = {
var lsym = ldef.symbol;
if (lsym == NoSymbol)
lsym = namer.enterInScope(
context.owner.newLabel(ldef.pos, ldef.name) setInfo MethodType(List(), UnitClass.tpe));
- val rhs1 = transform(ldef.rhs, EXPRmode, UnitClass.tpe);
+ val rhs1 = typed(ldef.rhs, UnitClass.tpe);
copy.LabelDef(ldef, ldef.name, ldef.params, rhs1) setSymbol lsym setType UnitClass.tpe
}
- def transformBlock(block: Block, mode: int, pt: Type): Block = {
+ def typedBlock(block: Block, mode: int, pt: Type): Block = {
namer.enterSyms(block.stats);
val stats1 =
if ((mode & INCONSTRmode) != 0) {
- val constrCall = transform(block.stats.head, mode, WildcardType);
+ val constrCall = typed(block.stats.head, mode, WildcardType);
context.enclClass.owner.resetFlag(INCONSTRUCTOR);
- constrCall :: transformStats(block.stats.tail, context.owner);
+ constrCall :: typedStats(block.stats.tail, context.owner);
} else {
- transformStats(block.stats, context.owner)
+ typedStats(block.stats, context.owner)
}
- val expr1 = transform(block.expr, mode & ~(FUNmode | QUALmode), pt);
+ val expr1 = typed(block.expr, mode & ~(FUNmode | QUALmode), pt);
val block1 = copy.Block(block, stats1, expr1)
setType (if (treeInfo.isPureExpr(block)) expr1.tpe else expr1.tpe.deconst);
if (block1.tpe.symbol.isAnonymousClass)
@@ -563,15 +558,15 @@ abstract class Typers: Analyzer {
if (isFullyDefined(pt)) block1 else checkNoEscaping.locals(context.scope, block1)
}
- def transformCase(cdef: CaseDef, pattpe: Type, pt: Type): CaseDef = {
- val pat1: Tree = transform(cdef.pat, PATTERNmode, pattpe);
+ def typedCase(cdef: CaseDef, pattpe: Type, pt: Type): CaseDef = {
+ val pat1: Tree = typedPattern(cdef.pat, pattpe);
val guard1: Tree = if (cdef.guard == EmptyTree) EmptyTree
- else transform(cdef.guard, EXPRmode, BooleanClass.tpe);
- val body1: Tree = transform(cdef.body, EXPRmode, pt);
+ else typed(cdef.guard, BooleanClass.tpe);
+ val body1: Tree = typed(cdef.body, pt);
copy.CaseDef(cdef, pat1, guard1, body1) setType body1.tpe
}
- def transformFunction(fun: Function, mode: int, pt: Type): Function = {
+ def typedFunction(fun: Function, mode: int, pt: Type): Function = {
val Triple(clazz, argpts, respt) = pt match {
case TypeRef(_, sym, argtps)
if (fun.vparams.length <= MaxFunctionArity && sym == FunctionClass(fun.vparams.length) ||
@@ -591,19 +586,19 @@ abstract class Typers: Analyzer {
namer.enterSym(vparam);
vparam.symbol
}
- val vparams1 = List.mapConserve(fun.vparams)(transformValDef);
- val body1 = transform(fun.body, EXPRmode, respt);
+ val vparams1 = List.mapConserve(fun.vparams)(typedValDef);
+ val body1 = typed(fun.body, respt);
copy.Function(fun, vparams1, body1)
setType typeRef(clazz.tpe.prefix, clazz, (vparamSyms map (.tpe)) ::: List(body1.tpe))
}
- def transformRefinement(stats: List[Tree]): List[Tree] = {
+ def typedRefinement(stats: List[Tree]): List[Tree] = {
namer.enterSyms(stats);
for (val stat <- stats) stat.symbol setFlag OVERRIDE;
- transformStats(stats, NoSymbol);
+ typedStats(stats, NoSymbol);
}
- def transformStats(stats: List[Tree], exprOwner: Symbol): List[Tree] =
+ def typedStats(stats: List[Tree], exprOwner: Symbol): List[Tree] =
List.mapConserve(stats) { stat =>
if (context.owner.isRefinementClass && !treeInfo.isDeclaration(stat))
errorTree(stat, "only declarations allowed here");
@@ -613,23 +608,23 @@ abstract class Typers: Analyzer {
EmptyTree
case _ =>
(if (exprOwner != context.owner && (!stat.isDef || stat.isInstanceOf[LabelDef]))
- newTyper(context.make(stat, exprOwner)) else this).transformExpr(stat)
+ newTyper(context.make(stat, exprOwner)) else this).typed(stat)
}
}
- private def transform1(tree: Tree, mode: int, pt: Type): Tree = {
+ private def typed1(tree: Tree, mode: int, pt: Type): Tree = {
def funmode = mode & stickyModes | FUNmode | POLYmode;
- def transformCases(cases: List[CaseDef], pattp: Type): List[CaseDef] = {
+ def typedCases(cases: List[CaseDef], pattp: Type): List[CaseDef] = {
List.mapConserve(cases)(cdef =>
- newTyper(context.makeNewScope(tree, context.owner)).transformCase(cdef, pattp, pt))
+ newTyper(context.makeNewScope(tree, context.owner)).typedCase(cdef, pattp, pt))
}
- def transformTypeApply(fun: Tree, args: List[Tree]): Tree = fun.tpe match {
+ def typedTypeApply(fun: Tree, args: List[Tree]): Tree = fun.tpe match {
case OverloadedType(pre, alts) =>
inferPolyAlternatives(fun, args.length);
- transformTypeApply(fun, args)
+ typedTypeApply(fun, args)
case PolyType(tparams, restpe) if (tparams.length != 0) =>
if (tparams.length == args.length) {
val targs = args map (.tpe);
@@ -646,12 +641,12 @@ abstract class Typers: Analyzer {
errorTree(tree, treeSymTypeMsg(fun) + " does not take type parameters.");
}
- def transformApply(fun: Tree, args: List[Tree]): Tree = fun.tpe match {
+ def typedApply(fun: Tree, args: List[Tree]): Tree = fun.tpe match {
case OverloadedType(pre, alts) =>
val args1 = List.mapConserve(args)(arg =>
- transform(arg, mode & stickyModes, WildcardType));
+ typed(arg, mode & stickyModes, WildcardType));
inferMethodAlternative(fun, context.undetparams, args1 map (.tpe.deconst), pt);
- transformApply(adapt(fun, funmode, WildcardType), args1);
+ typedApply(adapt(fun, funmode, WildcardType), args1);
case MethodType(formals0, restpe) =>
val formals = formalTypes(formals0, args.length);
if (formals.length != args.length) {
@@ -662,23 +657,20 @@ abstract class Typers: Analyzer {
context.undetparams = List();
if (tparams.isEmpty) {
val args1 = List.map2(args, formals) ((arg, formal) =>
- transform(arg, mode & stickyModes, formal));
+ typed(arg, mode & stickyModes, formal));
def ifPatternSkipFormals(tp: Type) = tp match {
case MethodType(_, rtp) if ((mode & PATTERNmode) != 0) => rtp
case _ => tp
}
- val tree1 = copy.Apply(tree, fun, args1).setType(ifPatternSkipFormals(restpe));
- val tree2 = constfold(tree1);
- if (tree2 != tree1) tree1.tpe = null;
- tree2
+ constfold(copy.Apply(tree, fun, args1).setType(ifPatternSkipFormals(restpe)));
} else {
assert((mode & PATTERNmode) == 0); // this case cannot arise for patterns
val lenientTargs = protoTypeArgs(tparams, formals, restpe, pt);
val strictTargs = List.map2(lenientTargs, tparams)((targ, tparam) =>
if (targ == WildcardType) tparam.tpe else targ);
- def transformArg(tree: Tree, formal: Type): Tree = {
+ def typedArg(tree: Tree, formal: Type): Tree = {
val lenientPt = formal.subst(tparams, lenientTargs);
- val tree1 = transform(tree, mode & stickyModes | POLYmode, lenientPt);
+ val tree1 = typed(tree, mode & stickyModes | POLYmode, lenientPt);
val argtparams = context.undetparams;
context.undetparams = List();
if (!argtparams.isEmpty) {
@@ -687,12 +679,12 @@ abstract class Typers: Analyzer {
}
tree1
}
- val args1 = List.map2(args, formals)(transformArg);
+ val args1 = List.map2(args, formals)(typedArg);
if (args1 exists (.tpe.isError)) setError(tree)
else {
if (settings.debug.value) System.out.println("infer method inst " + fun + ", tparams = " + tparams + ", args = " + args1.map(.tpe) + ", pt = " + pt + ", lobounds = " + tparams.map(.tpe.bounds.lo));//debug
val undetparams = inferMethodInstance(fun, tparams, args1, pt);
- val result = transformApply(fun, args1);
+ val result = typedApply(fun, args1);
context.undetparams = undetparams;
result
}
@@ -725,7 +717,7 @@ abstract class Typers: Analyzer {
/** Attribute a selection where `tree' is `qual.name'.
* `qual' is already attributed.
*/
- def transformSelect(qual: Tree, name: Name): Tree = {
+ def typedSelect(qual: Tree, name: Name): Tree = {
val sym =
if (tree.symbol != NoSymbol) {
val alts = qual.tpe.member(name).alternatives;
@@ -738,14 +730,15 @@ abstract class Typers: Analyzer {
if (sym == NoSymbol && qual.isTerm && (qual.symbol == null || qual.symbol.isValue)) {
val coercion = inferView(qual.pos, qual.tpe, name, true);
if (coercion != EmptyTree)
- return transform(
+ return typed(
copy.Select(tree, Apply(coercion, List(qual)) setPos qual.pos, name), mode, pt)
}
if (sym.info == NoType) {
- System.out.println(qual);
- System.out.println(qual.tpe.members);//debug
- System.out.println(qual.tpe.member(name));//debug
- errorTree(tree, decode(name) + " is not a member of " + qual.tpe.widen)
+ if (settings.debug.value) System.out.println("qual = " + qual + "\nmembers = " + qual.tpe.members);
+ errorTree(tree,
+ decode(name) + " is not a member of " + qual.tpe.widen +
+ (if (Position.line(tree.pos) > Position.line(qual.pos))
+ "\npossible cause: maybe a semicolon is missing before `" + name + "'?" else ""))
} else {
val tree1 = tree match {
case Select(_, _) => copy.Select(tree, qual, name)
@@ -761,7 +754,7 @@ abstract class Typers: Analyzer {
* Transformations: (1) Prefix class members with this.
* (2) Change imported symbols to selections
*/
- def transformIdent(name: Name): Tree = {
+ def typedIdent(name: Name): Tree = {
def ambiguousError(msg: String) =
error(tree.pos, "reference to " + name + " is ambiguous;\n" + msg);
@@ -832,8 +825,10 @@ abstract class Typers: Analyzer {
qual = imports.head.qual;
pre = qual.tpe;
} else {
- System.out.println(context);//debug
- System.out.println(context.imports);//debug
+ if (settings.debug.value) {
+ System.out.println(context);//debug
+ System.out.println(context.imports);//debug
+ }
error(tree.pos, "not found: " + decode(name));
defSym = context.owner.newErrorSymbol(name);
}
@@ -846,40 +841,40 @@ abstract class Typers: Analyzer {
stabilize(checkAccessible(tree1, defSym, pre, qual), pre, mode, pt)
}
- // begin transform1
+ // begin typed1
val sym: Symbol = tree.symbol;
if (sym != null) sym.initialize;
- //if (settings.debug.value && tree.isDef) global.log("transforming definition of " + sym);//DEBUG
+ //if (settings.debug.value && tree.isDef) global.log("typing definition of " + sym);//DEBUG
tree match {
case PackageDef(name, stats) =>
val stats1 = newTyper(context.make(tree, sym.moduleClass, sym.info.decls))
- .transformStats(stats, NoSymbol);
+ .typedStats(stats, NoSymbol);
copy.PackageDef(tree, name, stats1) setType NoType
case cdef @ ClassDef(_, _, _, _, _) =>
- newTyper(context.makeNewScope(tree, sym)).transformClassDef(cdef)
+ newTyper(context.makeNewScope(tree, sym)).typedClassDef(cdef)
case mdef @ ModuleDef(_, _, _) =>
- transformModuleDef(mdef)
+ typedModuleDef(mdef)
case vdef @ ValDef(_, _, _, _) =>
- transformValDef(vdef)
+ typedValDef(vdef)
case ddef @ DefDef(_, _, _, _, _, _) =>
- newTyper(context.makeNewScope(tree, sym)).transformDefDef(ddef)
+ newTyper(context.makeNewScope(tree, sym)).typedDefDef(ddef)
case tdef @ AbsTypeDef(_, _, _, _) =>
- transformAbsTypeDef(tdef)
+ newTyper(context.makeNewScope(tree, sym)).typedAbsTypeDef(tdef)
case tdef @ AliasTypeDef(_, _, _, _) =>
- newTyper(context.makeNewScope(tree, sym)).transformAliasTypeDef(tdef)
+ newTyper(context.makeNewScope(tree, sym)).typedAliasTypeDef(tdef)
case ldef @ LabelDef(_, List(), _) =>
- newTyper(context.makeNewScope(tree, context.owner)).transformLabelDef(ldef)
+ newTyper(context.makeNewScope(tree, context.owner)).typedLabelDef(ldef)
case Attributed(attr, defn) =>
- val attr1 = transform(attr, EXPRmode, AttributeClass.tpe);
- val defn1 = transform(defn, mode, pt);
+ val attr1 = typed(attr, AttributeClass.tpe);
+ val defn1 = typed(defn, mode, pt);
val existing = attributes.get(defn1.symbol) match {
case None => List()
case Some(attrs) => attrs
@@ -888,18 +883,18 @@ abstract class Typers: Analyzer {
defn1
case DocDef(comment, defn) =>
- transform(defn, mode, pt);
+ typed(defn, mode, pt);
case block @ Block(_, _) =>
newTyper(context.makeNewScope(tree, context.owner))
- .transformBlock(block, mode, pt)
+ .typedBlock(block, mode, pt)
case Sequence(elems) =>
- val elems1 = List.mapConserve(elems)(elem => transform(elem, mode, pt));
+ val elems1 = List.mapConserve(elems)(elem => typed(elem, mode, pt));
copy.Sequence(tree, elems1) setType pt
case Alternative(alts) =>
- val alts1 = List.mapConserve(alts)(alt => transform(alt, mode, pt));
+ val alts1 = List.mapConserve(alts)(alt => typed(alt, mode, pt));
copy.Alternative(tree, alts1) setType pt
case Bind(name, body) =>
@@ -909,31 +904,31 @@ abstract class Typers: Analyzer {
if (vble.name != nme.WILDCARD) namer.enterInScope(vble);
}
vble.setInfo(pt);
- val body1 = transform(body, mode, pt);
+ val body1 = typed(body, mode, pt);
vble.setInfo(if (treeInfo.isSequenceValued(body)) seqType(body1.tpe) else body1.tpe);
copy.Bind(tree, name, body1) setSymbol vble setType pt
case fun @ Function(_, _) =>
newTyper(context.makeNewScope(tree, context.owner))
- .transformFunction(fun, mode, pt)
+ .typedFunction(fun, mode, pt)
case Assign(lhs, rhs) =>
def isGetter(sym: Symbol) = sym.info match {
case PolyType(List(), _) => sym.owner.isClass && !sym.isStable
case _ => false
}
- val lhs1 = transformExpr(lhs);
+ val lhs1 = typed(lhs);
val varsym = lhs1.symbol;
if (varsym != null && isGetter(varsym)) {
lhs1 match {
case Select(qual, name) =>
- transform(
+ typed(
Apply(
Select(qual, nme.SETTER_NAME(name)) setPos lhs.pos,
List(rhs)) setPos tree.pos, mode, pt)
}
} else if (varsym != null && varsym.isVariable) {
- val rhs1 = transform(rhs, EXPRmode, lhs1.tpe);
+ val rhs1 = typed(rhs, lhs1.tpe);
copy.Assign(tree, lhs1, rhs1) setType UnitClass.tpe;
} else {
System.out.println("" + lhs1 + " " + varsym + " " + flagsToString(varsym.flags));//debug
@@ -942,19 +937,19 @@ abstract class Typers: Analyzer {
}
case If(cond, thenp, elsep) =>
- val cond1 = transform(cond, EXPRmode, BooleanClass.tpe);
+ val cond1 = typed(cond, BooleanClass.tpe);
if (elsep.isEmpty) {
- val thenp1 = transform(thenp, EXPRmode, UnitClass.tpe);
+ val thenp1 = typed(thenp, UnitClass.tpe);
copy.If(tree, cond1, thenp1, elsep) setType UnitClass.tpe
} else {
- val thenp1 = transform(thenp, EXPRmode, pt);
- val elsep1 = transform(elsep, EXPRmode, pt);
+ val thenp1 = typed(thenp, pt);
+ val elsep1 = typed(elsep, pt);
copy.If(tree, cond1, thenp1, elsep1) setType lub(List(thenp1.tpe, elsep1.tpe));
}
case Match(selector, cases) =>
- val selector1 = transformExpr(selector);
- val cases1 = transformCases(cases, selector1.tpe);
+ val selector1 = typed(selector);
+ val cases1 = typedCases(cases, selector1.tpe);
copy.Match(tree, selector1, cases1) setType lub(cases1 map (.tpe))
case Return(expr) =>
@@ -964,24 +959,24 @@ abstract class Typers: Analyzer {
else if (!context.owner.hasFlag(INITIALIZED))
errorTree(tree, "method " + context.owner + " has return statement; needs result type")
else {
- val expr1: Tree = transform(expr, EXPRmode, enclFun.tpe.resultType);
+ val expr1: Tree = typed(expr, enclFun.tpe.resultType);
copy.Return(tree, expr1) setSymbol enclFun setType AllClass.tpe;
}
case Try(block, catches, finalizer) =>
- val block1 = transform(block, EXPRmode, pt);
- val catches1 = transformCases(catches, ThrowableClass.tpe);
+ val block1 = typed(block, pt);
+ val catches1 = typedCases(catches, ThrowableClass.tpe);
val finalizer1 = if (finalizer.isEmpty) finalizer
- else transform(finalizer, EXPRmode, UnitClass.tpe);
+ else typed(finalizer, UnitClass.tpe);
copy.Try(tree, block1, catches1, finalizer1)
setType lub(block1.tpe :: (catches1 map (.tpe)))
case Throw(expr) =>
- val expr1 = transform(expr, EXPRmode, ThrowableClass.tpe);
+ val expr1 = typed(expr, ThrowableClass.tpe);
copy.Throw(tree, expr1) setType AllClass.tpe
case New(tpt: Tree) =>
- var tpt1 = transform(tpt, TYPEmode | FUNmode, WildcardType);
+ var tpt1 = typedTypeConstructor(tpt);
if (tpt1.hasSymbol && !tpt1.symbol.typeParams.isEmpty) {
context.undetparams = cloneSymbols(tpt1.symbol.unsafeTypeParams);
tpt1 = TypeTree()
@@ -991,7 +986,7 @@ abstract class Typers: Analyzer {
copy.New(tree, tpt1).setType(tpt1.tpe)
case Typed(expr, tpt @ Ident(name)) if (name == nme.WILDCARD_STAR.toTypeName) =>
- val expr1 = transform(expr, mode & stickyModes, seqType(pt));
+ val expr1 = typed(expr, mode & stickyModes, seqType(pt));
expr1.tpe.baseType(SeqClass) match {
case TypeRef(_, _, List(elemtp)) =>
copy.Typed(tree, expr1, tpt setType elemtp) setType elemtp
@@ -999,18 +994,18 @@ abstract class Typers: Analyzer {
setError(tree)
}
case Typed(expr, tpt) =>
- val tpt1 = transformType(tpt);
- val expr1 = transform(expr, mode & stickyModes, tpt1.tpe);
+ val tpt1 = typedType(tpt);
+ val expr1 = typed(expr, mode & stickyModes, tpt1.tpe);
copy.Typed(tree, expr1, tpt1) setType tpt1.tpe
case TypeApply(fun, args) =>
- val args1 = List.mapConserve(args)(transformType);
+ val args1 = List.mapConserve(args)(typedType);
// do args first in order to maintain conext.undetparams on the function side.
- transformTypeApply(transform(fun, funmode | TAPPmode, WildcardType), args1)
+ typedTypeApply(typed(fun, funmode | TAPPmode, WildcardType), args1)
case Apply(fun, args) =>
val funpt = if ((mode & PATTERNmode) != 0) pt else WildcardType;
- var fun1 = transform(fun, funmode, funpt);
+ var fun1 = typed(fun, funmode, funpt);
// if function is overloaded, filter all alternatives that match
// number of arguments and expected result type.
// if (settings.debug.value) System.out.println("trans app " + fun1 + ":" + fun1.symbol + ":" + fun1.tpe + " " + args);//DEBUG
@@ -1023,7 +1018,7 @@ abstract class Typers: Analyzer {
fun1 = adapt(fun1 setSymbol sym setType pre.memberType(sym), funmode, WildcardType)
}
appcnt = appcnt + 1;
- transformApply(fun1, args)
+ typedApply(fun1, args)
case Super(qual, mix) =>
val clazz = if (tree.symbol != NoSymbol) tree.symbol else qualifyingClass(qual);
@@ -1054,51 +1049,51 @@ abstract class Typers: Analyzer {
}
case Select(qual @ Super(_, _), nme.CONSTRUCTOR) =>
- val qual1 = transform(qual, EXPRmode | QUALmode | POLYmode | SUPERCONSTRmode, WildcardType);
+ val qual1 = typed(qual, EXPRmode | QUALmode | POLYmode | SUPERCONSTRmode, WildcardType);
// the qualifier type of a supercall constructor is its first parent class
- transformSelect(qual1, nme.CONSTRUCTOR);
+ typedSelect(qual1, nme.CONSTRUCTOR);
case Select(qual, name) =>
selcnt = selcnt + 1;
assert (name != nme.CONSTRUCTOR || !qual.isInstanceOf[Super], tree);//debug
- var qual1 = transform(qual, EXPRmode | QUALmode | POLYmode, WildcardType);
+ var qual1 = typedQualifier(qual);
if (name.isTypeName) qual1 = checkStable(qual1);
- transformSelect(qual1, name);
+ typedSelect(qual1, name);
case Ident(name) =>
idcnt = idcnt + 1;
if (name == nme.WILDCARD && (mode & (PATTERNmode | FUNmode)) == PATTERNmode)
tree setType pt
else
- transformIdent(name);
+ typedIdent(name);
case Literal(value) =>
tree setType
(if (value == ()) UnitClass.tpe else ConstantType(constfold.literalType(value), value))
case SingletonTypeTree(ref) =>
- val ref1 = checkStable(transform(ref, EXPRmode | QUALmode, AnyRefClass.tpe));
+ val ref1 = checkStable(typed(ref, EXPRmode | QUALmode, AnyRefClass.tpe));
tree setType ref1.tpe.resultType;
case SelectFromTypeTree(qual, selector) =>
- tree setType transformSelect(transformType(qual), selector).tpe
+ tree setType typedSelect(typedType(qual), selector).tpe
case CompoundTypeTree(templ: Template) =>
tree setType {
- val parents1 = List.mapConserve(templ.parents)(transformType);
+ val parents1 = List.mapConserve(templ.parents)(typedType);
if (parents1 exists (.tpe.isError)) ErrorType
else {
val decls = new Scope();
val self = refinedType(parents1 map (.tpe), context.enclClass.owner, decls);
- newTyper(context.make(tree, self.symbol, new Scope())).transformRefinement(templ.body);
+ newTyper(context.make(tree, self.symbol, new Scope())).typedRefinement(templ.body);
self
}
}
case AppliedTypeTree(tpt, args) =>
- val tpt1 = transform(tpt, mode | FUNmode | TAPPmode, WildcardType);
+ val tpt1 = typed(tpt, mode | FUNmode | TAPPmode, WildcardType);
val tparams = tpt1.tpe.symbol.typeParams;
- val args1 = List.mapConserve(args)(transformType);
+ val args1 = List.mapConserve(args)(typedType);
if (tpt1.tpe.isError)
setError(tree)
else if (tparams.length == args1.length)
@@ -1110,13 +1105,13 @@ abstract class Typers: Analyzer {
}
}
- def transform(tree: Tree, mode: int, pt: Type): Tree =
+ def typed(tree: Tree, mode: int, pt: Type): Tree =
try {
if (settings.debug.value) {
assert(pt != null, tree);//debug
- //System.out.println("transforming " + tree);//DEBUG
+ //System.out.println("typing " + tree);//DEBUG
}
- val tree1 = if (tree.tpe != null) tree else transform1(tree, mode, pt);
+ val tree1 = if (tree.tpe != null) tree else typed1(tree, mode, pt);
if (tree1.isEmpty) tree1 else adapt(tree1, mode, pt)
} catch {
case ex: TypeError =>
@@ -1124,13 +1119,22 @@ abstract class Typers: Analyzer {
setError(tree)
case ex: Throwable =>
if (true || settings.debug.value)//!!!
- System.out.println("exception when transforming " + tree + ", pt = " + pt);
+ System.out.println("exception when typing " + tree + ", pt = " + pt);
throw(ex)
}
- 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);
+ def typed(tree: Tree): Tree =
+ typed(tree, EXPRmode, WildcardType);
+ def typed(tree: Tree, pt: Type): Tree =
+ typed(tree, EXPRmode, pt);
+ def typedQualifier(tree: Tree): Tree =
+ typed(tree, EXPRmode | QUALmode | POLYmode, WildcardType);
+ def typedPattern(tree: Tree, pt: Type): Tree =
+ typed(tree, PATTERNmode, pt);
+ def typedType(tree: Tree): Tree =
+ typed(tree, TYPEmode, WildcardType);
+ def typedTypeConstructor(tree: Tree): Tree =
+ typed(tree, TYPEmode | FUNmode, WildcardType);
/* -- Views --------------------------------------------------------------- */
@@ -1139,61 +1143,89 @@ abstract class Typers: Analyzer {
case _ => tp
}
- private def transformImplicit(pos: int, info: ImplicitInfo, pt: Type): Tree =
+ private def typedImplicit(pos: int, info: ImplicitInfo, pt: Type, local: boolean): Tree =
if (isCompatible(depoly(info.tpe), pt)) {
implcnt = implcnt + 1;
var tree: Tree = EmptyTree;
+ def fail(reason: String): Tree = {
+ if (settings.debug.value)
+ System.out.println(tree.toString() + " is not a valid implicit value because:\n" + reason);
+ EmptyTree
+ }
try {
- tree = transform1(Ident(info.name) setPos pos, EXPRmode, pt);
- if (settings.debug.value) System.out.println("transformed implicit " + tree + ":" + tree.tpe + ", pt = " + pt);//debug
+ tree = Ident(info.name) setPos pos;
+ if (!local) tree setSymbol info.sym;
+ tree = typed1(tree, EXPRmode, pt);
+ if (settings.debug.value) System.out.println("typed implicit " + tree + ":" + tree.tpe + ", pt = " + pt);//debug
val tree1 = adapt(tree, EXPRmode, pt);
if (settings.debug.value) System.out.println("adapted implicit " + tree.symbol + ":" + info.sym);//debug
- if (info.sym == tree.symbol) tree1 else EmptyTree
+ if (info.sym == tree.symbol) tree1
+ else fail("syms differ: " + tree.symbol + " " + info.sym)
} catch {
- case ex: TypeError =>
- if (settings.debug.value)
- System.out.println(tree.toString() + " is not a valid implicit value because:\n" + ex.getMessage());
- EmptyTree
+ case ex: TypeError => fail(ex.getMessage())
}
} else EmptyTree;
private def inferImplicit(pos: int, pt: Type, isView: boolean, reportAmbiguous: boolean): Tree = {
+
def isBetter(sym1: Symbol, tpe1: Type, sym2: Symbol, tpe2: Type): boolean =
+ sym2.isError ||
(sym1.owner != sym2.owner) && (sym1.owner isSubClass sym2.owner) && (tpe1 matches tpe2);
+
val tc = newTyper(context.makeImplicit(reportAmbiguous));
- var iss = context.implicitss;
- var tree: Tree = EmptyTree;
- while (tree == EmptyTree && !iss.isEmpty) {
- var is = iss.head;
- //System.out.println("testing " + is.head.sym + is.head.sym.locationString + ":" + is.head.tpe);//DEBUG
- iss = iss.tail;
- while (!is.isEmpty) {
- tree = tc.transformImplicit(pos, is.head, pt);
- val is0 = is;
- is = is.tail;
- if (tree != EmptyTree) {
- while (!is.isEmpty) {
- val tree1 = tc.transformImplicit(pos, is.head, pt);
- if (tree1 != EmptyTree) {
- if (isBetter(is.head.sym, tree1.tpe, is0.head.sym, tree.tpe))
- tree = tree1
- else if (!isBetter(is0.head.sym, tree.tpe, is.head.sym, tree1.tpe))
- error(
- pos,
- "ambiguous implicit value:\n" +
- " both " + is0.head.sym + is0.head.sym.locationString + " of type " + tree.tpe +
- "\n and" + is.head.sym + is.head.sym.locationString + " of type " + tree1.tpe +
- (if (isView)
- "\n are possible conversion functions from " +
- pt.typeArgs(0) + " to " + pt.typeArgs(1)
- else
- "\n match expected type " + pt));
+
+ def searchImplicit(implicitInfoss: List[List[ImplicitInfo]], local: boolean): Tree = {
+ var iss = implicitInfoss;
+ var tree: Tree = EmptyTree;
+ while (tree == EmptyTree && !iss.isEmpty) {
+ var is = iss.head;
+ iss = iss.tail;
+ while (!is.isEmpty) {
+ tree = tc.typedImplicit(pos, is.head, pt, local);
+ if (settings.debug.value) System.out.println("tested " + is.head.sym + is.head.sym.locationString + ":" + is.head.tpe + "=" + tree);//debug
+ val is0 = is;
+ is = is.tail;
+ if (tree != EmptyTree) {
+ while (!is.isEmpty) {
+ val tree1 = tc.typedImplicit(pos, is.head, pt, local);
+ if (tree1 != EmptyTree) {
+ if (isBetter(is.head.sym, tree1.tpe, is0.head.sym, tree.tpe))
+ tree = tree1
+ else if (!isBetter(is0.head.sym, tree.tpe, is.head.sym, tree1.tpe))
+ error(
+ pos,
+ "ambiguous implicit value:\n" +
+ " both " + is0.head.sym + is0.head.sym.locationString + " of type " + tree.tpe +
+ "\n and" + is.head.sym + is.head.sym.locationString + " of type " + tree1.tpe +
+ (if (isView)
+ "\n are possible conversion functions from " +
+ pt.typeArgs(0) + " to " + pt.typeArgs(1)
+ else
+ "\n match expected type " + pt));
+ }
+ is = is.tail
}
- is = is.tail
}
}
}
+ tree
+ }
+
+ def implicitsOfType(tp: Type): List[List[ImplicitInfo]] = {
+ val tp1 =
+ if (tp.typeArgs.length - 1 <= MaxFunctionArity &&
+ tp.symbol == FunctionClass(tp.typeArgs.length - 1))
+ intersectionType(tp.typeArgs.reverse)
+ else tp;
+ tp1.baseClasses map implicitsOfClass;
}
+
+ def implicitsOfClass(clazz: Symbol): List[ImplicitInfo] =
+ clazz.initialize.linkedModule.moduleClass.info.decls.toList.filter(.hasFlag(IMPLICIT)) map
+ (sym => ImplicitInfo(sym.name, clazz.linkedModule.tpe.memberType(sym), sym));
+
+ var tree = searchImplicit(context.implicitss, true);
+ if (tree == EmptyTree) tree = searchImplicit(implicitsOfType(pt.widen), false);
tree
}
diff --git a/sources/scala/tools/nsc/typechecker/Variances.scala b/sources/scala/tools/nsc/typechecker/Variances.scala
index f3e5f52b9f..7257a6c832 100755
--- a/sources/scala/tools/nsc/typechecker/Variances.scala
+++ b/sources/scala/tools/nsc/typechecker/Variances.scala
@@ -5,12 +5,20 @@
// $Id$
package scala.tools.nsc.typechecker;
+import symtab.Flags._;
+
/** Variances form a lattice, 0 <= COVARIANT <= Variances, 0 <= CONTRAVARIANT <= VARIANCES
*/
-abstract class Variances: Analyzer {
+abstract class Variances {
+ val global: Global;
import global._;
- import symtab.Flags._;
+
+ /** Convert variance to string */
+ private def varianceString(variance: int): String =
+ if (variance == COVARIANT) "covariant"
+ else if (variance == CONTRAVARIANT) "contravariant"
+ else "invariant";
/** Flip between covariant and contravariant */
private def flip(v: int): int = {
@@ -19,6 +27,11 @@ abstract class Variances: Analyzer {
else v
}
+ private def compose(v1: int, v2: int) =
+ if (v1 == 0) 0
+ else if (v1 == CONTRAVARIANT) flip(v2)
+ else v2;
+
/** Map everything below VARIANCES to 0 */
private def cut(v: int): int =
if (v == VARIANCES) v else 0;
diff --git a/test/files/dis/List.check b/test/files/dis/List.check
index 4a06d4688c..fd9e49834e 100644
--- a/test/files/dis/List.check
+++ b/test/files/dis/List.check
@@ -1,4 +1,4 @@
-trait List[+a]() extends scala.Seq[a] with scala.ScalaObject {
+sealed trait List[+a]() extends scala.Seq[a] with scala.ScalaObject {
def isEmpty: scala.Boolean;
def head: a;
def tail: scala.List[a];