diff options
author | Martin Odersky <odersky@gmail.com> | 2005-05-19 16:51:03 +0000 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2005-05-19 16:51:03 +0000 |
commit | e34cd16629590a88bcf5a340886a0b287f0f2d86 (patch) | |
tree | 47a4180f082295cb082213e221844a96f4f17b79 | |
parent | 329705355e946923a94296352845a50d2680a9e5 (diff) | |
download | scala-e34cd16629590a88bcf5a340886a0b287f0f2d86.tar.gz scala-e34cd16629590a88bcf5a340886a0b287f0f2d86.tar.bz2 scala-e34cd16629590a88bcf5a340886a0b287f0f2d86.zip |
a
29 files changed, 176 insertions, 140 deletions
diff --git a/sources/scala/List.scala b/sources/scala/List.scala index 5d4e37f93c..fa89d33c93 100644 --- a/sources/scala/List.scala +++ b/sources/scala/List.scala @@ -260,7 +260,7 @@ object List { /** Lists with ordered elements are ordered */ - def view[a <% Ordered[a]](x: List[a]): Ordered[List[a]] = new Ordered[List[a]] { + implicit def list2ordered[a <% Ordered[a]](x: List[a]): Ordered[List[a]] = new Ordered[List[a]] { def compareTo [b >: List[a] <% Ordered[b]](y: b): int = y match { case y1: List[a] => compareLists(x, y1); case _ => -(y compareTo x) @@ -276,6 +276,7 @@ object List { } } } + def view[a <% Ordered[a]](x: List[a]): Ordered[List[a]] = list2ordered(x); } /** A trait representing an ordered collection of elements of type diff --git a/sources/scala/Predef.scala b/sources/scala/Predef.scala index 97c3453fe4..88f0e72015 100644 --- a/sources/scala/Predef.scala +++ b/sources/scala/Predef.scala @@ -142,7 +142,7 @@ object Predef { // views ------------------------------------------------------------- - implicit def view(x: int): Ordered[int] = new Ordered[int] with Proxy { + implicit def int2ordered(x: int): Ordered[int] = new Ordered[int] with Proxy { def self: Any = x; def compareTo [b >: int <% Ordered[b]](y: b): int = y match { case y1: int => @@ -152,8 +152,9 @@ object Predef { case _ => -(y compareTo x) } } + def view(x: int): Ordered[int] = int2ordered(x); - implicit def view(x: char): Ordered[char] = new Ordered[char] with Proxy { + implicit def char2ordered(x: char): Ordered[char] = new Ordered[char] with Proxy { def self: Any = x; def compareTo [b >: char <% Ordered[b]](y: b): int = y match { case y1: char => @@ -163,8 +164,9 @@ object Predef { case _ => -(y compareTo x) } } + def view(x: char): Ordered[char] = char2ordered(x); - implicit def view(x: long): Ordered[long] = new Ordered[long] with Proxy { + implicit def long2ordered(x: long): Ordered[long] = new Ordered[long] with Proxy { def self: Any = x; def compareTo [b >: long <% Ordered[b]](y: b): int = y match { case y1: long => @@ -174,8 +176,9 @@ object Predef { case _ => -(y compareTo x) } } + def view(x: long): Ordered[long] = long2ordered(x); - implicit def view(x: float): Ordered[float] = new Ordered[float] with Proxy { + implicit def float2ordered(x: float): Ordered[float] = new Ordered[float] with Proxy { def self: Any = x; def compareTo [b >: float <% Ordered[b]](y: b): int = y match { case y1: float => @@ -185,8 +188,9 @@ object Predef { case _ => -(y compareTo x) } } + def view(x: float): Ordered[float] = float2ordered(x); - implicit def view(x: double): Ordered[double] = new Ordered[double] with Proxy { + implicit def double2ordered(x: double): Ordered[double] = new Ordered[double] with Proxy { def self: Any = x; def compareTo [b >: double <% Ordered[b]](y: b): int = y match { case y1: double => @@ -196,8 +200,9 @@ object Predef { case _ => -(y compareTo x) } } + def view(x: double): Ordered[double] = double2ordered(x); - implicit def view(x: boolean): Ordered[boolean] = new Ordered[boolean] with Proxy { + implicit def boolean2ordered(x: boolean): Ordered[boolean] = new Ordered[boolean] with Proxy { def self: Any = x; def compareTo [b >: boolean <% Ordered[b]](y: b): int = y match { case y1: boolean => @@ -207,8 +212,9 @@ object Predef { case _ => -(y compareTo x) } } + def view(x: boolean): Ordered[boolean] = boolean2ordered(x); - implicit def view[A <% Ordered[A]](xs: Array[A]): Ordered[Array[A]] = new Ordered[Array[A]] with Proxy { + implicit def array2ordered[A <% Ordered[A]](xs: Array[A]): Ordered[Array[A]] = new Ordered[Array[A]] with Proxy { def self: Any = xs; def compareTo[B >: Array[A] <% Ordered[B]](that: B): Int = that match { case ys: Array[A] => @@ -225,6 +231,7 @@ object Predef { -(that compareTo xs) } } + def view[A <% Ordered[A]](xs: Array[A]): Ordered[Array[A]] = array2ordered(xs); private def first(xs: Int*): Int = xs.elements.find(x => x != 0) match { case Some(r) => r @@ -280,15 +287,18 @@ object Predef { } */ - implicit def view(x: String): Ordered[String] = new Ordered[String] with Proxy { + implicit def string2ordered(x: String): Ordered[String] = new Ordered[String] with Proxy { def self: Any = x; def compareTo [b >: String <% Ordered[b]](y: b): int = y match { case y1: String => x compareTo y1; case _ => -(y compareTo x) } } + def view(x: String): Ordered[String] = string2ordered(x); - implicit def view[A](xs: Array[A]): Seq[A] = new Seq[A] { + implicit def ordered2ordered[a <: Ordered[a]](x: a): Ordered[a] = x; + + implicit def array2seq[A](xs: Array[A]): Seq[A] = new Seq[A] { def length = xs.length; def elements = Iterator.fromArray(xs); def apply(n: Int) = xs(n); @@ -296,8 +306,9 @@ object Predef { override def equals(y: Any): Boolean = (xs == y); override protected def stringPrefix: String = "Array"; } + def view[A](xs: Array[A]): Seq[A] = array2seq(xs); - implicit def view(str: String): Seq[Char] = new Seq[Char] { + implicit def string2seq(str: String): Seq[Char] = new Seq[Char] { def length = str.length(); def elements = Iterator.fromString(str); def apply(n: Int) = str.charAt(n); @@ -305,6 +316,7 @@ object Predef { override def equals(y: Any): Boolean = (str == y); override protected def stringPrefix: String = "String"; } + def view(x: String): Seq[Char] = string2seq(x); implicit def byte2short(x: byte): short = x.coerce; implicit def byte2int(x: byte): int = x.coerce; diff --git a/sources/scala/concurrent/MailBox.scala b/sources/scala/concurrent/MailBox.scala index c4598f6bab..573b05a7a0 100644 --- a/sources/scala/concurrent/MailBox.scala +++ b/sources/scala/concurrent/MailBox.scala @@ -11,7 +11,7 @@ package scala.concurrent; //class MailBox with Monitor with LinkedListQueueCreator { -class MailBox with ListQueueCreator { +abstract class MailBox extends AnyRef with ListQueueCreator { type Message = AnyRef; diff --git a/sources/scala/concurrent/SyncChannel.scala b/sources/scala/concurrent/SyncChannel.scala index 4bc2c7abce..6cab7b2ad6 100644 --- a/sources/scala/concurrent/SyncChannel.scala +++ b/sources/scala/concurrent/SyncChannel.scala @@ -15,7 +15,7 @@ class SyncChannel[a] { private var reading = false; private var writing = false; - def await(def cond: Boolean) = while (!cond) { wait() } + def await(cond: => Boolean) = while (!cond) { wait() } def write(x: a) = synchronized { await(!writing); diff --git a/sources/scala/concurrent/jolib.scala b/sources/scala/concurrent/jolib.scala index f6e5065475..e7d19b5bd5 100644 --- a/sources/scala/concurrent/jolib.scala +++ b/sources/scala/concurrent/jolib.scala @@ -21,7 +21,7 @@ object jolib { /////////////////// JOIN DEFINITION ///////////////////////// - class Join with Monitor { + class Join { private var ruls: List[Pair[Pattern, Rule]] = null; diff --git a/sources/scala/concurrent/ops.scala b/sources/scala/concurrent/ops.scala index b0d25c2585..04bee676ec 100644 --- a/sources/scala/concurrent/ops.scala +++ b/sources/scala/concurrent/ops.scala @@ -12,18 +12,18 @@ package scala.concurrent; object ops { - def spawn(def p: Unit) = { + def spawn(p: => Unit) = { val t = new Thread() { override def run() = p; } t.start() } - def future[a](def p: a): () => a = { + def future[a](p: => a): () => a = { val result = new SyncVar[a]; spawn { result set p } () => result.get } - def par[a, b](def xp: a, def yp: b): Pair[a, b] = { + def par[a, b](xp: => a, yp: => b): Pair[a, b] = { val y = new SyncVar[b]; spawn { y set yp } Pair(xp, y.get) diff --git a/sources/scala/concurrent/pilib.scala b/sources/scala/concurrent/pilib.scala index a58b882901..9fb9d3a6ef 100644 --- a/sources/scala/concurrent/pilib.scala +++ b/sources/scala/concurrent/pilib.scala @@ -26,14 +26,14 @@ object pilib { * spawn < p_1 | ... | p_n > */ trait Spawn { - def <(def p: unit): Spawn; - def |(def p: unit): Spawn; + def <(p: => unit): Spawn; + def |(p: => unit): Spawn; def > : unit; } val spawn = new Spawn { //object spawn extends Spawn { // BUG ! - def <(def p: unit): Spawn = { scala.concurrent.ops.spawn(p); this } - def |(def p: unit): Spawn = { scala.concurrent.ops.spawn(p); this } + def <(p: => unit): Spawn = { scala.concurrent.ops.spawn(p); this } + def |(p: => unit): Spawn = { scala.concurrent.ops.spawn(p); this } def > : unit = () } @@ -101,7 +101,7 @@ object pilib { } class Product[a](c: Chan[a], v: a) { - def *[b](def f: b) = c.output(v, () => f); + def *[b](f: => b) = c.output(v, () => f); } //////////////////// SUM OF GUARDED PROCESSES ////////////////////// diff --git a/sources/scala/runtime/matching/Address.scala b/sources/scala/runtime/matching/Address.scala index 4f9299cc57..2e4c409fd8 100644 --- a/sources/scala/runtime/matching/Address.scala +++ b/sources/scala/runtime/matching/Address.scala @@ -4,21 +4,24 @@ object Address { def empty = new Address(); } +import List.list2ordered; + /** Address holds the path in reverse Dewey notation */ -class Address( l:Int* ) with Ordered[Address] { +class Address( l:Int* ) extends Ordered[Address] { private val list:List[Int] = l.toList; def compareTo [b >: Address <% Ordered[b]](y: b): int = y match { - case o:Address => List.view(list.reverse) compareTo o.list.reverse; + case o:Address => list.reverse.compareTo(o.list.reverse) + //(xs => List.view(xs)(Predef.int2ordered)); case _ => -(y compareTo this) } def down: Address = new Address( ( 1 :: list ):_* ); /** precond: p is nonempty */ - def right: Address = list.match { + def right: Address = list match { case i :: rest => new Address( ((i+1) :: rest ):_* ) } diff --git a/sources/scala/runtime/matching/Rule.scala b/sources/scala/runtime/matching/Rule.scala index 9aabeb4870..6f5b867fcd 100644 --- a/sources/scala/runtime/matching/Rule.scala +++ b/sources/scala/runtime/matching/Rule.scala @@ -1,7 +1,7 @@ package scala.runtime.matching ; /* hedge grammar rules */ -abstract class Rule with Ordered[Rule] { +abstract class Rule extends Ordered[Rule] { def compareTo [b >: Rule <% Ordered[b]](that: b): int = that match { case r:Rule => diff --git a/sources/scala/testing/SUnit.scala b/sources/scala/testing/SUnit.scala index 3bb5ed04c5..12771e5b56 100644 --- a/sources/scala/testing/SUnit.scala +++ b/sources/scala/testing/SUnit.scala @@ -40,7 +40,7 @@ object SUnit { } /** a TestCase defines the fixture to run multiple tests */ - class TestCase(val name: String) with Test with Assert { + class TestCase(val name: String) extends Test with Assert { protected def createResult() = new TestResult(); @@ -101,7 +101,7 @@ object SUnit { } /** a TestSuite runs a composite of test cases */ - class TestSuite(tests:Test*) with Test { + class TestSuite(tests:Test*) extends Test { def this(names:Seq[String], constr:String=>Test) = this((names.toList map constr):_*); @@ -130,55 +130,55 @@ object SUnit { /** this trait defined useful assert methods */ trait Assert { /** equality */ - def assertEquals[A](msg:String, expected:A, def actual:A): Unit = + def assertEquals[A](msg:String, expected:A, actual: => A): Unit = if( expected != actual ) fail(msg); /** equality */ - def assertEquals[A](expected:A, def actual:A): Unit = + def assertEquals[A](expected:A, actual: => A): Unit = assertEquals("(no message)", expected, actual); /** falseness */ - def assertFalse(msg:String, def actual: Boolean): Unit = + def assertFalse(msg:String, actual: => Boolean): Unit = assertEquals(msg, false, actual); /** falseness */ - def assertFalse(def actual: Boolean): Unit = + def assertFalse(actual: => Boolean): Unit = assertFalse("(no message)", actual); /** not null */ - def assertNotNull(msg:String, def actual: AnyRef): Unit = + def assertNotNull(msg:String, actual: => AnyRef): Unit = if( null == actual ) fail(msg); /** not null */ - def assertNotNull(def actual: AnyRef): Unit = + def assertNotNull(actual: => AnyRef): Unit = assertNotNull("(no message)", actual); /** reference inequality */ - def assertNotSame(msg:String, def expected: AnyRef, def actual: AnyRef): Unit = + def assertNotSame(msg:String, expected: => AnyRef, actual: => AnyRef): Unit = if(expected.eq(actual)) fail(msg); /** reference inequality */ - def assertNotSame(def expected: AnyRef, def actual: AnyRef): Unit = + def assertNotSame(expected: => AnyRef, actual: => AnyRef): Unit = assertNotSame("(no message)", expected, actual); /** null */ - def assertNull(msg:String, def actual: AnyRef): Unit = + def assertNull(msg:String, actual: => AnyRef): Unit = if( null != actual ) fail(msg); /** null */ - def assertNull(def actual: AnyRef): Unit = + def assertNull(actual: => AnyRef): Unit = assertNull("(no message)", actual); /** reference equality */ - def assertSame(msg:String, def expected: AnyRef, def actual: AnyRef): Unit = + def assertSame(msg:String, expected: => AnyRef, actual: => AnyRef): Unit = if(!expected.eq(actual)) fail(msg); /** reference equality */ - def assertSame(def expected: AnyRef, def actual: AnyRef): Unit = + def assertSame(expected: => AnyRef, actual: => AnyRef): Unit = assertNull("(no message)", actual); /** trueness */ - def assertTrue(msg:String, def actual: Boolean): Unit = + def assertTrue(msg:String, actual: => Boolean): Unit = assertEquals(msg, true, actual); /** trueness */ - def assertTrue(def actual: Boolean): Unit = + def assertTrue(actual: => Boolean): Unit = assertTrue("(no message)", actual); /** throws AssertFailed with given message */ diff --git a/sources/scala/tools/nsc/Global.scala b/sources/scala/tools/nsc/Global.scala index ca5c913c23..95de98a498 100755 --- a/sources/scala/tools/nsc/Global.scala +++ b/sources/scala/tools/nsc/Global.scala @@ -218,7 +218,9 @@ class Global(val settings: Settings, val reporter: Reporter) extends SymbolTable } def compileLate(file: AbstractFile): unit = - if (!(fileset contains file)) { + if (fileset == null) + throw new FatalError("No symbol file for " + file + " was found\n(This file cannot be loaded as a source file)"); + else if (!(fileset contains file)) { val unit = new CompilationUnit(getSourceFile(file)); addUnit(unit); atPhase(parserPhase) { parserPhase(unit) } diff --git a/sources/scala/tools/nsc/Settings.scala b/sources/scala/tools/nsc/Settings.scala index af39d7b6ad..a65c34f057 100644 --- a/sources/scala/tools/nsc/Settings.scala +++ b/sources/scala/tools/nsc/Settings.scala @@ -34,7 +34,7 @@ class Settings(error: String => unit) { val noimports = BooleanSetting("-noimports", "Compile without any implicit imports"); val nopredefs = BooleanSetting("-nopredefs", "Compile without any implicit predefined values"); val skip = PhasesSetting ("-skip", "Skip"); - val check = PhasesSetting ("-check", "Check the tree after"); + val check = PhasesSetting ("-check", "Check the tree at start of"); val print = PhasesSetting ("-print", "Print out program after"); val printer = ChoiceSetting ("-printer", "Printer to use", List("text", "html"), "text"); val printfile = StringSetting ("-printfile", "file", "Specify file in which to print trees", "-"); diff --git a/sources/scala/tools/nsc/ast/TreeBuilder.scala b/sources/scala/tools/nsc/ast/TreeBuilder.scala index f2b46aa6ed..96b79dc411 100755 --- a/sources/scala/tools/nsc/ast/TreeBuilder.scala +++ b/sources/scala/tools/nsc/ast/TreeBuilder.scala @@ -19,8 +19,9 @@ abstract class TreeBuilder { def freshName(): Name = freshName("x$"); private object patvarTransformer extends Transformer { + private var boundVars: List[Name] = List(nme.WILDCARD); override def transform(tree: Tree): Tree = tree match { - case Ident(name) if (treeInfo.isVariableName(name) && name != nme.WILDCARD) => + case Ident(name) if (treeInfo.isVariableName(name) && !(boundVars exists (name.==))) => 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 @@ -30,7 +31,12 @@ abstract class TreeBuilder { copy.Apply(tree, fn, transformTrees(args)) case Typed(expr, tpt) => copy.Typed(tree, transform(expr), tpt) - case Sequence(_) | Alternative(_) | Bind(_, _) => + case Bind(name, body) => + boundVars = name :: boundVars; + val body1 = transform(body); + boundVars = boundVars.tail; + copy.Bind(tree, name, body1) + case Sequence(_) | Alternative(_) => super.transform(tree) case _ => tree diff --git a/sources/scala/tools/nsc/ast/TreeGen.scala b/sources/scala/tools/nsc/ast/TreeGen.scala index d0b1d6a2f6..06aca77217 100755 --- a/sources/scala/tools/nsc/ast/TreeGen.scala +++ b/sources/scala/tools/nsc/ast/TreeGen.scala @@ -62,12 +62,12 @@ abstract class TreeGen { def TypeTree(tp: Type) = global.TypeTree() setType tp; def This(sym: Symbol) = - typer.transformQualExpr(global.This(sym.name) setSymbol sym); + global.This(sym.name) setSymbol sym setType sym.thisType; def Ident(sym: Symbol) = { assert(sym.isTerm); sym.setFlag(ACCESSED); - typer.transformExpr(global.Ident(sym.name) setSymbol sym); + global.Ident(sym.name) setSymbol sym setType sym.tpe; } def Select(qual: Tree, sym: Symbol) = { @@ -76,6 +76,14 @@ abstract class TreeGen { 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 diff --git a/sources/scala/tools/nsc/ast/TreeInfo.scala b/sources/scala/tools/nsc/ast/TreeInfo.scala index c0ffe8f4b3..249f68f0e0 100644 --- a/sources/scala/tools/nsc/ast/TreeInfo.scala +++ b/sources/scala/tools/nsc/ast/TreeInfo.scala @@ -71,6 +71,8 @@ abstract class TreeInfo { isPureExpr(fn) case Typed(expr, _) => isPureExpr(expr) + case Block(stats, expr) => + (stats forall isPureDef) && isPureExpr(expr) case _ => false } diff --git a/sources/scala/tools/nsc/symtab/SymbolTable.scala b/sources/scala/tools/nsc/symtab/SymbolTable.scala index cef83f99fa..de57388c29 100755 --- a/sources/scala/tools/nsc/symtab/SymbolTable.scala +++ b/sources/scala/tools/nsc/symtab/SymbolTable.scala @@ -17,6 +17,7 @@ abstract class SymbolTable extends Names def settings: Settings; def rootLoader: LazyType; + private var CNT = 0; private var ph: Phase = NoPhase; def phase: Phase = ph; def phase_=(p: Phase): unit = { diff --git a/sources/scala/tools/nsc/symtab/Symbols.scala b/sources/scala/tools/nsc/symtab/Symbols.scala index a42e5f3df9..07d5b0f12f 100755 --- a/sources/scala/tools/nsc/symtab/Symbols.scala +++ b/sources/scala/tools/nsc/symtab/Symbols.scala @@ -188,7 +188,7 @@ abstract class Symbols: SymbolTable { final def info: Type = { var cnt = 0; while ((rawflags & INITIALIZED) == 0) { - if (settings.debug.value) System.out.println("completing " + this + " in " + this.owner);//debug + //if (settings.debug.value) System.out.println("completing " + this + " in " + this.owner);//DEBUG assert(infos != null, this.name); val tp = infos.info; if ((rawflags & LOCKED) != 0) { @@ -199,8 +199,8 @@ abstract class Symbols: SymbolTable { val current = phase; phase = infos.start; tp.complete(this); - if ((rawflags & INITIALIZED) != 0 && settings.debug.value) - System.out.println("completed " + this/* + ":" + info*/);//debug + // if (settings.debug.value && (rawflags & INITIALIZED) != 0) System.out.println("completed " + this/* + ":" + info*/);//DEBUG + rawflags = rawflags & ~LOCKED; phase = current; cnt = cnt + 1; diff --git a/sources/scala/tools/nsc/symtab/Types.scala b/sources/scala/tools/nsc/symtab/Types.scala index 56a72ed968..0c05ae7027 100755 --- a/sources/scala/tools/nsc/symtab/Types.scala +++ b/sources/scala/tools/nsc/symtab/Types.scala @@ -462,6 +462,7 @@ abstract class Types: SymbolTable { override def prefixString: String = if (sym.isEmptyPackage && !settings.debug.value) "" else pre.prefixString + sym.nameString + "."; + assert(prefixString != "Nil.");//debug } /** A class for the bounds of abstract types and type parameters @@ -575,6 +576,7 @@ abstract class Types: SymbolTable { /** A class representing a constant type */ case class ConstantType(base: Type, value: Any) extends SingletonType { + assert(base.symbol != UnitClass); override def symbol: Symbol = base.symbol; override def singleDeref: Type = base; override def deconst: Type = base; @@ -803,6 +805,13 @@ abstract class Types: SymbolTable { /** A creator for intersection type where intersections of a single type are * replaced by the type itself. */ + def intersectionType(tps: List[Type], owner: Symbol): Type = tps match { + case List(tp) => tp + case _ => refinedType(tps, owner) + } + + /** A creator for intersection type where intersections of a single type are + * replaced by the type itself. */ def intersectionType(tps: List[Type]): Type = tps match { case List(tp) => tp case _ => refinedType(tps, commonOwner(tps)) @@ -1438,7 +1447,7 @@ abstract class Types: SymbolTable { val lubBaseTypes: Array[Type] = lubArray(closures); val lubParents = spanningTypes(List.fromArray(lubBaseTypes)); val lubOwner = commonOwner(ts); - val lubBase = refinedType(lubParents, lubOwner); + val lubBase = intersectionType(lubParents, lubOwner); val lubType = refinedType(lubParents, lubOwner); val lubThisType = lubType.symbol.thisType; val narrowts = ts map (.narrow); @@ -1505,7 +1514,7 @@ abstract class Types: SymbolTable { case ts => try { val glbOwner = commonOwner(ts); - val glbBase = refinedType(ts, glbOwner); + val glbBase = intersectionType(ts, glbOwner); val glbType = refinedType(ts, glbOwner); val glbThisType = glbType.symbol.thisType; def glbsym(proto: Symbol): Symbol = { diff --git a/sources/scala/tools/nsc/symtab/classfile/MetaParser.scala b/sources/scala/tools/nsc/symtab/classfile/MetaParser.scala index 07ccc96748..b2fdbe0dc8 100755 --- a/sources/scala/tools/nsc/symtab/classfile/MetaParser.scala +++ b/sources/scala/tools/nsc/symtab/classfile/MetaParser.scala @@ -65,13 +65,12 @@ abstract class MetaParser{ else if (token == "-") { nextToken(); Flags.CONTRAVARIANT } else 0; assert(token.startsWith("?")); - val sym = owner.newTypeParameter(Position.NOPOS, newTypeName(token)) - .setFlag(vflag) - .setInfo(TypeBounds( - definitions.AllClass.tpe, - definitions.AnyClass.tpe)); - locals enter sym; + val sym = owner.newTypeParameter(Position.NOPOS, newTypeName(token)).setFlag(vflag); nextToken(); + val lo = if (token == ">") { nextToken(); parseType() } else definitions.AllClass.tpe; + val hi = if (token == "<") { nextToken(); parseType() } else definitions.AnyClass.tpe; + sym.setInfo(TypeBounds(lo, hi)); + locals enter sym; sym } diff --git a/sources/scala/tools/nsc/typechecker/ConstantFolder.scala b/sources/scala/tools/nsc/typechecker/ConstantFolder.scala index 6fa914ea45..8fcac5ad5f 100755 --- a/sources/scala/tools/nsc/typechecker/ConstantFolder.scala +++ b/sources/scala/tools/nsc/typechecker/ConstantFolder.scala @@ -27,9 +27,9 @@ abstract class ConstantFolder { }); def fold(tree: Tree, value: Any): Tree = - if (value != NoValue) + if (value != NoValue && value != ()) { copy.Literal(tree, value) setType ConstantType(literalType(value), value) - else tree; + } 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/EtaExpansion.scala b/sources/scala/tools/nsc/typechecker/EtaExpansion.scala index 3403d6f5d1..27bc991283 100644 --- a/sources/scala/tools/nsc/typechecker/EtaExpansion.scala +++ b/sources/scala/tools/nsc/typechecker/EtaExpansion.scala @@ -56,6 +56,8 @@ abstract class EtaExpansion: Analyzer { /** Eta-expand lifted tree */ def expand(tree: Tree, tpe: Type): Tree = tpe match { + case mt: ImplicitMethodType => + tree case MethodType(formals, restpe) => val params = formals map (formal => ValDef(SYNTHETIC | PARAM, freshName(), TypeTree().setType(formal), EmptyTree)); diff --git a/sources/scala/tools/nsc/typechecker/Typers.scala b/sources/scala/tools/nsc/typechecker/Typers.scala index c0fa939ba8..559d5c83be 100755 --- a/sources/scala/tools/nsc/typechecker/Typers.scala +++ b/sources/scala/tools/nsc/typechecker/Typers.scala @@ -192,13 +192,14 @@ abstract class Typers: Analyzer { private def stabilize(tree: Tree, pre: Type, mode: int, pt: Type): Tree = { if (tree.symbol.hasFlag(OVERLOADED) && (mode & FUNmode) == 0) inferExprAlternative(tree, pt); + val sym = tree.symbol; if ((mode & (PATTERNmode | FUNmode)) == PATTERNmode && tree.isTerm) // (1) checkStable(tree) - else if ((mode & (EXPRmode | QUALmode)) == EXPRmode && !tree.symbol.isValue) // (2) - errorTree(tree, tree.symbol.toString() + " is not a value"); - else if (tree.symbol.isStable && pre.isStable && tree.tpe.symbol != ByNameParamClass && - (pt.isStable || (mode & QUALmode) != 0 || tree.symbol.isModule)) // (3) - tree.setType(singleType(pre, tree.symbol)) + else if ((mode & (EXPRmode | QUALmode)) == EXPRmode && !sym.isValue) // (2) + errorTree(tree, sym.toString() + " is not a value"); + else if (sym.isStable && pre.isStable && tree.tpe.symbol != ByNameParamClass && + (pt.isStable || (mode & QUALmode) != 0 || sym.isModule)) // (3) + tree.setType(singleType(pre, sym)) else tree } @@ -313,14 +314,22 @@ abstract class Typers: Analyzer { if ((mode & (EXPRmode | FUNmode)) == EXPRmode) { assert(pt != null); assert(tree1.tpe != null, tree1); - if (pt.symbol == UnitClass && tree1.tpe <:< AnyClass.tpe) // (12) - return transform(atPos(tree.pos)(Block(List(tree), Literal(()))), mode, pt) - else if (context.reportGeneralErrors) { // (13); the condition prevents chains of views + 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) + 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); } } + System.out.println(tree); + System.out.println(constfold(tree)); typeErrorTree(tree, tree.tpe, pt) } } @@ -443,7 +452,7 @@ abstract class Typers: Analyzer { val result = atPos(vdef.pos)( gen.DefDef(getter, vparamss => if ((mods & DEFERRED) != 0) EmptyTree - else stabilize(gen.mkRef(sym), sym.owner.thisType, EXPRmode, sym.tpe.deconst))); + else stabilize(gen.mkRef(sym), sym.owner.thisType, EXPRmode, sym.tpe))); checkNoEscaping.privates(result.symbol, result.tpt); result } @@ -471,7 +480,7 @@ abstract class Typers: Analyzer { val parents1 = parentTypes(templ); val selfType = if (context.owner.isAnonymousClass) - refinedType(context.owner.info.parents, context.owner.owner) + intersectionType(context.owner.info.parents, context.owner.owner) else context.owner.typeOfThis; validateParentClasses(parents1, selfType); val body1 = templ.body flatMap addGetterSetter; @@ -484,8 +493,7 @@ abstract class Typers: Analyzer { var tpt1 = checkNoEscaping.privates(sym, transformType(vdef.tpt)); val rhs1 = if (vdef.rhs.isEmpty) vdef.rhs - else constfold( - newTyper(context.make(vdef, sym)).transform(vdef.rhs, EXPRmode, tpt1.tpe.deconst)); + else newTyper(context.make(vdef, sym)).transform(vdef.rhs, EXPRmode, tpt1.tpe); copy.ValDef(vdef, vdef.mods, vdef.name, tpt1, rhs1) setType NoType } @@ -529,10 +537,12 @@ abstract class Typers: Analyzer { } def transformLabelDef(ldef: LabelDef): LabelDef = { - val lsym = namer.enterInScope( - context.owner.newLabel(ldef.pos, ldef.name) setInfo MethodType(List(), UnitClass.tpe)); + 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); - copy.LabelDef(ldef, ldef.name, ldef.params, rhs1) setType UnitClass.tpe + copy.LabelDef(ldef, ldef.name, ldef.params, rhs1) setSymbol lsym setType UnitClass.tpe } def transformBlock(block: Block, mode: int, pt: Type): Block = { @@ -546,9 +556,10 @@ abstract class Typers: Analyzer { transformStats(block.stats, context.owner) } val expr1 = transform(block.expr, mode & ~(FUNmode | QUALmode), pt); - val block1 = copy.Block(block, stats1, expr1) setType expr1.tpe.deconst; + val block1 = copy.Block(block, stats1, expr1) + setType (if (treeInfo.isPureExpr(block)) expr1.tpe else expr1.tpe.deconst); if (block1.tpe.symbol.isAnonymousClass) - block1 setType refinedType(block1.tpe.parents, block1.tpe.symbol.owner); + block1 setType intersectionType(block1.tpe.parents, block1.tpe.symbol.owner); if (isFullyDefined(pt)) block1 else checkNoEscaping.locals(context.scope, block1) } @@ -656,7 +667,10 @@ abstract class Typers: Analyzer { case MethodType(_, rtp) if ((mode & PATTERNmode) != 0) => rtp case _ => tp } - constfold(copy.Apply(tree, fun, args1).setType(ifPatternSkipFormals(restpe))) + val tree1 = copy.Apply(tree, fun, args1).setType(ifPatternSkipFormals(restpe)); + val tree2 = constfold(tree1); + if (tree2 != tree1) tree1.tpe = null; + tree2 } else { assert((mode & PATTERNmode) == 0); // this case cannot arise for patterns val lenientTargs = protoTypeArgs(tparams, formals, restpe, pt); @@ -793,10 +807,10 @@ abstract class Typers: Analyzer { ambiguousError( "it is both defined in " + defSym.owner + " and imported subsequently by \n" + imports.head); - else if (defSym.owner.isClass && !defSym.owner.isPackageClass && !defSym.isTypeParameter) - qual = atPos(tree.pos)(gen.mkQualifier(pre)); + else if (!defSym.owner.isClass || defSym.owner.isPackageClass || defSym.isTypeParameter) + pre = NoPrefix else - pre = NoPrefix; + qual = atPos(tree.pos)(gen.mkQualifier(pre)); } else { if (impSym.tpe != NoType) { var impSym1 = NoSymbol; @@ -825,6 +839,7 @@ abstract class Typers: Analyzer { } } } + if (defSym.owner.isPackageClass) pre = defSym.owner.thisType; val tree1 = if (qual == EmptyTree) tree else atPos(tree.pos)(Select(qual, name)); // atPos necessary because qualifier might come from startContext @@ -888,11 +903,14 @@ abstract class Typers: Analyzer { copy.Alternative(tree, alts1) setType pt case Bind(name, body) => + var vble = tree.symbol; + if (vble == NoSymbol) { + vble = context.owner.newValue(tree.pos, name); + if (vble.name != nme.WILDCARD) namer.enterInScope(vble); + } + vble.setInfo(pt); val body1 = transform(body, mode, pt); - val vble = context.owner.newValue(tree.pos, name).setInfo( - if (treeInfo.isSequenceValued(body)) seqType(pt) else body1.tpe); - //todo: check whether we can always use body1.tpe - namer.enterInScope(vble); + vble.setInfo(if (treeInfo.isSequenceValued(body)) seqType(body1.tpe) else body1.tpe); copy.Bind(tree, name, body1) setSymbol vble setType pt case fun @ Function(_, _) => @@ -1055,7 +1073,8 @@ abstract class Typers: Analyzer { transformIdent(name); case Literal(value) => - tree setType ConstantType(constfold.literalType(value), 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)); @@ -1115,14 +1134,18 @@ abstract class Typers: Analyzer { /* -- Views --------------------------------------------------------------- */ + private def depoly(tp: Type): Type = tp match { + case PolyType(tparams, restpe) => restpe.subst(tparams, tparams map (t => WildcardType)) + case _ => tp + } + private def transformImplicit(pos: int, info: ImplicitInfo, pt: Type): Tree = - if (isCompatible(info.tpe, pt)) { + if (isCompatible(depoly(info.tpe), pt)) { implcnt = implcnt + 1; var tree: Tree = 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 - if (settings.debug.value) assert(isCompatible(tree.tpe, pt), "bad impl " + info.tpe + " " + tree.tpe + " " + 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 @@ -1142,7 +1165,7 @@ abstract class Typers: Analyzer { var tree: Tree = EmptyTree; while (tree == EmptyTree && !iss.isEmpty) { var is = iss.head; - if (settings.debug.value) System.out.println("testing " + is.head.sym + ":" + is.head.tpe);//debug + //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); diff --git a/sources/scala/xml/NodeTraverser.scala b/sources/scala/xml/NodeTraverser.scala deleted file mode 100644 index 052219ceae..0000000000 --- a/sources/scala/xml/NodeTraverser.scala +++ /dev/null @@ -1,35 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2004, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -** $Id$ -\* */ - -package scala.xml ; - -import scala.collection.mutable ; - -class NodeTraverser[A <: AnyRef](handle: parsing.MarkupHandler[A]) { - - def traverse(n: Node): Iterable[A] = n match { - case Text(t) => handle.text(0,t); - case ProcInstr(ta,te) => handle.procInstr(0,ta,te); - case Comment(t) => handle.comment(0,t); - case EntityRef(n) => handle.entityRef(0,n); - case _ => - val nb = new mutable.ArrayBuffer[A](); - val it = n.child.elements; - while(it.hasNext) { - nb.appendAll(traverse(it.next)); - } - handle.element(0, n.namespace, n.label, n.attributes, nb) - } - -} - -class NodeSubstitution(handle: parsing.ConstructingHandler) - extends NodeTraverser[Node](handle) with Function1[Node,Iterable[Node]] { - def apply(n: Node) = traverse(n); -} diff --git a/sources/scala/xml/dtd/ContentModel.scala b/sources/scala/xml/dtd/ContentModel.scala index 42885c3e07..eefbc01207 100644 --- a/sources/scala/xml/dtd/ContentModel.scala +++ b/sources/scala/xml/dtd/ContentModel.scala @@ -56,7 +56,7 @@ object ContentModel extends scala.util.regexp.WordExp { } } - def toString(c: ContentModel, sb: StringBuffer): StringBuffer = c.match { + def toString(c: ContentModel, sb: StringBuffer): StringBuffer = c match { case ANY => sb.append("ANY"); diff --git a/sources/scala/xml/dtd/Parser.scala b/sources/scala/xml/dtd/Parser.scala index 0f43d3b1fd..55cf18635f 100644 --- a/sources/scala/xml/dtd/Parser.scala +++ b/sources/scala/xml/dtd/Parser.scala @@ -34,7 +34,7 @@ object Parser extends Scanner { // a bit too permissive concerning #PCDATA def contentspec: ContentModel = token match { - case NAME => value.match { + case NAME => value match { case "ANY" => ANY case "EMPTY" => EMPTY case _ => error("expected ANY, EMPTY or '(' instead of " + value ); diff --git a/sources/scala/xml/parsing/ConstructingHandler.scala b/sources/scala/xml/parsing/ConstructingHandler.scala index 2810fb1ad5..fac22b7015 100644 --- a/sources/scala/xml/parsing/ConstructingHandler.scala +++ b/sources/scala/xml/parsing/ConstructingHandler.scala @@ -1,9 +1,9 @@ package scala.xml.parsing; /** implementation of MarkupHandler that constructs nodes */ -abstract class ConstructingHandler(presWS: Boolean) extends MarkupHandler { +abstract class ConstructingHandler extends MarkupHandler { - val preserveWS = presWS; + val preserveWS: boolean; def elem(pos: int, pre: String, label: String, attrs: MetaData, pscope: NamespaceBinding, nodes: NodeSeq): NodeSeq = Elem(pre, label, attrs, pscope, nodes:_*); diff --git a/sources/scala/xml/parsing/ConstructingParser.scala b/sources/scala/xml/parsing/ConstructingParser.scala index cf06398458..ac2a2e4259 100644 --- a/sources/scala/xml/parsing/ConstructingParser.scala +++ b/sources/scala/xml/parsing/ConstructingParser.scala @@ -11,10 +11,11 @@ object ConstructingParser { /** an xml parser. parses XML and invokes callback methods of a MarkupHandler */ class ConstructingParser(inp: scala.io.Source, presWS:Boolean) -extends MarkupHandler -with MarkupParser(inp) -with ConstructingHandler(presWS) { +extends ConstructingHandler +with MarkupParser { + val preserveWS = presWS; + val input = inp; val handle = this; } diff --git a/sources/scala/xml/parsing/MarkupParser.scala b/sources/scala/xml/parsing/MarkupParser.scala index 486936852e..80a02aecfc 100644 --- a/sources/scala/xml/parsing/MarkupParser.scala +++ b/sources/scala/xml/parsing/MarkupParser.scala @@ -16,7 +16,9 @@ import scala.xml.dtd._ ; * and returns whatever the markup handler returns. Use ConstructingParser * if you just want to parse XML to construct instances of scala.xml.Node. */ -abstract class MarkupParser(_input: Source): MarkupHandler with TokenTests { +abstract class MarkupParser: (MarkupParser with MarkupHandler) extends AnyRef with TokenTests { + + val input: Source; // // variables, values @@ -88,7 +90,7 @@ abstract class MarkupParser(_input: Source): MarkupHandler with TokenTests { } if(!m.isPrefixed && m.key == "standalone") { - m.value.match { + m.value match { case "yes" => info_stdl = Some(true); case "no" => @@ -136,7 +138,7 @@ abstract class MarkupParser(_input: Source): MarkupHandler with TokenTests { val children = content(TopScope); // DTD handled as side effect var elemCount = 0; var theNode: Node = _; - for(val c <- children) c.match { + for(val c <- children) c match { case _:ProcInstr => ; case _:Comment => ; case _:EntityRef => // todo: fix entities, shouldn't be "special" @@ -452,7 +454,7 @@ abstract class MarkupParser(_input: Source): MarkupHandler with TokenTests { * PUBLIC S pubid S syslit */ - def externalID(): ExternalID = ch.match { + def externalID(): ExternalID = ch match { case 'S' => nextch; xToken("YSTEM"); @@ -690,7 +692,7 @@ abstract class MarkupParser(_input: Source): MarkupHandler with TokenTests { xProcInstr; // simply ignore processing instructions! else { xToken('!'); - ch.match { + ch match { case '-' => xComment ; // ignore comments @@ -766,7 +768,7 @@ abstract class MarkupParser(_input: Source): MarkupHandler with TokenTests { case '#' => nextch; - xName.match { + xName match { case "FIXED" => xSpace; val defValue = xAttributeValue(); // default value @@ -842,7 +844,7 @@ abstract class MarkupParser(_input: Source): MarkupHandler with TokenTests { /** 'N' notationDecl ::= "OTATION" */ - def notationDecl() = { + def notationDecl(): Unit = { xToken("OTATION"); xSpace; val notat = xName; diff --git a/sources/scala/xml/transform/BasicTransformer.scala b/sources/scala/xml/transform/BasicTransformer.scala index 84db52a280..56bbc16201 100644 --- a/sources/scala/xml/transform/BasicTransformer.scala +++ b/sources/scala/xml/transform/BasicTransformer.scala @@ -1,7 +1,7 @@ package scala.xml.transform ; /** a trait for XML transformations */ -trait BasicTransformer with Function1[Node,Node] { +trait BasicTransformer extends Function1[Node,Node] { protected case class NeedsCopy(result:Seq[Node]) extends java.lang.Throwable; |