diff options
author | Martin Odersky <odersky@gmail.com> | 2005-05-11 13:26:06 +0000 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2005-05-11 13:26:06 +0000 |
commit | 88a54be387762d1fdf96a8a128c84e95e613873c (patch) | |
tree | bfa66bd637aa0d44e40631403a4b879ccb6e98d4 /sources | |
parent | cb6e13ecc4c8f011709d971519ac8aec57b7497a (diff) | |
download | scala-88a54be387762d1fdf96a8a128c84e95e613873c.tar.gz scala-88a54be387762d1fdf96a8a128c84e95e613873c.tar.bz2 scala-88a54be387762d1fdf96a8a128c84e95e613873c.zip |
*** empty log message ***
Diffstat (limited to 'sources')
84 files changed, 949 insertions, 676 deletions
diff --git a/sources/scala/$colon$colon.scala b/sources/scala/$colon$colon.scala index f14183694f..78cac34599 100644 --- a/sources/scala/$colon$colon.scala +++ b/sources/scala/$colon$colon.scala @@ -11,6 +11,7 @@ package scala; import java.io.Serializable; +import Predef._; /** A non empty list characterized by a head and a tail. * diff --git a/sources/scala/Console.scala b/sources/scala/Console.scala index 7e0826ec78..86f62276f1 100644 --- a/sources/scala/Console.scala +++ b/sources/scala/Console.scala @@ -9,6 +9,7 @@ package scala; +import Predef._; /** The <code>Console</code> object implements functionality for * printing Scala values on the terminal. There are also functions diff --git a/sources/scala/Enumeration.scala b/sources/scala/Enumeration.scala index 90335ca4db..8348e92ab7 100644 --- a/sources/scala/Enumeration.scala +++ b/sources/scala/Enumeration.scala @@ -10,6 +10,7 @@ package scala; import scala.collection.mutable._; +import Predef._; /** * <p>The class <code>Enumeration</code> provides the same functionality as the diff --git a/sources/scala/IterableProxy.scala b/sources/scala/IterableProxy.scala index 537b2dcb10..19bae8825d 100644 --- a/sources/scala/IterableProxy.scala +++ b/sources/scala/IterableProxy.scala @@ -16,21 +16,23 @@ package scala; * @author Matthias Zenger * @version 1.0, 26/04/2004 */ -class IterableProxy[+A](x: Iterable[A]) extends Iterable[A] with Proxy(x) { +trait IterableProxy[+A] extends Iterable[A] with Proxy { + + def self: Iterable[A]; /** Creates a new iterator over all elements contained in this * object. * * @return the new iterator */ - def elements: Iterator[A] = x.elements; + def elements: Iterator[A] = self.elements; /** Apply a function <code>f</code> to all elements of this * iterable object. * * @param f a function that is applied to every element. */ - override def foreach(f: A => Unit): Unit = x.foreach(f); + override def foreach(f: A => Unit): Unit = self.foreach(f); /** Apply a predicate <code>p</code> to all elements of this * iterable object and return true, iff the predicate yields @@ -39,7 +41,7 @@ class IterableProxy[+A](x: Iterable[A]) extends Iterable[A] with Proxy(x) { * @param p the predicate * @returns true, iff the predicate yields true for all elements. */ - override def forall(p: A => Boolean): Boolean = x.forall(p); + override def forall(p: A => Boolean): Boolean = self.forall(p); /** Apply a predicate <code>p</code> to all elements of this * iterable object and return true, iff there is at least one @@ -48,7 +50,7 @@ class IterableProxy[+A](x: Iterable[A]) extends Iterable[A] with Proxy(x) { * @param p the predicate * @returns true, iff the predicate yields true for at least one element. */ - override def exists(p: A => Boolean): Boolean = x.exists(p); + override def exists(p: A => Boolean): Boolean = self.exists(p); /** Find and return the first element of the iterable object satisfying a * predicate, if any. @@ -57,7 +59,7 @@ class IterableProxy[+A](x: Iterable[A]) extends Iterable[A] with Proxy(x) { * @return the first element in the iterable object satisfying <code>p</code>, * or <code>None</code> if none exists. */ - override def find(p: A => Boolean): Option[A] = x.find(p); + override def find(p: A => Boolean): Option[A] = self.find(p); /** Combines the elements of this list together using the binary * operator <code>op</code>, from left to right, and starting with @@ -65,7 +67,7 @@ class IterableProxy[+A](x: Iterable[A]) extends Iterable[A] with Proxy(x) { * @return <code>op(... (op(op(z,a0),a1) ...), an)</code> if the list * is <code>List(a0, a1, ..., an)</code>. */ - override def foldLeft[B](z: B)(op: (B, A) => B): B = x.foldLeft(z)(op); + override def foldLeft[B](z: B)(op: (B, A) => B): B = self.foldLeft(z)(op); /** Combines the elements of this list together using the binary * operator <code>op</code>, from rigth to left, and starting with @@ -73,23 +75,23 @@ class IterableProxy[+A](x: Iterable[A]) extends Iterable[A] with Proxy(x) { * @return <code>a0 op (... op (an op z)...)</code> if the list * is <code>[a0, a1, ..., an]</code>. */ - override def foldRight[B](z: B)(op: (A, B) => B): B = x.foldRight(z)(op); + override def foldRight[B](z: B)(op: (A, B) => B): B = self.foldRight(z)(op); /** Similar to <code>foldLeft</code> but can be used as * an operator with the order of list and zero arguments reversed. * That is, <code>z /: xs</code> is the same as <code>xs foldLeft z</code> */ - override def /:[B](z: B)(f: (B, A) => B): B = x./:(z)(f); + override def /:[B](z: B)(f: (B, A) => B): B = self./:(z)(f); /** An alias for <code>foldRight</code>. * That is, <code>xs :\ z</code> is the same as <code>xs foldRight z</code> */ - override def :\[B](z: B)(f: (A, B) => B): B = x.:\(z)(f); + override def :\[B](z: B)(f: (A, B) => B): B = self.:\(z)(f); /** Checks if the other iterable object contains the same elements. * * @param that the other iterable object * @return true, iff both iterable objects contain the same elements. */ - override def sameElements[B >: A](that: Iterable[B]): Boolean = x.sameElements(that); + override def sameElements[B >: A](that: Iterable[B]): Boolean = self.sameElements(that); } diff --git a/sources/scala/List.scala b/sources/scala/List.scala index 2523862865..5d4e37f93c 100644 --- a/sources/scala/List.scala +++ b/sources/scala/List.scala @@ -202,6 +202,19 @@ object List { if (xs.isEmpty || ys.isEmpty) Nil else f(xs.head, ys.head) :: map2(xs.tail, ys.tail)(f); + /** Like xs map f, but returns xs unchanged if function `f' maps all elements to themselves + */ + def mapConserve[a <: AnyRef](xs: List[a])(f: a => a): List[a] = { + if (xs.isEmpty) xs + else { + val head = xs.head; + val head1 = f(head); + val tail = xs.tail; + val tail1 = mapConserve(tail)(f); + if ((head1 eq head) && (tail1 eq tail)) xs else head1 :: tail1 + } + } + /** Returns the list resulting from applying the given function <code>f</code> to * corresponding elements of the argument lists. * @@ -274,7 +287,7 @@ object List { * @author Martin Odersky and others * @version 1.0, 16/07/2003 */ -sealed trait List[+a] extends Seq[a] { +/*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. @@ -518,16 +531,6 @@ sealed trait List[+a] extends Seq[a] { case head :: tail => f(head) :: (tail map f) } - /** Like xs map f, but returns xs unchanged if function `f' maps all elements to themselves - */ - def mapConserve[b >: a](f: a => b): List[b] = this match { - case Nil => Nil - case head :: tail => - val head1 = f(head); - val tail1 = tail mapConserve f; - if (head1 == head && (tail1 eq tail)) this else head1 :: tail1 - } - /** Apply a function to all the elements of the list, and return the * reversed list of results. This is equivalent to a call to <code>map</code> * followed by a call to <code>reverse</code>, but more efficient. @@ -548,9 +551,12 @@ sealed trait List[+a] extends Seq[a] { * * @param f the treatment to apply to each element. */ - override def foreach(f: a => Unit): Unit = this match { - case Nil => () - case head :: tail => f(head); tail foreach f + override def foreach(f: a => Unit): Unit = { + def loop(xs: List[a]): Unit = xs match { + case Nil => () + case head :: tail => f(head); loop(tail) + } + loop(this) } /** Returns all the elements of this list that satisfy the @@ -866,7 +872,7 @@ sealed trait List[+a] extends Seq[a] { else head :: tail.removeDuplicates } } - +/* /** The empty list. * * @author Martin Odersky @@ -890,3 +896,4 @@ 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 index 32f489a88c..94d1ec218a 100644 --- a/sources/scala/Nil.scala +++ b/sources/scala/Nil.scala @@ -10,7 +10,7 @@ package scala; import java.io.Serializable; - +import Predef._; /** The empty list. * diff --git a/sources/scala/Predef.scala b/sources/scala/Predef.scala index 704bfacd56..97c3453fe4 100644 --- a/sources/scala/Predef.scala +++ b/sources/scala/Predef.scala @@ -142,7 +142,8 @@ object Predef { // views ------------------------------------------------------------- - implicit def view(x: int): Ordered[int] = new Proxy(x) with Ordered[int] { + implicit def view(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 => if (x < y1) -1 @@ -152,7 +153,8 @@ object Predef { } } - implicit def view(x: char): Ordered[char] = new Proxy(x) with Ordered[char] { + implicit def view(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 => if (x < y1) -1 @@ -162,7 +164,8 @@ object Predef { } } - implicit def view(x: long): Ordered[long] = new Proxy(x) with Ordered[long] { + implicit def view(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 => if (x < y1) -1 @@ -172,7 +175,8 @@ object Predef { } } - implicit def view(x: float): Ordered[float] = new Proxy(x) with Ordered[float] { + implicit def view(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 => if (x < y1) -1 @@ -182,7 +186,8 @@ object Predef { } } - implicit def view(x: double): Ordered[double] = new Proxy(x) with Ordered[double] { + implicit def view(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 => if (x < y1) -1 @@ -192,7 +197,8 @@ object Predef { } } - implicit def view(x: boolean): Ordered[boolean] = new Proxy(x) with Ordered[boolean] { + implicit def view(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 => if (x == y1) 0 @@ -202,7 +208,8 @@ object Predef { } } - implicit def view[A <% Ordered[A]](xs: Array[A]): Ordered[Array[A]] = new Proxy(xs) with Ordered[Array[A]] { + implicit def view[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] => var i, res = 0; @@ -273,7 +280,8 @@ object Predef { } */ - implicit def view(x: String): Ordered[String] = new Proxy(x) with Ordered[String] { + implicit def view(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) diff --git a/sources/scala/Proxy.scala b/sources/scala/Proxy.scala index 28b28fccd4..5129f0eb00 100644 --- a/sources/scala/Proxy.scala +++ b/sources/scala/Proxy.scala @@ -11,15 +11,16 @@ package scala; /** This class implements a simple proxy that forwards all calls to - * methods of class <code>Any</code> to another object <code>x</code>. + * methods of class <code>Any</code> to another object <code>self</code>. * Please note that only those methods can be forwarded that are * overridable and public. * * @author Matthias Zenger * @version 1.0, 26/04/2004 */ -class Proxy(x: Any) { - override def hashCode(): Int = x.hashCode(); - override def equals(y: Any): Boolean = x.equals(y); - override def toString(): String = x.toString(); +trait Proxy { + def self: Any; + override def hashCode(): Int = self.hashCode(); + override def equals(y: Any): Boolean = self.equals(y); + override def toString(): String = self.toString(); } diff --git a/sources/scala/Seq.scala b/sources/scala/Seq.scala index 6c13d58948..db24f1e789 100644 --- a/sources/scala/Seq.scala +++ b/sources/scala/Seq.scala @@ -9,9 +9,11 @@ package scala; +import Predef._; object Seq { - def view[A <% Ordered[A]](xs: Seq[A]): Ordered[Seq[A]] = new Proxy(xs) with Ordered[Seq[A]] { + def view[A <% Ordered[A]](xs: Seq[A]): Ordered[Seq[A]] = new Ordered[Seq[A]] with Proxy { + def self: Any = xs; def compareTo[B >: Seq[A] <% Ordered[B]](that: B): Int = that match { case ys: Seq[A] => var res = 0; diff --git a/sources/scala/SeqProxy.scala b/sources/scala/SeqProxy.scala index cfb0d4ad6d..03f6031312 100644 --- a/sources/scala/SeqProxy.scala +++ b/sources/scala/SeqProxy.scala @@ -17,25 +17,27 @@ package scala; * @author Matthias Zenger * @version 1.0, 16/07/2003 */ -class SeqProxy[+A](x: Seq[A]) extends Seq[A] with IterableProxy(x) { +trait SeqProxy[+A] extends Seq[A] with IterableProxy[A] { + + def self: Seq[A]; /** Returns the length of the sequence. * * @return the sequence length. */ - def length: Int = x.length; + def length: Int = self.length; /** Access element number <code>n</code>. * * @return the element at index <code>n</code>. */ - def apply(n: Int): A = x.apply(n); + def apply(n: Int): A = self.apply(n); /** Is this partial function defined for the index <code>x</code>? * * @return true, iff <code>x</code> is a legal sequence index. */ - override def isDefinedAt(y: Int): Boolean = x.isDefinedAt(y); + override def isDefinedAt(y: Int): Boolean = self.isDefinedAt(y); /** Returns the index of the first occurence of the specified * object in this sequence. @@ -44,7 +46,7 @@ class SeqProxy[+A](x: Seq[A]) extends Seq[A] with IterableProxy(x) { * @return the index in this sequence of the first occurence of the specified * element, or -1 if the sequence does not contain this element. */ - override def indexOf[B >: A](elem: B): Int = x.indexOf(elem); + override def indexOf[B >: A](elem: B): Int = self.indexOf(elem); /** Returns the index of the last occurence of the specified * element in this sequence, or -1 if the sequence does not @@ -55,21 +57,21 @@ class SeqProxy[+A](x: Seq[A]) extends Seq[A] with IterableProxy(x) { * specified element, or -1 if the sequence does not contain * this element. */ - override def lastIndexOf[B >: A](elem: B): Int = x.lastIndexOf(elem); + override def lastIndexOf[B >: A](elem: B): Int = self.lastIndexOf(elem); /** Returns the sub-sequence starting from index <code>n</code>. */ - override def take(n: Int): Seq[A] = x.take(n); + override def take(n: Int): Seq[A] = self.take(n); /** Returns a new sub-sequence that drops the first <code>n</code> * elements of this sequence. */ - override def drop(n: Int): Seq[A] = x.drop(n); + override def drop(n: Int): Seq[A] = self.drop(n); /** Returns a subsequence starting from index <code>from</code> * consisting of <code>len</code> elements. */ - override def subseq(from: Int, len: Int): Seq[A] = x.subseq(from, len); + override def subseq(from: Int, len: Int): Seq[A] = self.subseq(from, len); /** Fills the given array <code>xs</code> with the elements of * this sequence starting at position <code>start</code>. @@ -79,11 +81,11 @@ class SeqProxy[+A](x: Seq[A]) extends Seq[A] with IterableProxy(x) { * @return the given array <code>xs</code> filled with the elements * of this sequence. */ - override def copyToArray[B >: A](xs: Array[B], start: Int): Array[B] = x.copyToArray(xs, start); + override def copyToArray[B >: A](xs: Array[B], start: Int): Array[B] = self.copyToArray(xs, start); /** Transform this sequence into a list of all elements. * * @return a list which enumerates all elements of this sequence. */ - override def toList: List[A] = x.toList; + override def toList: List[A] = self.toList; } diff --git a/sources/scala/Serializable.scala b/sources/scala/Serializable.scala deleted file mode 100644 index af011f7d39..0000000000 --- a/sources/scala/Serializable.scala +++ /dev/null @@ -1,12 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2002, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -** $Id$ -*/ - -package scala; - -class Serializable extends Attribute {} diff --git a/sources/scala/Stream.scala b/sources/scala/Stream.scala index 3256b647a3..bd0501b4fb 100644 --- a/sources/scala/Stream.scala +++ b/sources/scala/Stream.scala @@ -25,7 +25,7 @@ object Stream { def printElems(buf: StringBuffer, prefix: String): StringBuffer = buf; } - def cons[a](hd: a, def/*!!!*/ tl: Stream[a]) = new Stream[a] { + def cons[a](hd: a, tl: => Stream[a]) = new Stream[a] { def isEmpty = false; def head = hd; private var tlVal: Stream[a] = _; @@ -129,7 +129,7 @@ trait Stream[+a] extends Seq[a] { def length: int = if (isEmpty) 0 else tail.length + 1; - def append[b >: a](def/*!!!*/ rest: Stream[b]): Stream[b] = + def append[b >: a](rest: => Stream[b]): Stream[b] = if (isEmpty) rest else Stream.cons(head, tail.append(rest)); diff --git a/sources/scala/collection/BitSet.scala b/sources/scala/collection/BitSet.scala index aa77d59e60..5b6fa9568a 100644 --- a/sources/scala/collection/BitSet.scala +++ b/sources/scala/collection/BitSet.scala @@ -14,7 +14,7 @@ package scala.collection; * @author Burak Emir, Stephane Micheloud * @version 1.0 */ -abstract class BitSet with Function1[Int,Boolean] { +abstract class BitSet extends AnyRef with Function1[Int,Boolean] { /** number of bits in this bitset */ def size: Int; diff --git a/sources/scala/collection/Map.scala b/sources/scala/collection/Map.scala index e623380eb1..65ee3a6c3b 100644 --- a/sources/scala/collection/Map.scala +++ b/sources/scala/collection/Map.scala @@ -9,7 +9,6 @@ package scala.collection; - /** This trait defines the interface of collections that unambiguously map * keys to values (i.e. a key is mapped to at least one value). * Trait <code>Map</code> may only be used for @@ -24,7 +23,7 @@ package scala.collection; * @author Matthias Zenger * @version 1.1, 02/05/2004 */ -trait Map[A, +B] with PartialFunction[A, B] with Iterable[Pair[A, B]] { +trait Map[A, +B] extends AnyRef with PartialFunction[A, B] with Iterable[Pair[A, B]] { /** Compute the number of key-to-value mappings. * diff --git a/sources/scala/collection/MapProxy.scala b/sources/scala/collection/MapProxy.scala index 2886c1f1f9..8284a628d2 100644 --- a/sources/scala/collection/MapProxy.scala +++ b/sources/scala/collection/MapProxy.scala @@ -17,25 +17,27 @@ package scala.collection; * @author Matthias Zenger * @version 1.0, 21/07/2003 */ -class MapProxy[A, +B](map: Map[A, B]) extends Map[A, B] with IterableProxy(map) { +trait MapProxy[A, +B] extends Map[A, B] with IterableProxy[Pair[A, B]] { - def size: Int = map.size; + def self: Map[A, B]; - def get(key: A): Option[B] = map.get(key); + def size: Int = self.size; - override def isEmpty: Boolean = map.isEmpty; + def get(key: A): Option[B] = self.get(key); - override def apply(key: A): B = map.apply(key); + override def isEmpty: Boolean = self.isEmpty; - override def contains(key: A): Boolean = map.contains(key); + override def apply(key: A): B = self.apply(key); - override def isDefinedAt(key: A) = map.isDefinedAt(key); + override def contains(key: A): Boolean = self.contains(key); - override def keys: Iterator[A] = map.keys; + override def isDefinedAt(key: A) = self.isDefinedAt(key); - override def values: Iterator[B] = map.values; + override def keys: Iterator[A] = self.keys; - override def foreach(f: (A, B) => Unit) = map.foreach(f); + override def values: Iterator[B] = self.values; - override def toList: List[Pair[A, B]] = map.toList; + override def foreach(f: (A, B) => Unit) = self.foreach(f); + + override def toList: List[Pair[A, B]] = self.toList; } diff --git a/sources/scala/collection/Set.scala b/sources/scala/collection/Set.scala index f57f6a3961..a4cf078543 100644 --- a/sources/scala/collection/Set.scala +++ b/sources/scala/collection/Set.scala @@ -23,7 +23,7 @@ package scala.collection; * @author Matthias Zenger * @version 1.0, 08/07/2003 */ -trait Set[A] with Function1[A, Boolean] with Iterable[A] { +trait Set[A] extends AnyRef with Function1[A, Boolean] with Iterable[A] { /** Returns the number of elements in this set. * diff --git a/sources/scala/collection/SetProxy.scala b/sources/scala/collection/SetProxy.scala index 9d030f58b2..0fc1931385 100644 --- a/sources/scala/collection/SetProxy.scala +++ b/sources/scala/collection/SetProxy.scala @@ -17,19 +17,21 @@ package scala.collection; * @author Matthias Zenger * @version 1.0, 21/07/2003 */ -class SetProxy[A](set: Set[A]) extends Set[A] with IterableProxy(set) { +trait SetProxy[A] extends Set[A] with IterableProxy[A] { - def size: Int = set.size; + def self: Set[A]; - override def isEmpty: Boolean = set.isEmpty; + def size: Int = self.size; - def contains(elem: A): Boolean = set.contains(elem); + override def isEmpty: Boolean = self.isEmpty; - override def subsetOf(that: Set[A]): Boolean = set.subsetOf(that); + def contains(elem: A): Boolean = self.contains(elem); - override def foreach(f: A => Unit): Unit = set.foreach(f); + override def subsetOf(that: Set[A]): Boolean = self.subsetOf(that); - override def exists(p: A => Boolean): Boolean = set.exists(p); + override def foreach(f: A => Unit): Unit = self.foreach(f); - override def toList: List[A] = set.toList; + override def exists(p: A => Boolean): Boolean = self.exists(p); + + override def toList: List[A] = self.toList; } diff --git a/sources/scala/collection/immutable/ListMap.scala b/sources/scala/collection/immutable/ListMap.scala index dd6e981c9b..b21e5320db 100644 --- a/sources/scala/collection/immutable/ListMap.scala +++ b/sources/scala/collection/immutable/ListMap.scala @@ -22,7 +22,7 @@ object ListMap { * @author Matthias Zenger * @version 1.0, 09/07/2003 */ -class ListMap[A, B] with Map[A, B] { +class ListMap[A, B] extends AnyRef with Map[A, B] { /** This method returns a new ListMap instance mapping keys of the * same type to values of type <code>C</code>. diff --git a/sources/scala/collection/immutable/ListSet.scala b/sources/scala/collection/immutable/ListSet.scala index fa87d40cd9..12f7c4bf78 100644 --- a/sources/scala/collection/immutable/ListSet.scala +++ b/sources/scala/collection/immutable/ListSet.scala @@ -25,7 +25,7 @@ object ListSet { * @author Matthias Zenger * @version 1.0, 09/07/2003 */ -class ListSet[A] with Set[A] { +class ListSet[A] extends AnyRef with Set[A] { /** Returns the number of elements in this set. * diff --git a/sources/scala/collection/immutable/Map.scala b/sources/scala/collection/immutable/Map.scala index 37abe9f7ef..494ea843fa 100644 --- a/sources/scala/collection/immutable/Map.scala +++ b/sources/scala/collection/immutable/Map.scala @@ -22,7 +22,7 @@ package scala.collection.immutable; * @author Erik Stenman * @version 1.1, 22/03/2004 */ -trait Map[A, B] with scala.collection.Map[A, B] { +trait Map[A, B] extends AnyRef with scala.collection.Map[A, B] { /** This method returns a new map instance of the same class * mapping keys of the same type to values of type <code>C</code>. diff --git a/sources/scala/collection/immutable/Set.scala b/sources/scala/collection/immutable/Set.scala index 7308b595dc..16735fcab9 100644 --- a/sources/scala/collection/immutable/Set.scala +++ b/sources/scala/collection/immutable/Set.scala @@ -18,7 +18,7 @@ package scala.collection.immutable; * @author Matthias Zenger * @version 1.1, 03/05/2004 */ -trait Set[A] with scala.collection.Set[A] { +trait Set[A] extends AnyRef with scala.collection.Set[A] { /** This method creates a new set with an additional element. */ diff --git a/sources/scala/collection/immutable/Stack.scala b/sources/scala/collection/immutable/Stack.scala index 7fe660e2c0..887c6b31b4 100644 --- a/sources/scala/collection/immutable/Stack.scala +++ b/sources/scala/collection/immutable/Stack.scala @@ -22,7 +22,7 @@ object Stack { * @author Matthias Zenger * @version 1.0, 10/07/2003 */ -class Stack[+A] with Seq[A] { +class Stack[+A] extends Seq[A] { /** Checks if this stack is empty. * diff --git a/sources/scala/collection/immutable/Tree.scala b/sources/scala/collection/immutable/Tree.scala index ecc4e0311f..061ed34dd7 100644 --- a/sources/scala/collection/immutable/Tree.scala +++ b/sources/scala/collection/immutable/Tree.scala @@ -61,7 +61,7 @@ import java.lang.Math; * @author Michel Schinz * @version 1.1, 2005-01-20 */ -abstract class Tree[A <% Ordered[A], B] with java.io.Serializable { +abstract class Tree[A <% Ordered[A], B]() extends AnyRef with java.io.Serializable { /* Data structure: ** - size:Int - the number of elements in the tree. ** - tree:T, which is composed of nodes of the form: @@ -168,7 +168,7 @@ abstract class Tree[A <% Ordered[A], B] with java.io.Serializable { var iter = tree.mk_iter(scala.Nil); def hasNext = !iter.isEmpty; def next = - iter.match { + iter match { case (GBNode(_,v,_,t)::iter_tail) => { iter= t.mk_iter(iter_tail); v; @@ -186,8 +186,8 @@ abstract class Tree[A <% Ordered[A], B] with java.io.Serializable { New(size, tree.balance(size)); } -private abstract class InsertTree[A <% Ordered[A],B]() - with java.io.Serializable { +protected abstract class InsertTree[A <% Ordered[A],B]() + extends AnyRef with java.io.Serializable { def insertLeft(k: A, v: B, t: GBTree[A,B]): InsertTree[A,B]; def insertRight(k: A, v: B, t: GBTree[A,B]): InsertTree[A,B]; def node: GBTree[A,B]; @@ -225,7 +225,7 @@ private case class INode[A <% Ordered[A],B](t1: GBTree[A,B], * GBTree is an internal class used by Tree. */ -private abstract class GBTree[A <% Ordered[A],B] with java.io.Serializable { +protected abstract class GBTree[A <% Ordered[A],B] extends AnyRef with java.io.Serializable { type aNode = GBTree[A,B]; type anInsertTree = InsertTree[A,B]; @@ -246,7 +246,7 @@ private abstract class GBTree[A <% Ordered[A],B] with java.io.Serializable { def balance(s:int):GBTree[A,B]; } -private case class GBLeaf[A <% Ordered[A],B] extends GBTree[A,B] { +private case class GBLeaf[A <% Ordered[A],B]() extends GBTree[A,B] { def count = Pair(1, 0); def isDefinedAt(key:A) = false; def get(_key:A) = None; diff --git a/sources/scala/collection/immutable/TreeSet.scala b/sources/scala/collection/immutable/TreeSet.scala index e8e9cf3b99..20847a17a0 100644 --- a/sources/scala/collection/immutable/TreeSet.scala +++ b/sources/scala/collection/immutable/TreeSet.scala @@ -16,7 +16,7 @@ package scala.collection.immutable; * @author Burak Emir * @version 1.1, 03/05/2004 */ -class TreeSet[A <% Ordered[A]] extends Tree[A, A] with Set[A] { +class TreeSet[A <% Ordered[A]]() extends Tree[A, A] with Set[A] { override protected type This = TreeSet[A]; override protected def getThis: This = this; diff --git a/sources/scala/collection/mutable/BitSet.scala b/sources/scala/collection/mutable/BitSet.scala index 6961ed2520..30da819e67 100644 --- a/sources/scala/collection/mutable/BitSet.scala +++ b/sources/scala/collection/mutable/BitSet.scala @@ -19,7 +19,7 @@ class BitSet(initSize: Int) extends scala.collection.BitSet { /** default constructor, initial size of 512 bits */ def this() = this( 512 ); // ResizableArray.initialSize << 5 - class ByteArray with ResizableArray[Int] { + class ByteArray extends AnyRef with ResizableArray[Int] { final def ensureBits(nbits: Int): Unit = { super[ResizableArray].ensureSize(memsize( nbits )); diff --git a/sources/scala/collection/mutable/Buffer.scala b/sources/scala/collection/mutable/Buffer.scala index 9dec464ff6..5d6adcc9c9 100644 --- a/sources/scala/collection/mutable/Buffer.scala +++ b/sources/scala/collection/mutable/Buffer.scala @@ -9,7 +9,6 @@ package scala.collection.mutable; - /** Buffers are used to create sequences of elements incrementally by * appending, prepending, or inserting new elements. It is also * possible to access and modify elements in a random access fashion @@ -18,7 +17,7 @@ package scala.collection.mutable; * @author Matthias Zenger * @version 1.1, 02/03/2004 */ -trait Buffer[A] with Seq[A] with Scriptable[Message[Pair[Location, A]]] with Cloneable { +trait Buffer[A] extends AnyRef with Seq[A] with Scriptable[Message[Pair[Location, A]]] with Cloneable { /** Append a single element to this buffer and return * the identity of the buffer. diff --git a/sources/scala/collection/mutable/BufferProxy.scala b/sources/scala/collection/mutable/BufferProxy.scala index 1c4be09a3c..c06202024a 100644 --- a/sources/scala/collection/mutable/BufferProxy.scala +++ b/sources/scala/collection/mutable/BufferProxy.scala @@ -17,26 +17,28 @@ package scala.collection.mutable; * @author Matthias Zenger * @version 1.0, 16/04/2004 */ -class BufferProxy[A](buf: Buffer[A]) extends Buffer[A] with Proxy(buf) { +trait BufferProxy[A] extends Buffer[A] with Proxy { - def length: Int = buf.length; + def self: Buffer[A]; - def elements: Iterator[A] = buf.elements; + def length: Int = self.length; - def apply(n: Int): A = buf.apply(n); + def elements: Iterator[A] = self.elements; + + def apply(n: Int): A = self.apply(n); /** Append a single element to this buffer and return * the identity of the buffer. * * @param elem the element to append. */ - def +(elem: A): Buffer[A] = buf.+(elem); + def +(elem: A): Buffer[A] = self.+(elem); /** Append a single element to this buffer. * * @param elem the element to append. */ - override def +=(elem: A): Unit = buf.+=(elem); + override def +=(elem: A): Unit = self.+=(elem); /** Appends a number of elements provided by an iterable object * via its <code>elements</code> method. The identity of the @@ -44,34 +46,34 @@ class BufferProxy[A](buf: Buffer[A]) extends Buffer[A] with Proxy(buf) { * * @param iter the iterable object. */ - override def ++(iter: Iterable[A]): Buffer[A] = buf.++(iter); + override def ++(iter: Iterable[A]): Buffer[A] = self.++(iter); /** Appends a number of elements provided by an iterable object * via its <code>elements</code> method. * * @param iter the iterable object. */ - override def ++=(iter: Iterable[A]): Unit = buf.++=(iter); + override def ++=(iter: Iterable[A]): Unit = self.++=(iter); /** Appends a sequence of elements to this buffer. * * @param elems the elements to append. */ - override def append(elems: A*): Unit = buf.++=(elems); + override def append(elems: A*): Unit = self.++=(elems); /** Appends a number of elements provided by an iterable object * via its <code>elements</code> method. * * @param iter the iterable object. */ - override def appendAll(iter: Iterable[A]): Unit = buf.appendAll(iter); + override def appendAll(iter: Iterable[A]): Unit = self.appendAll(iter); /** Prepend a single element to this buffer and return * the identity of the buffer. * * @param elem the element to append. */ - def +:(elem: A): Buffer[A] = buf.+:(elem); + def +:(elem: A): Buffer[A] = self.+:(elem); /** Prepends a number of elements provided by an iterable object * via its <code>elements</code> method. The identity of the @@ -79,13 +81,13 @@ class BufferProxy[A](buf: Buffer[A]) extends Buffer[A] with Proxy(buf) { * * @param iter the iterable object. */ - override def ++:(iter: Iterable[A]): Buffer[A] = buf.++:(iter); + override def ++:(iter: Iterable[A]): Buffer[A] = self.++:(iter); /** Prepend an element to this list. * * @param elem the element to prepend. */ - override def prepend(elems: A*): Unit = buf.prependAll(elems); + override def prepend(elems: A*): Unit = self.prependAll(elems); /** Prepends a number of elements provided by an iterable object * via its <code>elements</code> method. The identity of the @@ -93,7 +95,7 @@ class BufferProxy[A](buf: Buffer[A]) extends Buffer[A] with Proxy(buf) { * * @param iter the iterable object. */ - override def prependAll(elems: Iterable[A]): Unit = buf.prependAll(elems); + override def prependAll(elems: Iterable[A]): Unit = self.prependAll(elems); /** Inserts new elements at the index <code>n</code>. Opposed to method * <code>update</code>, this method will not replace an element with a @@ -102,7 +104,7 @@ class BufferProxy[A](buf: Buffer[A]) extends Buffer[A] with Proxy(buf) { * @param n the index where a new element will be inserted. * @param elems the new elements to insert. */ - override def insert(n: Int, elems: A*): Unit = buf.insertAll(n, elems); + override def insert(n: Int, elems: A*): Unit = self.insertAll(n, elems); /** Inserts new elements at the index <code>n</code>. Opposed to method * <code>update</code>, this method will not replace an element with a @@ -111,7 +113,7 @@ class BufferProxy[A](buf: Buffer[A]) extends Buffer[A] with Proxy(buf) { * @param n the index where a new element will be inserted. * @param iter the iterable object providing all elements to insert. */ - def insertAll(n: Int, iter: Iterable[A]): Unit = buf.insertAll(n, iter); + def insertAll(n: Int, iter: Iterable[A]): Unit = self.insertAll(n, iter); /** Replace element at index <code>n</code> with the new element * <code>newelem</code>. @@ -119,27 +121,27 @@ class BufferProxy[A](buf: Buffer[A]) extends Buffer[A] with Proxy(buf) { * @param n the index of the element to replace. * @param newelem the new element. */ - def update(n: Int, newelem: A): Unit = buf.update(n, newelem); + def update(n: Int, newelem: A): Unit = self.update(n, newelem); /** Removes the element on a given index position. * * @param n the index which refers to the element to delete. */ - def remove(n: Int): A = buf.remove(n); + def remove(n: Int): A = self.remove(n); /** Clears the buffer contents. */ - def clear: Unit = buf.clear; + def clear: Unit = self.clear; /** Send a message to this scriptable object. * * @param cmd the message to send. */ - override def <<(cmd: Message[Pair[Location, A]]): Unit = buf << cmd; + override def <<(cmd: Message[Pair[Location, A]]): Unit = self << cmd; /** Return a clone of this buffer. * * @return a <code>Buffer</code> with the same elements. */ - override def clone(): Buffer[A] = new BufferProxy(buf.clone()); + override def clone(): Buffer[A] = new BufferProxy[A] { def self = BufferProxy.this.self.clone() } } diff --git a/sources/scala/collection/mutable/DefaultMapModel.scala b/sources/scala/collection/mutable/DefaultMapModel.scala index a9d9b32376..932ea22a2b 100644 --- a/sources/scala/collection/mutable/DefaultMapModel.scala +++ b/sources/scala/collection/mutable/DefaultMapModel.scala @@ -17,7 +17,7 @@ package scala.collection.mutable; * @author Matthias Zenger * @version 1.0, 08/07/2003 */ -trait DefaultMapModel[A, B] extends scala.collection.mutable.Map[A, B] { +trait DefaultMapModel[A, B] extends AnyRef with scala.collection.mutable.Map[A, B] { protected type Entry = DefaultEntry[A,B]; protected def findEntry(key: A): Option[Entry]; @@ -43,7 +43,7 @@ trait DefaultMapModel[A, B] extends scala.collection.mutable.Map[A, B] { } } -protected class DefaultEntry[A,B](k: A, v: B) with java.io.Serializable { +protected class DefaultEntry[A,B](k: A, v: B) extends AnyRef with java.io.Serializable { def key = k; var value = v; def toPair = Pair(k, value); diff --git a/sources/scala/collection/mutable/HashTable.scala b/sources/scala/collection/mutable/HashTable.scala index 68c19804a0..382cd43f69 100644 --- a/sources/scala/collection/mutable/HashTable.scala +++ b/sources/scala/collection/mutable/HashTable.scala @@ -9,6 +9,7 @@ package scala.collection.mutable; +import Predef._; /** This class can be used to construct data structures that are based * on hashtables. Class <code>HashTable[A]</code> implements a hashtable @@ -27,7 +28,7 @@ package scala.collection.mutable; * @author Matthias Zenger * @version 1.0, 08/07/2003 */ -abstract class HashTable[A] with java.io.Serializable { +abstract class HashTable[A] extends AnyRef with java.io.Serializable { /** The load factor for the hash table. */ diff --git a/sources/scala/collection/mutable/History.scala b/sources/scala/collection/mutable/History.scala index 0587349806..f00c8a26f4 100644 --- a/sources/scala/collection/mutable/History.scala +++ b/sources/scala/collection/mutable/History.scala @@ -18,7 +18,7 @@ package scala.collection.mutable; * @author Matthias Zenger * @version 1.0, 08/07/2003 */ -class History[A, B] with Subscriber[A, B] with Iterable[Pair[B, A]] { +class History[A, B] extends AnyRef with Subscriber[A, B] with Iterable[Pair[B, A]] { protected val log: Queue[Pair[B, A]] = new Queue[Pair[B, A]]; diff --git a/sources/scala/collection/mutable/Map.scala b/sources/scala/collection/mutable/Map.scala index b8c5ceb804..88fe6c55b2 100644 --- a/sources/scala/collection/mutable/Map.scala +++ b/sources/scala/collection/mutable/Map.scala @@ -9,7 +9,6 @@ package scala.collection.mutable; - /** This trait represents mutable maps. Concrete map implementations * just have to provide functionality for the abstract methods in * <code>scala.collection.Map</code> as well as for <code>update</code>, @@ -18,7 +17,7 @@ package scala.collection.mutable; * @author Matthias Zenger * @version 1.1, 09/05/2004 */ -trait Map[A, B] with scala.collection.Map[A, B] with Scriptable[Message[Pair[A, B]]] with Cloneable { +trait Map[A, B] extends AnyRef with scala.collection.Map[A, B] with Scriptable[Message[Pair[A, B]]] with Cloneable { /** This method allows one to add a new mapping from <code>key</code> * to <code>value</code> to the map. If the map already contains a diff --git a/sources/scala/collection/mutable/MapProxy.scala b/sources/scala/collection/mutable/MapProxy.scala index 75493aad86..8081e3a66a 100644 --- a/sources/scala/collection/mutable/MapProxy.scala +++ b/sources/scala/collection/mutable/MapProxy.scala @@ -17,36 +17,37 @@ package scala.collection.mutable; * @author Matthias Zenger * @version 1.0, 21/07/2003 */ -class MapProxy[A, B](m: Map[A, B]) extends Map[A, B] - with scala.collection.MapProxy[A, B](m) { +trait MapProxy[A, B] extends Map[A, B] with scala.collection.MapProxy[A, B] { - def update(key: A, value: B): Unit = m.update(key, value); + def self: Map[A, B]; - override def ++=(map: Iterable[Pair[A, B]]): Unit = m ++= map; + def update(key: A, value: B): Unit = self.update(key, value); - override def ++=(it: Iterator[Pair[A, B]]): Unit = m ++= it; + override def ++=(map: Iterable[Pair[A, B]]): Unit = self ++= map; - override def incl(mappings: Pair[A, B]*): Unit = m ++= mappings; + override def ++=(it: Iterator[Pair[A, B]]): Unit = self ++= it; - def -=(key: A): Unit = m -= key; + override def incl(mappings: Pair[A, B]*): Unit = self ++= mappings; - override def --=(keys: Iterable[A]): Unit = m --= keys; + def -=(key: A): Unit = self -= key; - override def --=(it: Iterator[A]): Unit = m --= it; + override def --=(keys: Iterable[A]): Unit = self --= keys; - override def excl(keys: A*): Unit = m --= keys; + override def --=(it: Iterator[A]): Unit = self --= it; - override def clear: Unit = m.clear; + override def excl(keys: A*): Unit = self --= keys; - override def map(f: (A, B) => B): Unit = m.map(f); + override def clear: Unit = self.clear; - override def filter(p: (A, B) => Boolean): Unit = m.filter(p); + override def map(f: (A, B) => B): Unit = self.map(f); - override def toString() = m.toString(); + override def filter(p: (A, B) => Boolean): Unit = self.filter(p); - override def mappingToString(p: Pair[A, B]) = m.mappingToString(p); + override def toString() = self.toString(); - override def <<(cmd: Message[Pair[A, B]]): Unit = m << cmd; + override def mappingToString(p: Pair[A, B]) = self.mappingToString(p); - override def clone(): Map[A, B] = new MapProxy(m.clone()); + override def <<(cmd: Message[Pair[A, B]]): Unit = self << cmd; + + override def clone(): Map[A, B] = new MapProxy[A, B] { def self = MapProxy.this.self.clone() } } diff --git a/sources/scala/collection/mutable/Message.scala b/sources/scala/collection/mutable/Message.scala index da5610b29a..bd805c5d6e 100644 --- a/sources/scala/collection/mutable/Message.scala +++ b/sources/scala/collection/mutable/Message.scala @@ -27,7 +27,7 @@ trait Message[+A]; * @author Matthias Zenger * @version 1.0, 08/07/2003 */ -case class Include[+A](elem: A) extends Message[A]; +case class Include[+I](elem: I) extends Message[I]; /** This observable update refers to destructive modification operations * of elements from collection classes. @@ -50,7 +50,7 @@ case class Remove[+A](elem: A) extends Message[A]; * @author Matthias Zenger * @version 1.0, 08/07/2003 */ -case class Reset[+A] extends Message[A]; +case class Reset[+A]() extends Message[A]; /** Objects of this class represent compound messages consisting * of a sequence of other messages. diff --git a/sources/scala/collection/mutable/ObservableBuffer.scala b/sources/scala/collection/mutable/ObservableBuffer.scala index 9c2a1febe5..c51384f0dc 100644 --- a/sources/scala/collection/mutable/ObservableBuffer.scala +++ b/sources/scala/collection/mutable/ObservableBuffer.scala @@ -22,17 +22,17 @@ abstract class ObservableBuffer[A, This <: ObservableBuffer[A, This]]: This extends Buffer[A] with Publisher[Message[Pair[Location, A]] with Undoable, This] { - abstract override def +(elem: A): Buffer[A] = { - super.+(elem); - publish(new Include(Pair(End, elem)) with Undoable { + abstract override def +(element: A): Buffer[A] = { + super.+(element); + publish(new Include(Pair(End, element)) with Undoable { def undo: Unit = trimEnd(1); }); this } - abstract override def +:(elem: A): Buffer[A] = { - super.+:(elem); - publish(new Include(Pair(Start, elem)) with Undoable { + abstract override def +:(element: A): Buffer[A] = { + super.+:(element); + publish(new Include(Pair(Start, element)) with Undoable { def undo: Unit = trimStart(1); }); this @@ -50,21 +50,21 @@ abstract class ObservableBuffer[A, This <: ObservableBuffer[A, This]]: This } } - abstract override def update(n: Int, newelem: A): Unit = { - val oldelem = apply(n); - super.update(n, newelem); - publish(new Update(Pair(Index(n), newelem)) with Undoable { - def undo: Unit = update(n, oldelem); + abstract override def update(n: Int, newelement: A): Unit = { + val oldelement = apply(n); + super.update(n, newelement); + publish(new Update(Pair(Index(n), newelement)) with Undoable { + def undo: Unit = update(n, oldelement); }); } abstract override def remove(n: Int): A = { - val oldelem = apply(n); + val oldelement = apply(n); super.remove(n); - publish(new Remove(Pair(Index(n), oldelem)) with Undoable { - def undo: Unit = insert(n, oldelem); + publish(new Remove(Pair(Index(n), oldelement)) with Undoable { + def undo: Unit = insert(n, oldelement); }); - oldelem + oldelement } abstract override def clear: Unit = { diff --git a/sources/scala/collection/mutable/PriorityQueueProxy.scala b/sources/scala/collection/mutable/PriorityQueueProxy.scala index 0a93803e3a..e78b98065f 100644 --- a/sources/scala/collection/mutable/PriorityQueueProxy.scala +++ b/sources/scala/collection/mutable/PriorityQueueProxy.scala @@ -17,77 +17,78 @@ package scala.collection.mutable; * @author Matthias Zenger * @version 1.0, 03/05/2004 */ -class PriorityQueueProxy[A <% Ordered[A]](p: PriorityQueue[A]) extends - PriorityQueue[A] with IterableProxy[A](p) { - - /** Creates a new iterator over all elements contained in this - * object. - * - * @return the new iterator - */ - override def elements: Iterator[A] = p.elements; - - /** Returns the length of this priority queue. - */ - override def length: Int = p.length; - - /** Checks if the queue is empty. - * - * @return true, iff there is no element in the queue. - */ - override def isEmpty: Boolean = p.isEmpty; - - /** Inserts a single element into the priority queue. - * - * @param elem the element to insert - */ - override def +=(elem: A): Unit = p += elem; - - /** Adds all elements provided by an <code>Iterable</code> object - * into the priority queue. - * - * @param iter an iterable object - */ - override def ++=(iter: Iterable[A]): Unit = p ++= iter; - - /** Adds all elements provided by an iterator into the priority queue. - * - * @param it an iterator - */ - override def ++=(it: Iterator[A]): Unit = p ++= it; - - /** Adds all elements to the queue. - * - * @param elems the elements to add. - */ - override def enqueue(elems: A*): Unit = p ++= elems; - - /** Returns the element with the highest priority in the queue, - * and removes this element from the queue. - * - * @return the element with the highest priority. - */ - override def dequeue: A = p.dequeue; - - /** Returns the element with the highest priority in the queue, - * or throws an error if there is no element contained in the queue. - * - * @return the element with the highest priority. - */ - override def max: A = p.max; - - /** Removes all elements from the queue. After this operation is completed, - * the queue will be empty. - */ - override def clear: Unit = p.clear; - - /** Returns a regular queue containing the same elements. - */ - override def toQueue: Queue[A] = p.toQueue; - - /** This method clones the priority queue. - * - * @return a priority queue with the same elements. - */ - override def clone(): PriorityQueue[A] = new PriorityQueueProxy(p.clone()); +abstract class PriorityQueueProxy[A <% Ordered[A]] extends PriorityQueue[A] with IterableProxy[A] { + + def self: PriorityQueue[A]; + + /** Creates a new iterator over all elements contained in this + * object. + * + * @return the new iterator + */ + override def elements: Iterator[A] = self.elements; + + /** Returns the length of this priority queue. + */ + override def length: Int = self.length; + + /** Checks if the queue is empty. + * + * @return true, iff there is no element in the queue. + */ + override def isEmpty: Boolean = self.isEmpty; + + /** Inserts a single element into the priority queue. + * + * @param elem the element to insert + */ + override def +=(elem: A): Unit = self += elem; + + /** Adds all elements provided by an <code>Iterable</code> object + * into the priority queue. + * + * @param iter an iterable object + */ + override def ++=(iter: Iterable[A]): Unit = self ++= iter; + + /** Adds all elements provided by an iterator into the priority queue. + * + * @param it an iterator + */ + override def ++=(it: Iterator[A]): Unit = self ++= it; + + /** Adds all elements to the queue. + * + * @param elems the elements to add. + */ + override def enqueue(elems: A*): Unit = self ++= elems; + + /** Returns the element with the highest priority in the queue, + * and removes this element from the queue. + * + * @return the element with the highest priority. + */ + override def dequeue: A = self.dequeue; + + /** Returns the element with the highest priority in the queue, + * or throws an error if there is no element contained in the queue. + * + * @return the element with the highest priority. + */ + override def max: A = self.max; + + /** Removes all elements from the queue. After this operation is completed, + * the queue will be empty. + */ + override def clear: Unit = self.clear; + + /** Returns a regular queue containing the same elements. + */ + override def toQueue: Queue[A] = self.toQueue; + + /** This method clones the priority queue. + * + * @return a priority queue with the same elements. + */ + override def clone(): PriorityQueue[A] = new PriorityQueueProxy[A] { def self = PriorityQueueProxy.this.self.clone() } } diff --git a/sources/scala/collection/mutable/Publisher.scala b/sources/scala/collection/mutable/Publisher.scala index 1426bf7639..7042c63289 100644 --- a/sources/scala/collection/mutable/Publisher.scala +++ b/sources/scala/collection/mutable/Publisher.scala @@ -20,7 +20,7 @@ package scala.collection.mutable; * @author Matthias Zenger * @version 1.0, 08/07/2003 */ -class Publisher[A, This <: Publisher[A, This]]: This { +abstract class Publisher[A, This <: Publisher[A, This]]: This { private val filters = new HashMap[Subscriber[A, This], scala.collection.mutable.Set[A => Boolean]] with MultiMap[Subscriber[A, This], A => Boolean]; diff --git a/sources/scala/collection/mutable/QueueProxy.scala b/sources/scala/collection/mutable/QueueProxy.scala index b9c3b52c0c..65c426a9c2 100644 --- a/sources/scala/collection/mutable/QueueProxy.scala +++ b/sources/scala/collection/mutable/QueueProxy.scala @@ -16,29 +16,31 @@ package scala.collection.mutable; * @author Matthias Zenger * @version 1.1, 03/05/2004 */ -class QueueProxy[A](q: Queue[A]) extends Queue[A] with SeqProxy[A](q) { +trait QueueProxy[A] extends Queue[A] with SeqProxy[A] { + + def self: Queue[A]; /** Access element number <code>n</code>. * * @return the element at index <code>n</code>. */ - override def apply(n: Int): A = q.apply(n); + override def apply(n: Int): A = self.apply(n); /** Returns the length of this queue. */ - override def length: Int = q.length; + override def length: Int = self.length; /** Checks if the queue is empty. * * @return true, iff there is no element in the queue. */ - override def isEmpty: Boolean = q.isEmpty; + override def isEmpty: Boolean = self.isEmpty; /** Inserts a single element at the end of the queue. * * @param elem the element to insert */ - override def +=(elem: A): Unit = q += elem; + override def +=(elem: A): Unit = self += elem; /** Adds all elements provided by an <code>Iterable</code> object * at the end of the queue. The elements are prepended in the order they @@ -46,7 +48,7 @@ class QueueProxy[A](q: Queue[A]) extends Queue[A] with SeqProxy[A](q) { * * @param iter an iterable object */ - override def ++=(iter: Iterable[A]): Unit = q ++= iter; + override def ++=(iter: Iterable[A]): Unit = self ++= iter; /** Adds all elements provided by an iterator * at the end of the queue. The elements are prepended in the order they @@ -54,42 +56,42 @@ class QueueProxy[A](q: Queue[A]) extends Queue[A] with SeqProxy[A](q) { * * @param iter an iterator */ - override def ++=(it: Iterator[A]): Unit = q ++= it; + override def ++=(it: Iterator[A]): Unit = self ++= it; /** Adds all elements to the queue. * * @param elems the elements to add. */ - override def enqueue(elems: A*): Unit = q ++= elems; + override def enqueue(elems: A*): Unit = self ++= elems; /** Returns the first element in the queue, and removes this element * from the queue. * * @return the first element of the queue. */ - override def dequeue: A = q.dequeue; + override def dequeue: A = self.dequeue; /** Returns the first element in the queue, or throws an error if there * is no element contained in the queue. * * @return the first element. */ - override def front: A = q.front; + override def front: A = self.front; /** Removes all elements from the queue. After this operation is completed, * the queue will be empty. */ - override def clear: Unit = q.clear; + override def clear: Unit = self.clear; /** Returns an iterator over all elements on the queue. * * @return an iterator over all queue elements. */ - override def elements: Iterator[A] = q.elements; + override def elements: Iterator[A] = self.elements; /** This method clones the queue. * * @return a queue with the same elements. */ - override def clone(): Queue[A] = new QueueProxy(q.clone()); + override def clone(): Queue[A] = new QueueProxy[A] { def self = QueueProxy.this.self.clone() } } diff --git a/sources/scala/collection/mutable/ResizableArray.scala b/sources/scala/collection/mutable/ResizableArray.scala index b7d002f1e2..8f9052465d 100644 --- a/sources/scala/collection/mutable/ResizableArray.scala +++ b/sources/scala/collection/mutable/ResizableArray.scala @@ -16,7 +16,7 @@ package scala.collection.mutable; * @author Matthias Zenger, Burak Emir * @version 1.0, 03/05/2004 */ -abstract class ResizableArray[A] with Iterable[A] with java.io.Serializable { +abstract class ResizableArray[A] extends AnyRef with Iterable[A] with java.io.Serializable { import java.lang.System.arraycopy; protected val initialSize: Int = 16; diff --git a/sources/scala/collection/mutable/Set.scala b/sources/scala/collection/mutable/Set.scala index f974b7d1e5..7ef0fb0b16 100644 --- a/sources/scala/collection/mutable/Set.scala +++ b/sources/scala/collection/mutable/Set.scala @@ -18,7 +18,7 @@ package scala.collection.mutable; * @author Matthias Zenger * @version 1.1, 09/05/2004 */ -trait Set[A] with scala.collection.Set[A] with Scriptable[Message[A]] with Cloneable { +trait Set[A] extends AnyRef with scala.collection.Set[A] with Scriptable[Message[A]] with Cloneable { /** This method allows one to add or remove an element <code>elem</code> * from this set depending on the value of parameter <code>included</code>. diff --git a/sources/scala/collection/mutable/SetProxy.scala b/sources/scala/collection/mutable/SetProxy.scala index af7521d733..4cd759a60d 100644 --- a/sources/scala/collection/mutable/SetProxy.scala +++ b/sources/scala/collection/mutable/SetProxy.scala @@ -17,34 +17,35 @@ package scala.collection.mutable; * @author Matthias Zenger * @version 1.1, 09/05/2004 */ -class SetProxy[A](set: Set[A]) extends Set[A] - with scala.collection.SetProxy[A](set) { +trait SetProxy[A] extends Set[A] with scala.collection.SetProxy[A] { - override def update(elem: A, included: Boolean): Unit = set(elem) = included; + def self: Set[A]; - def +=(elem: A): Unit = set += elem; + override def update(elem: A, included: Boolean): Unit = self(elem) = included; - override def ++=(that: Iterable[A]): Unit = set ++= that; + def +=(elem: A): Unit = self += elem; - override def ++=(it: Iterator[A]): Unit = set ++= it; + override def ++=(that: Iterable[A]): Unit = self ++= that; - override def incl(elems: A*): Unit = set ++= elems; + override def ++=(it: Iterator[A]): Unit = self ++= it; - def -=(elem: A): Unit = set -= elem; + override def incl(elems: A*): Unit = self ++= elems; - override def --=(that: Iterable[A]): Unit = set --= that; + def -=(elem: A): Unit = self -= elem; - override def --=(it: Iterator[A]): Unit = set --= it; + override def --=(that: Iterable[A]): Unit = self --= that; - override def excl(elems: A*): Unit = set --= elems; + override def --=(it: Iterator[A]): Unit = self --= it; - override def intersect(that: Set[A]): Unit = set.intersect(that); + override def excl(elems: A*): Unit = self --= elems; - def clear: Unit = set.clear; + override def intersect(that: Set[A]): Unit = self.intersect(that); - override def filter(p: A => Boolean): Unit = set.filter(p); + def clear: Unit = self.clear; - override def <<(cmd: Message[A]): Unit = set << cmd; + override def filter(p: A => Boolean): Unit = self.filter(p); - override def clone(): Set[A] = new SetProxy(set.clone()); + override def <<(cmd: Message[A]): Unit = self << cmd; + + override def clone(): Set[A] = new SetProxy[A] { def self = SetProxy.this.self.clone() } } diff --git a/sources/scala/collection/mutable/SingleLinkedList.scala b/sources/scala/collection/mutable/SingleLinkedList.scala index 30d7796df2..ba1b141524 100644 --- a/sources/scala/collection/mutable/SingleLinkedList.scala +++ b/sources/scala/collection/mutable/SingleLinkedList.scala @@ -18,7 +18,7 @@ package scala.collection.mutable; * @author Matthias Zenger * @version 1.0, 08/07/2003 */ -abstract class SingleLinkedList[A, This <: SingleLinkedList[A, This]]: This with Seq[A] { +abstract class SingleLinkedList[A, This <: SingleLinkedList[A, This]]: This extends AnyRef with Seq[A] { var elem: A = _; diff --git a/sources/scala/collection/mutable/StackProxy.scala b/sources/scala/collection/mutable/StackProxy.scala index 62f333945e..cfca6ca56c 100644 --- a/sources/scala/collection/mutable/StackProxy.scala +++ b/sources/scala/collection/mutable/StackProxy.scala @@ -16,29 +16,31 @@ package scala.collection.mutable; * @author Matthias Zenger * @version 1.0, 10/05/2004 */ -class StackProxy[A](s: Stack[A]) extends Stack[A] with SeqProxy[A](s) { +trait StackProxy[A] extends Stack[A] with SeqProxy[A] { + + def self: Stack[A]; /** Access element number <code>n</code>. * * @return the element at index <code>n</code>. */ - override def apply(n: Int): A = s.apply(n); + override def apply(n: Int): A = self.apply(n); /** Returns the length of this stack. */ - override def length: Int = s.length; + override def length: Int = self.length; /** Checks if the stack is empty. * * @return true, iff there is no element on the stack */ - override def isEmpty: Boolean = s.isEmpty; + override def isEmpty: Boolean = self.isEmpty; /** Pushes a single element on top of the stack. * * @param elem the element to push onto the stack */ - override def +=(elem: A): Unit = s += elem; + override def +=(elem: A): Unit = self += elem; /** Pushes all elements provided by an <code>Iterable</code> object * on top of the stack. The elements are pushed in the order they @@ -46,7 +48,7 @@ class StackProxy[A](s: Stack[A]) extends Stack[A] with SeqProxy[A](s) { * * @param iter an iterable object */ - override def ++=(iter: Iterable[A]): Unit = s ++= iter; + override def ++=(iter: Iterable[A]): Unit = self ++= iter; /** Pushes all elements provided by an iterator @@ -55,14 +57,14 @@ class StackProxy[A](s: Stack[A]) extends Stack[A] with SeqProxy[A](s) { * * @param iter an iterator */ - override def ++=(it: Iterator[A]): Unit = s ++= it; + override def ++=(it: Iterator[A]): Unit = self ++= it; /** Pushes a sequence of elements on top of the stack. The first element * is pushed first, etc. * * @param elems a sequence of elements */ - override def push(elems: A*): Unit = s ++= elems; + override def push(elems: A*): Unit = self ++= elems; /** Returns the top element of the stack. This method will not remove * the element from the stack. An error is signaled if there is no @@ -70,17 +72,17 @@ class StackProxy[A](s: Stack[A]) extends Stack[A] with SeqProxy[A](s) { * * @return the top element */ - override def top: A = s.top; + override def top: A = self.top; /** Removes the top element from the stack. */ - override def pop: A = s.pop; + override def pop: A = self.pop; /** * Removes all elements from the stack. After this operation completed, * the stack will be empty. */ - override def clear: Unit = s.clear; + override def clear: Unit = self.clear; /** Returns an iterator over all elements on the stack. This iterator * is stable with respect to state changes in the stack object; i.e. @@ -90,17 +92,17 @@ class StackProxy[A](s: Stack[A]) extends Stack[A] with SeqProxy[A](s) { * * @return an iterator over all stack elements. */ - override def elements: Iterator[A] = s.elements; + override def elements: Iterator[A] = self.elements; /** Creates a list of all stack elements in FIFO order. * * @return the created list. */ - override def toList: List[A] = s.toList; + override def toList: List[A] = self.toList; /** This method clones the stack. * * @return a stack with the same elements. */ - override def clone(): Stack[A] = new StackProxy(s.clone()); + override def clone(): Stack[A] = new StackProxy[A] { def self = StackProxy.this.self.clone() } } diff --git a/sources/scala/nsclib b/sources/scala/nsclib index 02595951cc..829b8f2d61 100755 --- a/sources/scala/nsclib +++ b/sources/scala/nsclib @@ -1 +1 @@ -scala scala.tools.nsc.Main -bootclasspath /home/linuxsoft/apps/java-1.4.2_07/jre/lib/rt.jar -classpath "bootclasses:$HOME/scala/sources" -verbose -prompt -nopredefs
\ No newline at end of file +scala scala.tools.nsc.Main -bootclasspath /home/linuxsoft/apps/java-1.4.2_07/jre/lib/rt.jar -classpath "bootclasses:$HOME/scala/sources" -d newclasses -verbose -prompt -nopredefs
\ No newline at end of file diff --git a/sources/scala/nsclib.bat b/sources/scala/nsclib.bat index c9be294c86..dc94b7e70e 100755 --- a/sources/scala/nsclib.bat +++ b/sources/scala/nsclib.bat @@ -1 +1 @@ -nsc -bootclasspath c:\j2sdk1.4.2_05\jre\lib\rt.jar -classpath "bootclasses;\scala\sources" -verbose -prompt -nopredefs Predef.scala
\ No newline at end of file +nsc -bootclasspath c:\j2sdk1.4.2_05\jre\lib\rt.jar -classpath "bootclasses;\scala\sources" -d newclasses -verbose -prompt -nopredefs %*
\ No newline at end of file diff --git a/sources/scala/tools/nsc/CompilationUnits.scala b/sources/scala/tools/nsc/CompilationUnits.scala index 568856ae7f..3cf6ab9c8b 100644 --- a/sources/scala/tools/nsc/CompilationUnits.scala +++ b/sources/scala/tools/nsc/CompilationUnits.scala @@ -8,7 +8,7 @@ package scala.tools.nsc; import scala.tools.util.{SourceFile, Position}; import scala.tools.nsc.util.FreshNameCreator; -class CompilationUnits: Global { +abstract class CompilationUnits: Global { class CompilationUnit(val source: SourceFile, val mixinOnly: boolean) { diff --git a/sources/scala/tools/nsc/Global.scala b/sources/scala/tools/nsc/Global.scala index 651725f7cf..64eaba7d11 100755 --- a/sources/scala/tools/nsc/Global.scala +++ b/sources/scala/tools/nsc/Global.scala @@ -209,16 +209,16 @@ class Global(val settings: Settings, val reporter: Reporter) extends SymbolTable sym.reset(new loaders.SourcefileLoader(file)); } informTime("total", startTime); + informStatistics; } - def compileLate(file: AbstractFile): unit = { + def compileLate(file: AbstractFile): unit = if (!(fileset contains file)) { val unit = new CompilationUnit(getSourceFile(file)); addUnit(unit); atPhase(parserPhase) { parserPhase(unit) } atPhase(namerPhase) { namerPhase(unit) } } - } def compileFiles(files: List[AbstractFile]): unit = try { @@ -284,4 +284,11 @@ class Global(val settings: Settings, val reporter: Reporter) extends SymbolTable error("could not write file " + file); } } + + private def informStatistics = { + inform("#identifiers : " + analyzer.idcnt); + inform("#selections : " + analyzer.selcnt); + inform("#applications: " + analyzer.appcnt); + inform("#implicits : " + analyzer.implcnt); + } } diff --git a/sources/scala/tools/nsc/ast/TreeBuilder.scala b/sources/scala/tools/nsc/ast/TreeBuilder.scala index e183cb7804..f2b46aa6ed 100755 --- a/sources/scala/tools/nsc/ast/TreeBuilder.scala +++ b/sources/scala/tools/nsc/ast/TreeBuilder.scala @@ -97,9 +97,7 @@ abstract class TreeBuilder { List(ClassDef( FINAL | SYNTHETIC, x, List(), TypeTree(), Template(parents, makeConstructorPart(0, List(List()), args) ::: stats))), - Typed( - New(Apply(Select(Ident(x), nme.CONSTRUCTOR), List())), - makeIntersectionTypeTree(parents map (.duplicate)))) + New(Apply(Select(Ident(x), nme.CONSTRUCTOR), List()))) } /** Create a tree represeting an assignment <lhs = rhs> */ @@ -274,18 +272,21 @@ abstract class TreeBuilder { cnt = cnt + 1; ValDef(mods, v, TypeTree(), Select(Ident(tmp), newTermName("_" + cnt))) } - firstDef :: restDefs + firstDef :: restDefs } } /** Add constructor to template */ def makeConstructorPart(mods: int, vparamss: List[List[ValDef]], args: List[Tree]): List[Tree] = { - val vparamss1 = vparamss map (.map (vd => - ValDef(PARAM | (vd.mods & IMPLICIT), vd.name, vd.tpt.duplicate, EmptyTree))); + var vparamss1 = + vparamss map (.map (vd => + ValDef(PARAM | (vd.mods & IMPLICIT), vd.name, vd.tpt.duplicate, EmptyTree))); + if (vparamss1.isEmpty || + !vparamss1.head.isEmpty && (vparamss1.head.head.mods & IMPLICIT) != 0) + vparamss1 = List() :: vparamss1; val constr: Tree = DefDef( - mods & ConstrFlags | SYNTHETIC, nme.CONSTRUCTOR, List(), - if (vparamss1.isEmpty) List(List()) else vparamss1, - TypeTree(), makeSuperCall(args)); + mods & ConstrFlags | SYNTHETIC, nme.CONSTRUCTOR, List(), vparamss1, TypeTree(), + makeSuperCall(args)); val vparams: List[Tree] = for (val vparams <- vparamss; val vparam <- vparams) yield vparam; vparams ::: List(constr) diff --git a/sources/scala/tools/nsc/ast/TreeCheckers.scala b/sources/scala/tools/nsc/ast/TreeCheckers.scala index 8c3cf80334..be6e2a2b4c 100755 --- a/sources/scala/tools/nsc/ast/TreeCheckers.scala +++ b/sources/scala/tools/nsc/ast/TreeCheckers.scala @@ -7,7 +7,7 @@ package scala.tools.nsc.ast; import scala.tools.util.Position; -class TreeCheckers: Global { +abstract class TreeCheckers: Global { object treeChecker extends Traverser { override def traverse(tree: Tree): unit = { diff --git a/sources/scala/tools/nsc/ast/Trees.scala b/sources/scala/tools/nsc/ast/Trees.scala index e5d040a31f..52b73b5804 100644 --- a/sources/scala/tools/nsc/ast/Trees.scala +++ b/sources/scala/tools/nsc/ast/Trees.scala @@ -9,7 +9,7 @@ import java.io.StringWriter; import java.io.PrintWriter; import scala.tools.util.Position; -class Trees: Global { +abstract class Trees: Global { abstract class Tree { @@ -165,7 +165,7 @@ class Trees: Global { /** Return expression */ case class Return(expr: Tree) - extends SymTree; + extends SymTree with TermTree; case class Try(block: Tree, catches: List[CaseDef], finalizer: Tree) extends TermTree; @@ -678,19 +678,19 @@ class Trees: Global { } def transformTrees(trees: List[Tree]): List[Tree] = - trees mapConserve (tree => transform(tree)); + List.mapConserve(trees)(transform); def transformTemplate(tree: Template): Template = transform(tree: Tree).asInstanceOf[Template]; def transformAbsTypeDefs(trees: List[AbsTypeDef]): List[AbsTypeDef] = - trees mapConserve (tree => transform(tree).asInstanceOf[AbsTypeDef]); + List.mapConserve(trees)(tree=> transform(tree).asInstanceOf[AbsTypeDef]); def transformValDefs(trees: List[ValDef]): List[ValDef] = - trees mapConserve (tree => transform(tree).asInstanceOf[ValDef]); + List.mapConserve(trees)(tree => transform(tree).asInstanceOf[ValDef]); def transformValDefss(treess: List[List[ValDef]]): List[List[ValDef]] = - treess mapConserve (tree => transformValDefs(tree)); + List.mapConserve(treess)(tree => transformValDefs(tree)); def transformCaseDefs(trees: List[CaseDef]): List[CaseDef] = - trees mapConserve (tree => transform(tree).asInstanceOf[CaseDef]); + List.mapConserve(trees)(tree => transform(tree).asInstanceOf[CaseDef]); def transformIdents(trees: List[Ident]): List[Ident] = - trees mapConserve (tree => transform(tree).asInstanceOf[Ident]); + List.mapConserve(trees)(tree => transform(tree).asInstanceOf[Ident]); } class Traverser { diff --git a/sources/scala/tools/nsc/ast/parser/Parsers.scala b/sources/scala/tools/nsc/ast/parser/Parsers.scala index 4e8b098707..8e0ef42c1f 100755 --- a/sources/scala/tools/nsc/ast/parser/Parsers.scala +++ b/sources/scala/tools/nsc/ast/parser/Parsers.scala @@ -158,7 +158,7 @@ abstract class Parsers: ParserPhase { /** Join the comment associated with a definition */ - def joinComment(def trees: List[Tree]): List[Tree] = { + def joinComment(trees: => List[Tree]): List[Tree] = { val buf = in.docBuffer; if (buf != null) { in.docBuffer = null; @@ -750,10 +750,11 @@ abstract class Parsers: ParserPhase { * | BlockExpr * | SimpleExpr `.' Id * | SimpleExpr TypeArgs - * | SimpleExpr ArgumentExprs + * | SimpleExpr1 ArgumentExprs */ def simpleExpr(): Tree = { var t: Tree = _; + var isNew = false; in.token match { case CHARLIT | INTLIT | LONGLIT | FLOATLIT | DOUBLELIT | STRINGLIT | SYMBOLLIT | TRUE | FALSE | NULL => @@ -785,7 +786,7 @@ abstract class Parsers: ParserPhase { case LBRACE => t = blockExpr() case NEW => - return atPos(in.skipToken()) { + t = atPos(in.skipToken()) { val parents = new ListBuffer[Tree] + simpleType(); var args: List[Tree] = List(); if (in.token == LPAREN) args = argumentExprs(); @@ -796,6 +797,7 @@ abstract class Parsers: ParserPhase { val stats = if (in.token == LBRACE) templateBody() else List(); makeNew(parents.toList, stats, args) } + isNew = true case _ => syntaxError("illegal start of simple expression", true); t = errorTermTree @@ -811,11 +813,12 @@ abstract class Parsers: ParserPhase { case _ => return t; } - case LPAREN | LBRACE => + case LPAREN | LBRACE if (!isNew) => t = atPos(in.pos) { Apply(t, argumentExprs()) } case _ => return t } + isNew = false } null;//dummy } @@ -1064,7 +1067,10 @@ abstract class Parsers: ParserPhase { case _ => mods } - loop(0); + var mods = loop(0); + if ((mods & (Flags.ABSTRACT | Flags.OVERRIDE)) == (Flags.ABSTRACT | Flags.OVERRIDE)) + mods = mods & ~(Flags.ABSTRACT | Flags.OVERRIDE) | Flags.ABSOVERRIDE; + mods } /** LocalClassModifiers ::= {LocalClassModifier} @@ -1154,7 +1160,10 @@ abstract class Parsers: ParserPhase { */ def paramType(): Tree = if (in.token == ARROW) - atPos(in.skipToken()) { makeFunctionTypeTree(List(), typ()) } + atPos(in.skipToken()) { + AppliedTypeTree( + scalaDot(nme.BYNAME_PARAM_CLASS_NAME.toTypeName), List(typ())) + } else { val t = typ(); if (in.token == IDENTIFIER && in.name == STAR) { @@ -1490,7 +1499,6 @@ abstract class Parsers: ParserPhase { val vparamss = paramClauses(name, implicitViews.toList, (mods & Flags.CASE) != 0); val thistpe = simpleTypedOpt(); val mods1 = if (vparamss.isEmpty && (mods & Flags.ABSTRACT) != 0) { - if (settings.debug.value) System.out.println("is trait: " + name);//debug mods | Flags.TRAIT } else mods; val template = classTemplate(mods1, vparamss); diff --git a/sources/scala/tools/nsc/ast/parser/Scanners.scala b/sources/scala/tools/nsc/ast/parser/Scanners.scala index 91da9b67f0..25f67f52f2 100755 --- a/sources/scala/tools/nsc/ast/parser/Scanners.scala +++ b/sources/scala/tools/nsc/ast/parser/Scanners.scala @@ -681,7 +681,7 @@ abstract class Scanners: ParserPhase { /** generate an error at the given position */ - def syntaxError(pos: int, msg: String) = { + def syntaxError(pos: int, msg: String): unit = { unit.error(pos, msg); token = ERROR; errpos = pos; @@ -703,66 +703,65 @@ abstract class Scanners: ParserPhase { // Enter keywords - def enterKeyword(s: String, tokenId: int) = { + def enterKeyword(n: Name, tokenId: int): unit = { while (tokenId >= tokenName.length) { val newTokName = new Array[Name](tokenName.length * 2); System.arraycopy(tokenName, 0, newTokName, 0, newTokName.length); tokenName = newTokName; } - val n = newTermName(s); tokenName(tokenId) = n; if (n.start > maxKey) maxKey = n.start; if (tokenId >= tokenCount) tokenCount = tokenId + 1; } - enterKeyword("abstract", ABSTRACT); - enterKeyword("case", CASE); - enterKeyword("class", CLASS); - enterKeyword("catch", CATCH); - enterKeyword("def", DEF); - enterKeyword("do", DO); - enterKeyword("else", ELSE); - enterKeyword("extends", EXTENDS); - enterKeyword("false", FALSE); - enterKeyword("final", FINAL); - enterKeyword("finally", FINALLY); - enterKeyword("for", FOR); - enterKeyword("if", IF); - enterKeyword("implicit", IMPLICIT); - enterKeyword("import", IMPORT); - enterKeyword("match", MATCH); - enterKeyword("new", NEW); - enterKeyword("null", NULL); - enterKeyword("object", OBJECT); - enterKeyword("override", OVERRIDE); - enterKeyword("package", PACKAGE); - enterKeyword("private", PRIVATE); - enterKeyword("protected", PROTECTED); - enterKeyword("return", RETURN); - enterKeyword("sealed", SEALED); - enterKeyword("super", SUPER); - enterKeyword("this", THIS); - enterKeyword("throw", THROW); - enterKeyword("trait", TRAIT); - enterKeyword("true", TRUE); - enterKeyword("try", TRY); - enterKeyword("type", TYPE); - enterKeyword("val", VAL); - enterKeyword("var", VAR); - enterKeyword("with", WITH); - enterKeyword("while", WHILE); - enterKeyword("yield", YIELD); - enterKeyword(".", DOT); - enterKeyword("_", USCORE); - enterKeyword(":", COLON); - enterKeyword("=", EQUALS); - enterKeyword("=>", ARROW); - enterKeyword("<-", LARROW); - enterKeyword("<:", SUBTYPE); - enterKeyword("<%", VIEWBOUND); - enterKeyword(">:", SUPERTYPE); - enterKeyword("#", HASH); - enterKeyword("@", AT); + enterKeyword(nme.ABSTRACTkw, ABSTRACT); + enterKeyword(nme.CASEkw, CASE); + enterKeyword(nme.CLASSkw, CLASS); + enterKeyword(nme.CATCHkw, CATCH); + enterKeyword(nme.DEFkw, DEF); + enterKeyword(nme.DOkw, DO); + enterKeyword(nme.ELSEkw, ELSE); + enterKeyword(nme.EXTENDSkw, EXTENDS); + enterKeyword(nme.FALSEkw, FALSE); + enterKeyword(nme.FINALkw, FINAL); + enterKeyword(nme.FINALLYkw, FINALLY); + enterKeyword(nme.FORkw, FOR); + enterKeyword(nme.IFkw, IF); + enterKeyword(nme.IMPLICITkw, IMPLICIT); + enterKeyword(nme.IMPORTkw, IMPORT); + enterKeyword(nme.MATCHkw, MATCH); + enterKeyword(nme.NEWkw, NEW); + enterKeyword(nme.NULLkw, NULL); + enterKeyword(nme.OBJECTkw, OBJECT); + enterKeyword(nme.OVERRIDEkw, OVERRIDE); + enterKeyword(nme.PACKAGEkw, PACKAGE); + enterKeyword(nme.PRIVATEkw, PRIVATE); + enterKeyword(nme.PROTECTEDkw, PROTECTED); + enterKeyword(nme.RETURNkw, RETURN); + enterKeyword(nme.SEALEDkw, SEALED); + enterKeyword(nme.SUPERkw, SUPER); + enterKeyword(nme.THISkw, THIS); + enterKeyword(nme.THROWkw, THROW); + enterKeyword(nme.TRAITkw, TRAIT); + enterKeyword(nme.TRUEkw, TRUE); + enterKeyword(nme.TRYkw, TRY); + enterKeyword(nme.TYPEkw, TYPE); + enterKeyword(nme.VALkw, VAL); + enterKeyword(nme.VARkw, VAR); + enterKeyword(nme.WITHkw, WITH); + enterKeyword(nme.WHILEkw, WHILE); + enterKeyword(nme.YIELDkw, YIELD); + enterKeyword(nme.DOTkw, DOT); + enterKeyword(nme.USCOREkw, USCORE); + enterKeyword(nme.COLONkw, COLON); + enterKeyword(nme.EQUALSkw, EQUALS); + enterKeyword(nme.ARROWkw, ARROW); + enterKeyword(nme.LARROWkw, LARROW); + enterKeyword(nme.SUBTYPEkw, SUBTYPE); + enterKeyword(nme.VIEWBOUNDkw, VIEWBOUND); + enterKeyword(nme.SUPERTYPEkw, SUPERTYPE); + enterKeyword(nme.HASHkw, HASH); + enterKeyword(nme.ATkw, AT); // Build keyword array key = new Array[byte](maxKey+1); diff --git a/sources/scala/tools/nsc/symtab/Definitions.scala b/sources/scala/tools/nsc/symtab/Definitions.scala index bc78fb2ad8..9b51dfe620 100755 --- a/sources/scala/tools/nsc/symtab/Definitions.scala +++ b/sources/scala/tools/nsc/symtab/Definitions.scala @@ -62,7 +62,10 @@ abstract class Definitions: SymbolTable { var NilModule: Symbol = _; var ConsClass: Symbol = _; var RepeatedParamClass: Symbol = _; + var ByNameParamClass: Symbol = _; + val MaxTupleArity = 9; + val MaxFunctionArity = 9; def TupleClass(i: int): Symbol = getClass("scala.Tuple" + i); def FunctionClass(i: int): Symbol = getClass("scala.Function" + i); @@ -128,6 +131,15 @@ abstract class Definitions: SymbolTable { clazz } + private def newCovariantPolyClass(owner: Symbol, name: Name, parent: Symbol => Type): Symbol = { + val clazz = newClass(owner, name, List()); + val tparam = newTypeParam(clazz, 0) setFlag COVARIANT; + clazz.setInfo( + PolyType( + List(tparam), + ClassInfoType(List(parent(tparam)), new Scope(), clazz))) + } + private def newAlias(owner: Symbol, name: Name, alias: Type): Symbol = { val tpsym = owner.newAliasType(Position.NOPOS, name.toTypeName); tpsym.setInfo(alias); @@ -212,16 +224,11 @@ abstract class Definitions: SymbolTable { MatchErrorModule = getModule("scala.MatchError"); NilModule = getModule("scala.Nil"); ConsClass = getClass("scala.$colon$colon"); - RepeatedParamClass = newClass(ScalaPackageClass, nme.REPEATED_PARAM_CLASS_NAME, List()); - { val tparam = newTypeParam(RepeatedParamClass, 0); - RepeatedParamClass.setInfo( - PolyType( - List(tparam), - ClassInfoType( - List(typeRef(SeqClass.typeConstructor.prefix, SeqClass, List(tparam.typeConstructor))), - new Scope(), - RepeatedParamClass))) - } + RepeatedParamClass = newCovariantPolyClass( + ScalaPackageClass, nme.REPEATED_PARAM_CLASS_NAME, + tparam => typeRef(SeqClass.typeConstructor.prefix, SeqClass, List(tparam.typeConstructor))); + ByNameParamClass = newCovariantPolyClass( + ScalaPackageClass, nme.BYNAME_PARAM_CLASS_NAME, tparam => AnyClass.typeConstructor); // members of class scala.Any Any_== = newMethod( diff --git a/sources/scala/tools/nsc/symtab/Flags.scala b/sources/scala/tools/nsc/symtab/Flags.scala index 83c8a5c269..e50d92bbd2 100644 --- a/sources/scala/tools/nsc/symtab/Flags.scala +++ b/sources/scala/tools/nsc/symtab/Flags.scala @@ -69,15 +69,16 @@ object Flags { // masks val SourceFlags = 0x001FFFFF; // these modifiers can be set in source programs. val ExplicitFlags = // these modifiers can be set explicitly in source programs. - PRIVATE | PROTECTED | ABSTRACT | FINAL | SEALED | OVERRIDE | CASE | IMPLICIT; + PRIVATE | PROTECTED | ABSTRACT | FINAL | SEALED | OVERRIDE | CASE | IMPLICIT | ABSOVERRIDE; val PrintableFlags = // these modifiers appear in TreePrinter output. ExplicitFlags | LOCAL | SYNTHETIC | STABLE | ACCESSOR | ACCESS_METHOD | PARAMACCESSOR | LABEL | BRIDGE; val GenFlags = // these modifiers can be in generated trees SourceFlags | PrintableFlags; + val FieldFlags = MUTABLE | ACCESSED | PARAMACCESSOR; val AccessFlags = PRIVATE | PROTECTED; - val Variances = COVARIANT | CONTRAVARIANT; + val VARIANCES = COVARIANT | CONTRAVARIANT; val ConstrFlags = JAVA; val PickledFlags = 0xFFFFFFFF & ~LOCKED & ~INITIALIZED; @@ -121,7 +122,7 @@ object Flags { case COVARIANT => "<covariant>" case CONTRAVARIANT => "<contravariant>" - case ABSOVERRIDE => "<absoverride>" + case ABSOVERRIDE => "abstract override" case LOCAL => "<local>" case JAVA => "<java>" diff --git a/sources/scala/tools/nsc/symtab/Names.scala b/sources/scala/tools/nsc/symtab/Names.scala index ed9aad85fd..ce7d66aed1 100755 --- a/sources/scala/tools/nsc/symtab/Names.scala +++ b/sources/scala/tools/nsc/symtab/Names.scala @@ -54,7 +54,7 @@ class Names { private def enterChars(cs: Array[char], offset: int, len: int): unit = { var i = 0; while (i < len) { - if (nc == chrs.length) { + if (nc + i == chrs.length) { val newchrs = new Array[char](chrs.length * 2); System.arraycopy(chrs, 0, newchrs, 0, chrs.length); chrs = newchrs; @@ -95,34 +95,23 @@ class Names { /** create a type name from the characters in cs[offset..offset+len-1]. */ - def newTypeName(cs: Array[char], offset: int, len: int): Name = { - val h = hashValue(cs, offset, len) & HASH_MASK; - var n = typeHashtable(h); - while ((n != null) && (n.length != len || !equals(n.start, cs, offset, len))) - n = n.next; - if (n == null) { - n = new TypeName(nc, len, h); - enterChars(cs, offset, len); - } - n - } + def newTypeName(cs: Array[char], offset: int, len: int): Name = + newTermName(cs, offset, len).toTypeName; /** create a type name from string */ def newTypeName(s: String): Name = - newTypeName(s.toCharArray(), 0, s.length()); + newTermName(s).toTypeName; /** create a type name from the UTF8 encoded bytes in bs[offset..offset+len-1]. */ - def newTypeName(bs: Array[byte], offset: int, len: int): Name = { - val cs = new Array[char](bs.length); - val nchrs = UTF8Codec.decode(bs, offset, cs, 0, len); - newTypeName(cs, 0, nchrs) - } + def newTypeName(bs: Array[byte], offset: int, len: int): Name = + newTermName(bs, offset, len).toTypeName; + def nameChars: Array[char] = chrs; - def view(s: String): Name = newTermName(s); + implicit def view(s: String): Name = newTermName(s); // Classes ---------------------------------------------------------------------- diff --git a/sources/scala/tools/nsc/symtab/Scopes.scala b/sources/scala/tools/nsc/symtab/Scopes.scala index c9432222df..4ce45d88d0 100755 --- a/sources/scala/tools/nsc/symtab/Scopes.scala +++ b/sources/scala/tools/nsc/symtab/Scopes.scala @@ -169,7 +169,7 @@ abstract class Scopes: SymbolTable { */ def lookupEntry(name: Name): ScopeEntry = { var e: ScopeEntry = null; - if (hashtable != null) { + if (false & hashtable != null) { e = hashtable(name.start & HASHMASK); while (e != null && e.sym.name != name) e = e.tail; } else { @@ -182,7 +182,7 @@ abstract class Scopes: SymbolTable { /** lookup next entry with same name as this one */ def lookupNextEntry(entry: ScopeEntry): ScopeEntry = { var e = entry; - if (hashtable != null) + if (hashtable != null) //debug do { e = e.tail } while (e != null && e.sym.name != entry.sym.name) else do { e = e.next } while (e != null && e.sym.name != entry.sym.name); diff --git a/sources/scala/tools/nsc/symtab/StdNames.scala b/sources/scala/tools/nsc/symtab/StdNames.scala index 8e8ebdb0fe..77e71141c5 100755 --- a/sources/scala/tools/nsc/symtab/StdNames.scala +++ b/sources/scala/tools/nsc/symtab/StdNames.scala @@ -11,6 +11,56 @@ abstract class StdNames: SymbolTable { object nme { + // Scala keywords; enter them first to minimize scanner.maxKey + val ABSTRACTkw = newTermName("abstract"); + val CASEkw = newTermName("case"); + val CLASSkw = newTermName("class"); + val CATCHkw = newTermName("catch"); + val DEFkw = newTermName("def"); + val DOkw = newTermName("do"); + val ELSEkw = newTermName("else"); + val EXTENDSkw = newTermName("extends"); + val FALSEkw = newTermName("false"); + val FINALkw = newTermName("final"); + val FINALLYkw = newTermName("finally"); + val FORkw = newTermName("for"); + val IFkw = newTermName("if"); + val IMPLICITkw = newTermName("implicit"); + val IMPORTkw = newTermName("import"); + val MATCHkw = newTermName("match"); + val NEWkw = newTermName("new"); + val NULLkw = newTermName("null"); + val OBJECTkw = newTermName("object"); + val OVERRIDEkw = newTermName("override"); + val PACKAGEkw = newTermName("package"); + val PRIVATEkw = newTermName("private"); + val PROTECTEDkw = newTermName("protected"); + val RETURNkw = newTermName("return"); + val SEALEDkw = newTermName("sealed"); + val SUPERkw = newTermName("super"); + val THISkw = newTermName("this"); + val THROWkw = newTermName("throw"); + val TRAITkw = newTermName("trait"); + val TRUEkw = newTermName("true"); + val TRYkw = newTermName("try"); + val TYPEkw = newTermName("type"); + val VALkw = newTermName("val"); + val VARkw = newTermName("var"); + val WITHkw = newTermName("with"); + val WHILEkw = newTermName("while"); + val YIELDkw = newTermName("yield"); + val DOTkw = newTermName("."); + val USCOREkw = newTermName("_"); + val COLONkw = newTermName(":"); + val EQUALSkw = newTermName("="); + val ARROWkw = newTermName("=>"); + val LARROWkw = newTermName("<-"); + val SUBTYPEkw = newTermName("<:"); + val VIEWBOUNDkw = newTermName("<%"); + val SUPERTYPEkw = newTermName(">:"); + val HASHkw = newTermName("#"); + val ATkw = newTermName("@"); + private val LOCAL_PREFIX_STRING = "local$"; private val MIXIN_PREFIX_STRING = "mixin$"; private val OUTER_PREFIX_STRING = "outer$"; @@ -44,6 +94,7 @@ abstract class StdNames: SymbolTable { val STAR = newTermName("*"); val ROOT = newTermName("<root>"); val REPEATED_PARAM_CLASS_NAME = newTermName("<repeated>"); + val BYNAME_PARAM_CLASS_NAME = newTermName("<byname>"); val CONSTRUCTOR = newTermName("<init>"); val INITIALIZER = newTermName("<init>"); diff --git a/sources/scala/tools/nsc/symtab/SymbolLoaders.scala b/sources/scala/tools/nsc/symtab/SymbolLoaders.scala index af05d2fcf1..b10fcabdf0 100755 --- a/sources/scala/tools/nsc/symtab/SymbolLoaders.scala +++ b/sources/scala/tools/nsc/symtab/SymbolLoaders.scala @@ -59,11 +59,13 @@ abstract class SymbolLoaders { initRoot(root); if (!root.isPackageClass) initRoot(root.linkedSym); } + override def load(root: Symbol): unit = complete(root); private def initRoot(root: Symbol): unit = { if (root.rawInfo == this) root.setInfo(if (ok) NoType else ErrorType); - if (root.isModule) initRoot(root.moduleClass) + if (root.isModule) initRoot(root.moduleClass); + if (root.isClass && !root.isModuleClass) root.rawInfo.load(root) } } @@ -148,21 +150,17 @@ abstract class SymbolLoaders { val global: SymbolLoaders.this.global.type = SymbolLoaders.this.global; } - abstract class ClassSymbolLoader(file: AbstractFile) extends SymbolLoader(file) { - override def completeLoad(root: Symbol): unit = complete(root); - } - - class ClassfileLoader(file: AbstractFile) extends ClassSymbolLoader(file) { + class ClassfileLoader(file: AbstractFile) extends SymbolLoader(file) { protected def doComplete(root: Symbol): unit = classfileParser.parse(file, root); protected def kindString: String = "class file"; } - class SymblfileLoader(file: AbstractFile) extends ClassSymbolLoader(file) { + class SymblfileLoader(file: AbstractFile) extends SymbolLoader(file) { protected def doComplete(root: Symbol): unit = symblfileParser.parse(file, root); protected def kindString: String = "symbl file"; } - class SourcefileLoader(file: AbstractFile) extends ClassSymbolLoader(file) { + class SourcefileLoader(file: AbstractFile) extends SymbolLoader(file) { protected def doComplete(root: Symbol): unit = global.compileLate(file); protected def kindString: String = "source file"; } diff --git a/sources/scala/tools/nsc/symtab/SymbolTable.scala b/sources/scala/tools/nsc/symtab/SymbolTable.scala index 59bb30b1a6..cef83f99fa 100755 --- a/sources/scala/tools/nsc/symtab/SymbolTable.scala +++ b/sources/scala/tools/nsc/symtab/SymbolTable.scala @@ -25,7 +25,7 @@ abstract class SymbolTable extends Names ph = p } - def atPhase[T](ph: Phase)(def op: T): T = { + def atPhase[T](ph: Phase)(op: => T): T = { val current = phase; phase = ph; val result = op; diff --git a/sources/scala/tools/nsc/symtab/Symbols.scala b/sources/scala/tools/nsc/symtab/Symbols.scala index 36e03cf808..a42e5f3df9 100755 --- a/sources/scala/tools/nsc/symtab/Symbols.scala +++ b/sources/scala/tools/nsc/symtab/Symbols.scala @@ -80,7 +80,7 @@ abstract class Symbols: SymbolTable { clazz.setInfo(ClassInfoType(List(), new ErrorScope(this), clazz)); clazz } - final def newErrorSymbol(name: Name) = + final def newErrorSymbol(name: Name): Symbol = if (name.isTypeName) newErrorClass(name) else newErrorValue(name); // Tests ---------------------------------------------------------------------- @@ -107,7 +107,7 @@ abstract class Symbols: SymbolTable { final def isAbstractType = isType && !isClass && hasFlag(DEFERRED); final def isTypeParameter = isType && hasFlag(PARAM); final def isAnonymousClass = isClass && (name startsWith nme.ANON_CLASS_NAME); // startsWith necessary because name may grow when lifted - final def isRefinementClass = isClass && name == nme.REFINE_CLASS_NAME; // no lifting for refinement classes + final def isRefinementClass = isClass && name == nme.REFINE_CLASS_NAME.toTypeName; // no lifting for refinement classes final def isModuleClass = isClass && hasFlag(MODULE); final def isPackageClass = isClass && hasFlag(PACKAGE); final def isRoot = isPackageClass && name == nme.ROOT.toTypeName; @@ -188,6 +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 assert(infos != null, this.name); val tp = infos.info; if ((rawflags & LOCKED) != 0) { @@ -197,8 +198,9 @@ abstract class Symbols: SymbolTable { rawflags = rawflags | LOCKED; val current = phase; phase = infos.start; - //System.out.println("completing " + this);//DEBUG tp.complete(this); + if ((rawflags & INITIALIZED) != 0 && settings.debug.value) + System.out.println("completed " + this/* + ":" + info*/);//debug rawflags = rawflags & ~LOCKED; phase = current; cnt = cnt + 1; @@ -277,14 +279,10 @@ abstract class Symbols: SymbolTable { def typeConstructor: Type = throw new Error("typeConstructor inapplicable for " + this); /** The type parameters of this symbol */ + def unsafeTypeParams: List[Symbol] = rawInfo.typeParams; + def typeParams: List[Symbol] = { -/* - if (!hasFlag(MODULE)) { - System.out.println("complete load " + this); - rawInfo.completeLoad(this); - } -*/ - rawInfo.typeParams + rawInfo.load(this); rawInfo.typeParams } /** Reset symbol to initial state @@ -534,7 +532,7 @@ abstract class Symbols: SymbolTable { else if (isAliasType) typeParamsString + " = " + tp.resultType else if (isAbstractType) - tp.match { + tp match { case TypeBounds(lo, hi) => (if (lo.symbol == AllClass) "" else " >: " + lo) + (if (hi.symbol == AnyClass) "" else " <: " + hi) @@ -600,10 +598,10 @@ abstract class Symbols: SymbolTable { override def tpe: Type = { assert(tpeCache != NoType, this); if (valid != phase) { - valid = phase; + if (hasFlag(INITIALIZED)) valid = phase; tpeCache = NoType; tpeCache = typeRef(if (isTypeParameter) NoPrefix else owner.thisType, - this, typeParams map (.tpe)); + this, unsafeTypeParams map (.tpe)) } assert(tpeCache != null/*, "" + this + " " + phase*/); tpeCache @@ -617,7 +615,8 @@ abstract class Symbols: SymbolTable { override def setInfo(tp: Type): this.type = { valid = null; tyconCache = null; - super.setInfo(tp) + super.setInfo(tp); + this } override def reset(completer: Type): unit = { super.reset(completer); @@ -690,6 +689,18 @@ abstract class Symbols: SymbolTable { def cloneSymbolImpl(owner: Symbol): Symbol = throw new Error(); } + def cloneSymbols(syms: List[Symbol]): List[Symbol] = { + val syms1 = syms map (.cloneSymbol); + for (val sym1 <- syms1) sym1.setInfo(sym1.info.substSym(syms, syms1)); + syms1 + } + + def cloneSymbols(syms: List[Symbol], owner: Symbol): List[Symbol] = { + val syms1 = syms map (.cloneSymbol(owner)); + for (val sym1 <- syms1) sym1.setInfo(sym1.info.substSym(syms, syms1)); + syms1 + } + /** An exception for cyclic references of symbol definitions */ case class CyclicReference(sym: Symbol, info: Type) extends TypeError("illegal cyclic reference involving " + sym); diff --git a/sources/scala/tools/nsc/symtab/Types.scala b/sources/scala/tools/nsc/symtab/Types.scala index 250a85f639..b921431f4b 100755 --- a/sources/scala/tools/nsc/symtab/Types.scala +++ b/sources/scala/tools/nsc/symtab/Types.scala @@ -63,7 +63,7 @@ abstract class Types: SymbolTable { /** Map a parameterless method type to its result type * identity for all other types */ - def derefDef: Type = match { + def derefDef: Type = this match { case PolyType(List(), restp) => restp case _ => this } @@ -161,9 +161,16 @@ abstract class Types: SymbolTable { def memberInfo(sym: Symbol): Type = sym.info.asSeenFrom(this, sym.owner); - /** The type of `sym', seen as a member of this type. */ - def memberType(sym: Symbol): Type = - sym.tpe.asSeenFrom(this, sym.owner); + /** The type of `sym', seen as a memeber of this type. */ + def memberType(sym: Symbol): Type = sym.tpe.asSeenFrom(this, sym.owner); + + /* + def memberType(sym: Symbol): Type = { + if (sym.nameString startsWith "PolyType") + System.out.println("" + this + ".memberType(" + sym + ":" + sym.tpe + ") = " + memberType(sym) + ", owner = " + sym.owner);//debug + memberType(sym) + } + */ /** Substitute types `to' for occurrences of references to symbols `from' * in this type. */ @@ -289,8 +296,8 @@ abstract class Types: SymbolTable { /** If this is a lazy type, assign a new type to `sym'. */ def complete(sym: Symbol): unit = {} - /** If this is a symbol loader type, assign the loaded type to `sym'. */ - def completeLoad(sym: Symbol): unit = {} + /** If this is a symbol loader type, load and assign a new type to `sym'. */ + def load(sym: Symbol): unit = {} private def findDecl(name: Name, excludedFlags: int): Symbol = { var alts: List[Symbol] = List(); @@ -338,8 +345,12 @@ abstract class Types: SymbolTable { members = new Scope(List(member, sym)) } else { var prevEntry = members lookupEntry sym.name; - while (prevEntry != null && prevEntry.sym != sym && - !(memberType(prevEntry.sym) matches memberType(sym))) + while (prevEntry != null && + !(prevEntry.sym == sym + || + !prevEntry.sym.hasFlag(PRIVATE) && + !entry.sym.hasFlag(PRIVATE) && + (memberType(prevEntry.sym) matches memberType(sym)))) prevEntry = members lookupNextEntry prevEntry; if (prevEntry == null) { members enter sym; @@ -351,7 +362,7 @@ abstract class Types: SymbolTable { } entry = if (name == nme.ANYNAME) entry.next else decls lookupNextEntry entry } // while (entry != null) - excluded = excluded | PRIVATE + // excluded = excluded | LOCAL } // while (!bcs.isEmpty) excluded = excludedFlags } // while (continue) @@ -412,12 +423,13 @@ abstract class Types: SymbolTable { case object NoPrefix extends Type { override def isStable: boolean = true; override def prefixString = ""; + override def toString(): String = "<noprefix>"; } /** A class for this-types of the form <sym>.this.type */ case class ThisType(sym: Symbol) extends SingletonType { - assert(!sym.isModuleClass || sym.isRoot, sym); + assert(sym.isClass && !sym.isModuleClass || sym.isRoot, sym); override def symbol = sym; override def singleDeref: Type = sym.typeOfThis; override def prefixString = @@ -494,21 +506,31 @@ abstract class Types: SymbolTable { def computeBaseClasses: List[Symbol] = if (parents.isEmpty) List(symbol) else { - var bcs: List[Symbol] = parents.head.baseClasses; - val mixins = parents.tail; - def isNew(limit: List[Type])(clazz: Symbol): boolean = { - var ms = mixins; - while (!(ms eq limit) && ms.head.closurePos(clazz) < 0) ms = ms.tail; - ms eq limit - } - var ms = mixins; - while (!ms.isEmpty) { - bcs = ms.head.baseClasses.filter(isNew(ms)) ::: bcs; - ms = ms.tail + //System.out.println("computing base classes of " + symbol + " at phase " + phase);//DEBUG + // optimized, since this seems to be performance critical + val superclazz = parents.head; + var mixins = parents.tail; + val sbcs = superclazz.baseClasses; + var bcs = sbcs; + def isNew(clazz: Symbol): boolean = + superclazz.closurePos(clazz) < 0 && + { var p = bcs; + while ((p ne sbcs) && (p.head != clazz)) p = p.tail; + p eq sbcs + } + while (!mixins.isEmpty) { + def addMixinBaseClasses(mbcs: List[Symbol]): List[Symbol] = + if (mbcs.isEmpty) bcs + else if (isNew(mbcs.head)) mbcs.head :: addMixinBaseClasses(mbcs.tail) + else addMixinBaseClasses(mbcs.tail); + bcs = addMixinBaseClasses(mixins.head.baseClasses); + mixins = mixins.tail } symbol :: bcs } - if (validBaseClasses != phase) { + if (validBaseClasses == null || + validBaseClasses != phase && + infoTransformers.nextFrom(validBaseClasses).phase.id >= phase.id) { validBaseClasses = phase; baseClassCache = null; baseClassCache = computeBaseClasses; @@ -529,7 +551,8 @@ abstract class Types: SymbolTable { if (parents.isEmpty) this else parents.head.erasure; override def toString(): String = - parents.mkString("", " with ", "") + decls.mkString("{", "; ", "}") + parents.mkString("", " with ", "") + + (if (settings.debug.value || decls.elems != null) decls.mkString("{", "; ", "}") else "") } /** A class representing intersection types with refinements of the form @@ -554,6 +577,8 @@ abstract class Types: SymbolTable { override def singleDeref: Type = base; override def deconst: Type = base; override def toString(): String = base.toString() + "(" + value + ")"; + override def hashCode(): int = if (value == null) 0 + else base.hashCode() * 41 + value.hashCode(); } /** A class for named types of the form <prefix>.<sym.name>[args] @@ -580,14 +605,17 @@ abstract class Types: SymbolTable { override def parents: List[Type] = sym.info.parents map transform; - override def typeOfThis = transform(sym.typeOfThis); + override def typeOfThis = { + class bar { val res = transform(sym.typeOfThis) } + (new bar).res + } override def prefix: Type = pre; override def typeArgs: List[Type] = args; override def typeParams: List[Symbol] = - if (args.isEmpty) symbol.typeParams else List(); + if (args.isEmpty) symbol.unsafeTypeParams else List(); override def decls: Scope = sym.info.decls; @@ -615,11 +643,19 @@ abstract class Types: SymbolTable { sym == AnyRefClass) AnyClass.tpe else typeRef(NoPrefix, sym, List()); - override def toString(): String = - if (!settings.debug.value && sym == RepeatedParamClass && !args.isEmpty) - args(0).toString() + "*" - else pre.prefixString + sym.nameString + - (if (args.isEmpty) "" else args.mkString("[", ",", "]")); + override def toString(): String = { + if (!settings.debug.value) { + if (sym == RepeatedParamClass && !args.isEmpty) + return args(0).toString() + "*"; + if (sym == ByNameParamClass && !args.isEmpty) + return "=> " + args(0).toString(); + if (args.length > 0 && args.length <= MaxFunctionArity - 1 && + sym == FunctionClass(args.length - 1)) + return args.init.mkString("(", ", ", ")") + " => " + args.last; + } + pre.prefixString + sym.nameString + + (if (args.isEmpty) "" else args.mkString("[", ",", "]")) + } } /** A class representing a method type with parameters. @@ -630,7 +666,7 @@ abstract class Types: SymbolTable { override def paramSectionCount: int = resultType.paramSectionCount + 1; override def erasure = { - val pts = paramTypes mapConserve (.erasure); + val pts = List.mapConserve(paramTypes)(.erasure); val res = resultType.erasure; if ((pts eq paramTypes) && (res eq resultType)) this else MethodType(pts, res) @@ -662,12 +698,10 @@ abstract class Types: SymbolTable { override def erasure = resultType.erasure; override def toString(): String = - (if (typeParams.isEmpty) "=> " else typeParams.mkString("[", ",", "]")) + resultType; + (if (typeParams.isEmpty) "=>! " else typeParams.mkString("[", ",", "]")) + resultType;//!!! override def cloneInfo(owner: Symbol) = { - val tparams = typeParams map (.cloneSymbol(owner)); - for (val tparam <- tparams) - tparam.setInfo(tparam.info.substSym(typeParams, tparams)); + val tparams = cloneSymbols(typeParams, owner); PolyType(tparams, resultType.substSym(typeParams, tparams)) } } @@ -727,7 +761,9 @@ abstract class Types: SymbolTable { val sym1 = if (sym.isAbstractType) rebind(pre, sym) else sym; if (sym1.isAbstractType && !pre.isStable && !pre.isError) throw new MalformedType(pre, sym.nameString); - if (sym1.isAliasType && sym1.typeParams.length == args.length) { + if (sym1.isAliasType && sym1.info.typeParams.length == args.length) { + // note: we require that object is initialized, + // that's why we use info.typeParams instead of typeParams. if (sym1.hasFlag(LOCKED)) throw new TypeError("illegal cyclic reference involving " + sym1); sym1.setFlag(LOCKED); @@ -795,16 +831,19 @@ abstract class Types: SymbolTable { case ErrorType | WildcardType | NoType | NoPrefix | ThisType(_) => tp case SingleType(pre, sym) => - val pre1 = this(pre); - if (pre1 eq pre) tp - else singleType(pre1, sym) + if (sym.isPackageClass) tp // short path + else { + val pre1 = this(pre); + if (pre1 eq pre) tp + else singleType(pre1, sym) + } case ConstantType(base, value) => val base1 = this(base); if (base1 eq base) tp else ConstantType(base1, value) case TypeRef(pre, sym, args) => val pre1 = this(pre); - val args1 = args mapConserve this; + val args1 = List.mapConserve(args)(this); if ((pre1 eq pre) && (args1 eq args)) tp else typeRef(pre1, sym, args1) case TypeBounds(lo, hi) => @@ -813,7 +852,7 @@ abstract class Types: SymbolTable { if ((lo1 eq lo) && (hi1 eq hi)) tp else TypeBounds(lo1, hi1) case RefinedType(parents, refinement) => - val parents1 = parents mapConserve this; + val parents1 = List.mapConserve(parents)(this); val refinement1 = mapOver(refinement); if ((parents1 eq parents) && (refinement1 eq refinement)) tp else { @@ -828,7 +867,7 @@ abstract class Types: SymbolTable { result } case MethodType(paramtypes, result) => - val paramtypes1 = paramtypes mapConserve this; + val paramtypes1 = List.mapConserve(paramtypes)(this); val result1 = this(result); if ((paramtypes1 eq paramtypes) && (result1 eq result)) tp else if (tp.isInstanceOf[ImplicitMethodType]) new ImplicitMethodType(paramtypes1, result1) @@ -860,7 +899,7 @@ abstract class Types: SymbolTable { /** Map this function over given list of symbols */ private def mapOver(syms: List[Symbol]): List[Symbol] = { val infos = syms map (.info); - val infos1 = infos mapConserve this; + val infos1 = List.mapConserve(infos)(this); if (infos1 eq infos) syms else { val syms1 = syms map (.cloneSymbol); @@ -882,11 +921,13 @@ abstract class Types: SymbolTable { else toPrefix(pre.baseType(clazz).prefix, clazz.owner); toPrefix(pre, clazz) case SingleType(pre, sym) => - try { - mapOver(tp) - } catch { - case ex: MalformedType => apply(tp.singleDeref) // todo: try needed? - } + if (sym.isPackageClass) tp // fast path + else + try { + mapOver(tp) + } catch { + case ex: MalformedType => apply(tp.singleDeref) // todo: try needed? + } case TypeRef(prefix, sym, args) if (sym.isTypeParameter) => def toInstance(pre: Type, clazz: Symbol): Type = if (pre == NoType || pre == NoPrefix || !clazz.isClass) tp @@ -902,7 +943,8 @@ abstract class Types: SymbolTable { if (symclazz == clazz && (pre.widen.symbol isSubClass symclazz)) pre.baseType(symclazz) match { case TypeRef(_, basesym, baseargs) => - instParam(basesym.info.typeParams, baseargs); + assert(basesym.typeParams.length == baseargs.length);//debug + instParam(basesym.typeParams, baseargs); case _ => throwError } @@ -1124,7 +1166,7 @@ abstract class Types: SymbolTable { isSubArgs(tps1.tail, tps2.tail, tparams.tail) } sym1 == sym2 && (pre1 <:< pre2) && - isSubArgs(args1, args2, sym1.info.typeParams) + isSubArgs(args1, args2, sym1.typeParams) || sym1.isAbstractType && !(tp1 =:= tp1.bounds.hi) && (tp1.bounds.hi <:< tp2) || @@ -1211,6 +1253,8 @@ abstract class Types: SymbolTable { case Pair(PolyType(tparams1, res1), PolyType(tparams2, res2)) => tparams1.length == tparams2.length && (res1 matches res2.substSym(tparams2, tparams1)) + case Pair(PolyType(List(), rtp1), _) => matchesType(rtp1, tp2) + case Pair(_, PolyType(List(), rtp2)) => matchesType(tp1, rtp2) case Pair(MethodType(_, _), _) => false case Pair(PolyType(_, _), _) => false case Pair(_, MethodType(_, _)) => false @@ -1361,10 +1405,11 @@ abstract class Types: SymbolTable { /** The least upper bound wrt <:< of a list of types */ def lub(ts: List[Type]): Type = { - def lub0(ts0: List[Type]): Type = elimSub(ts0) match { + def lub0(ts0: List[Type]): Type = elimSub(ts0 map (.deconst)) match { case List() => AllClass.tpe case List(t) => t case ts @ PolyType(tparams, _) :: _ => + assert(false);//debug PolyType( List.map2(tparams, List.transpose(matchingBounds(ts, tparams))) ((tparam, bounds) => tparam.cloneSymbol.setInfo(glb(bounds))), @@ -1375,8 +1420,9 @@ abstract class Types: SymbolTable { val closures: List[Array[Type]] = ts map (.closure); val lubBaseTypes: Array[Type] = lubArray(closures); val lubParents = spanningTypes(List.fromArray(lubBaseTypes)); - val lubBase = refinedType(lubParents, commonOwner(ts)); - val lubType = refinedType(lubParents, lubBase.symbol); + val lubOwner = commonOwner(ts); + val lubBase = refinedType(lubParents, lubOwner); + val lubType = refinedType(lubParents, lubOwner); val lubThisType = lubType.symbol.thisType; val narrowts = ts map (.narrow); def lubsym(proto: Symbol): Symbol = { @@ -1384,24 +1430,29 @@ abstract class Types: SymbolTable { val syms = narrowts map (t => t.nonPrivateMember(proto.name).suchThat(sym => sym.tpe matches prototp.substThis(lubThisType.symbol, t))); - val symtypes = List.map2(narrowts, syms) - ((t, sym) => t.memberInfo(sym).substThis(t.symbol, lubThisType)); - if (syms contains NoSymbol) - NoSymbol - else if (proto.isTerm) - proto.cloneSymbol.setInfo(lub(symtypes)) - else if (symtypes.tail forall (symtypes.head =:=)) - proto.cloneSymbol.setInfo(symtypes.head) - else { - def lubBounds(bnds: List[TypeBounds]): TypeBounds = - TypeBounds(glb(bnds map (.lo)), lub(bnds map (.hi))); - proto.owner.newAbstractType(proto.pos, proto.name) - .setInfo(lubBounds(symtypes map (.bounds))) - } + if (syms contains NoSymbol) NoSymbol + else { + val symtypes = List.map2(narrowts, syms) + ((t, sym) => t.memberInfo(sym).substThis(t.symbol, lubThisType)); + System.out.println("common symbols: " + syms + ":" + symtypes);//debug + if (proto.isTerm) + proto.cloneSymbol.setInfo(lub(symtypes)) + else if (symtypes.tail forall (symtypes.head =:=)) + proto.cloneSymbol.setInfo(symtypes.head) + else { + def lubBounds(bnds: List[TypeBounds]): TypeBounds = + TypeBounds(glb(bnds map (.lo)), lub(bnds map (.hi))); + proto.owner.newAbstractType(proto.pos, proto.name) + .setInfo(lubBounds(symtypes map (.bounds))) + } + } } def refines(tp: Type, sym: Symbol): boolean = { val syms = tp.nonPrivateMember(sym.name).alternatives; - !syms.isEmpty && (syms forall (alt => !specializesSym(lubThisType, sym, tp, alt))) + !syms.isEmpty && (syms forall (alt => + // todo alt != sym is strictly speaking not correct, but without it we lose + // efficiency. + alt != sym && !specializesSym(lubThisType, sym, tp, alt))) } for (val sym <- lubBase.nonPrivateMembers) // add a refinement symbol for all non-class members of lubBase @@ -1410,15 +1461,21 @@ abstract class Types: SymbolTable { addMember(lubThisType, lubType, lubsym(sym)); if (lubType.decls.isEmpty) lubBase else lubType; } - if (settings.debug.value) System.out.println("lub of " + ts);//debug + if (settings.debug.value) { + System.out.println(indent + "lub of " + ts);//debug + indent = indent + " "; + } val res = limitRecursion(ts, "least upper", lub0); - if (settings.debug.value) System.out.println("lub of " + ts + " is " + res);//debug + if (settings.debug.value) { + indent = indent.substring(0, indent.length() - 2); + System.out.println(indent + "lub of " + ts + " is " + res);//debug + } res } /** The greatest lower bound wrt <:< of a list of types */ def glb(ts: List[Type]): Type = { - def glb0(ts0: List[Type]): Type = elimSuper(ts0) match { + def glb0(ts0: List[Type]): Type = elimSuper(ts0 map (.deconst)) match { case List() => AnyClass.tpe case List(t) => t case ts @ PolyType(tparams, _) :: _ => @@ -1430,8 +1487,9 @@ abstract class Types: SymbolTable { MethodType(pts, glb0(matchingRestypes(ts, pts))) case ts => try { - val glbBase = refinedType(ts, commonOwner(ts)); - val glbType = refinedType(ts, glbBase.symbol); + val glbOwner = commonOwner(ts); + val glbBase = refinedType(ts, glbOwner); + val glbType = refinedType(ts, glbOwner); val glbThisType = glbType.symbol.thisType; def glbsym(proto: Symbol): Symbol = { val prototp = glbThisType.memberInfo(proto); @@ -1475,7 +1533,16 @@ abstract class Types: SymbolTable { else AllClass.tpe } } - limitRecursion(ts, "greatest lower", glb0) + if (settings.debug.value) { + System.out.println(indent + "glb of " + ts);//debug + indent = indent + " "; + } + val res = limitRecursion(ts, "greatest lower", glb0); + if (settings.debug.value) { + indent = indent.substring(0, indent.length() - 2); + System.out.println(indent + "glb of " + ts + " is " + res);//debug + } + res } /** The most deeply nested owner that contains all the symbols @@ -1491,7 +1558,7 @@ abstract class Types: SymbolTable { private def commonOwner(tps: List[Type]): Symbol = { if (settings.debug.value) System.out.println("computing common owner of types " + tps);//debug commonOwnerMap.init; - tps mapConserve commonOwnerMap; + List.mapConserve(tps)(commonOwnerMap); commonOwnerMap.result } @@ -1508,7 +1575,7 @@ abstract class Types: SymbolTable { val pre = if (variance == 1) lub(pres) else glb(pres); val argss = tps map (.typeArgs); val args = - List.map2(sym.info.typeParams, List.transpose(argss)) + List.map2(sym.typeParams, List.transpose(argss)) ((tparam, as) => if (tparam.variance == variance) lub(as) else if (tparam.variance == -variance) glb(as) @@ -1532,6 +1599,7 @@ abstract class Types: SymbolTable { /** Make symbol `sym' a member of scope `tp.decls' where `thistp' is the narrowed * owner type of the scope */ private def addMember(thistp: Type, tp: Type, sym: Symbol): unit = { + System.out.println("add member " + sym);//debug if (!(thistp specializes sym)) { if (sym.isTerm) for (val alt <- tp.nonPrivateDecl(sym.name).alternatives) diff --git a/sources/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/sources/scala/tools/nsc/symtab/classfile/ClassfileParser.scala index d63f186146..e5ea1c434a 100755 --- a/sources/scala/tools/nsc/symtab/classfile/ClassfileParser.scala +++ b/sources/scala/tools/nsc/symtab/classfile/ClassfileParser.scala @@ -149,28 +149,28 @@ abstract class ClassfileParser { def getSuperClass(index: int): Symbol = if (index == 0) definitions.AnyClass else getClassSymbol(index); - def getLiteral(index: int): Any = { + def getLiteral(index: int): Constant = { if (index <= 0 || len <= index) errorBadIndex(index); var value = values(index); if (value == null) { val start = starts(index); value = in.buf(start) match { case CONSTANT_STRING => - getName(in.getChar(start + 1)).toString() + Constant(getName(in.getChar(start + 1)).toString()) case CONSTANT_INTEGER => - in.getInt(start + 1) + Constant(in.getInt(start + 1)) case CONSTANT_FLOAT => - in.getFloat(start + 1) + Constant(in.getFloat(start + 1)) case CONSTANT_LONG => - in.getLong(start + 1) + Constant(in.getLong(start + 1)) case CONSTANT_DOUBLE => - in.getDouble(start + 1) + Constant(in.getDouble(start + 1)) case _ => errorBadTag(start); } values(index) = value; } - value + value.asInstanceOf[Constant] } /** Throws an exception signaling a bad constant index. */ @@ -264,7 +264,7 @@ abstract class ClassfileParser { def parseField(): unit = { val jflags = in.nextChar(); var sflags = transFlags(jflags); - if ((sflags & FINAL) != 0) sflags = sflags | MUTABLE; + if ((sflags & FINAL) == 0) sflags = sflags | MUTABLE; if ((sflags & PRIVATE) != 0) { in.skip(4); skipAttributes(); } else { @@ -314,22 +314,21 @@ abstract class ClassfileParser { sym.setFlag(DEPRECATED); in.skip(attrLen) case nme.ConstantValueATTR => - def cast(value: Any, tp: Type): Any = { + def cast(c: Constant, tp: Type): Any = { val s = symtype.symbol; - if (s == definitions.ByteClass) value.asInstanceOf[byte] - else if (s == definitions.ShortClass) value.asInstanceOf[short] - else if (s == definitions.CharClass) value.asInstanceOf[char] - else if (s == definitions.IntClass) value.asInstanceOf[int] - else if (s == definitions.LongClass) value.asInstanceOf[long] - else if (s == definitions.FloatClass) value.asInstanceOf[float] - else if (s == definitions.DoubleClass) value.asInstanceOf[double] + if (s == definitions.ByteClass) c.value.asInstanceOf$erased[int].asInstanceOf$erased[byte] + else if (s == definitions.ShortClass) c.value.asInstanceOf$erased[int].asInstanceOf$erased[short] + else if (s == definitions.CharClass) c.value.asInstanceOf$erased[int].asInstanceOf$erased[char] + else if (s == definitions.IntClass) c.value.asInstanceOf$erased[int] + else if (s == definitions.LongClass) c.value.asInstanceOf$erased[long] + else if (s == definitions.FloatClass) c.value.asInstanceOf$erased[float] + else if (s == definitions.DoubleClass) c.value.asInstanceOf$erased[double] else if (s == definitions.UnitClass) () - else if (s == definitions.BooleanClass) value.asInstanceOf[int] != 0 - else if (s == definitions.StringClass) value.asInstanceOf[String] - else value + else if (s == definitions.BooleanClass) c.value.asInstanceOf$erased[int] != 0 + else c.value } - val value = pool.getLiteral(in.nextChar()); - sym.setInfo(ConstantType(symtype, cast(value, symtype))) + val c = pool.getLiteral(in.nextChar()); + sym.setInfo(ConstantType(symtype, cast(c, symtype))) case nme.InnerClassesATTR => parseInnerClasses() case nme.ScalaSignatureATTR => diff --git a/sources/scala/tools/nsc/symtab/classfile/Constant.scala b/sources/scala/tools/nsc/symtab/classfile/Constant.scala index 32161fdfc1..d1fb4f1a3d 100755 --- a/sources/scala/tools/nsc/symtab/classfile/Constant.scala +++ b/sources/scala/tools/nsc/symtab/classfile/Constant.scala @@ -6,4 +6,8 @@ package scala.tools.nsc.symtab.classfile; /* A wrapper for constant values */ -case class Constant(value: Any); +case class Constant(value: Any) { + // todo: change hashcode generation to make this superfluous + override def hashCode(): int = if (value == null) 0 else value.hashCode() * 41 + 17; +} + diff --git a/sources/scala/tools/nsc/symtab/classfile/Pickler.scala b/sources/scala/tools/nsc/symtab/classfile/Pickler.scala index b21f033354..f8dbada928 100755 --- a/sources/scala/tools/nsc/symtab/classfile/Pickler.scala +++ b/sources/scala/tools/nsc/symtab/classfile/Pickler.scala @@ -51,6 +51,7 @@ abstract class Pickler { /** Is root in symbol.owner*? */ private def isLocal(sym: Symbol): boolean = + sym.isRefinementClass || sym.name.toTermName == rootName && sym.owner == rootOwner || sym != NoSymbol && isLocal(sym.owner); @@ -179,7 +180,8 @@ abstract class Pickler { case SingleType(pre, sym) => writeRef(pre); writeRef(sym); SINGLEtpe case ConstantType(base, value) => - writeRef(base); writeRef(value); CONSTANTtpe + writeRef(base); writeRef(Constant(value)); + CONSTANTtpe case TypeRef(pre, sym, args) => writeRef(pre); writeRef(sym); writeRefs(args); TYPEREFtpe case TypeBounds(lo, hi) => diff --git a/sources/scala/tools/nsc/symtab/classfile/UnPickler.scala b/sources/scala/tools/nsc/symtab/classfile/UnPickler.scala index 2356e61f8c..b35cc61a47 100755 --- a/sources/scala/tools/nsc/symtab/classfile/UnPickler.scala +++ b/sources/scala/tools/nsc/symtab/classfile/UnPickler.scala @@ -9,6 +9,7 @@ import scala.tools.util.{Position, UTF8Codec}; import java.lang.{Float, Double}; import Flags._; import PickleFormat._; +import collection.mutable.HashMap; abstract class UnPickler { val global: Global; @@ -19,7 +20,7 @@ abstract class UnPickler { } catch { case ex: Throwable => if (settings.debug.value) ex.printStackTrace(); - throw new RuntimeException("error readng Scala signature: " + ex.getMessage()); + throw new RuntimeException("error reading Scala signature of " + classRoot.nameString + ": " + ex.getMessage()); } private class UnPickle(bytes: Array[byte], offset: int, classRoot: Symbol, moduleRoot: Symbol) extends PickleBuffer(bytes, offset, -1) { @@ -27,11 +28,19 @@ abstract class UnPickler { private val index = createIndex; private val entries = new Array[AnyRef](index.length); + private val symScopes = new HashMap[Symbol, Scope]; + for (val i <- Iterator.range(0, index.length)) if (isSymbolEntry(i)) { at(i, readSymbol); () } if (settings.debug.value) global.log("unpickled " + classRoot + ":" + classRoot.rawInfo + ", " + moduleRoot + ":" + moduleRoot.rawInfo);//debug + /** The scope associated with given symbol */ + private def symScope(sym: Symbol) = symScopes.get(sym) match { + case None => val s = new Scope(); symScopes(sym) = s; s + case Some(s) => s + } + /** Does entry represent an (internal) symbol */ private def isSymbolEntry(i: int): boolean = { val tag = bytes(index(i)); @@ -84,7 +93,6 @@ abstract class UnPickler { sym = NoSymbol case _ => val name = readNameRef(); - System.out.println("reading symbol " + name);//debug val owner = readSymbolRef(); val flags = readNat(); val inforef = readNat(); @@ -111,8 +119,8 @@ abstract class UnPickler { sym.setFlag(flags); sym.setInfo(new LazyTypeRef(inforef)); if (sym.owner.isClass && sym != classRoot && sym != moduleRoot && - !sym.isModuleClass && !sym.hasFlag(PARAM)) - sym.owner.info.decls enter sym + !sym.isModuleClass && !sym.isRefinementClass && !sym.hasFlag(PARAM | LOCAL)) + symScope(sym.owner) enter sym } sym } @@ -139,10 +147,10 @@ abstract class UnPickler { new TypeBounds(readTypeRef(), readTypeRef()) case REFINEDtpe => val clazz = readSymbolRef(); - new RefinedType(until(end, readTypeRef), new Scope()) { override def symbol = clazz } + new RefinedType(until(end, readTypeRef), symScope(clazz)) { override def symbol = clazz } case CLASSINFOtpe => val clazz = readSymbolRef(); - ClassInfoType(until(end, readTypeRef), new Scope(), clazz) + ClassInfoType(until(end, readTypeRef), symScope(clazz), clazz) case METHODtpe => val restpe = readTypeRef(); MethodType(until(end, readTypeRef), restpe) @@ -184,10 +192,11 @@ abstract class UnPickler { private def readConstantRef(): Constant = at(readNat(), readConstant); private def errorBadSignature(msg: String) = - throw new RuntimeException("malformed Scala signature at " + readIndex + "; " + msg); + throw new RuntimeException("malformed Scala signature of " + classRoot.name + " at " + readIndex + "; " + msg); private class LazyTypeRef(i: int) extends LazyType { - override def complete(sym: Symbol): unit = sym setInfo at(i, readType) + override def complete(sym: Symbol): unit = sym setInfo at(i, readType); + override def load(sym: Symbol): unit = complete(sym) } } } diff --git a/sources/scala/tools/nsc/typechecker/ConstantFolder.scala b/sources/scala/tools/nsc/typechecker/ConstantFolder.scala index 3971167d0c..83530cdd34 100755 --- a/sources/scala/tools/nsc/typechecker/ConstantFolder.scala +++ b/sources/scala/tools/nsc/typechecker/ConstantFolder.scala @@ -53,7 +53,7 @@ abstract class ConstantFolder { private def foldBinop(op: Name, lvalue: Any, rvalue: Any): Any = Triple(op, lvalue, rvalue) match { case Triple(nme.ZOR , x: boolean, y: boolean) => x | y - case Triple(nme.OR, , x: boolean, y: boolean) => x | y + case Triple(nme.OR , x: boolean, y: boolean) => x | y case Triple(nme.OR , x: int , y: int ) => x | y case Triple(nme.OR , x: long , y: long ) => x | y diff --git a/sources/scala/tools/nsc/typechecker/Contexts.scala b/sources/scala/tools/nsc/typechecker/Contexts.scala index 19d02e6856..4d8edafab6 100755 --- a/sources/scala/tools/nsc/typechecker/Contexts.scala +++ b/sources/scala/tools/nsc/typechecker/Contexts.scala @@ -116,8 +116,9 @@ class Contexts: Analyzer { def ambiguousError(pos: int, pre: Type, sym1: Symbol, sym2: Symbol, rest: String): unit = { val msg = "ambiguous reference to overloaded definition,\n" + - "both " + sym1 + ": " + pre.memberType(sym1) + "\n" + - "and " + sym2 + ": " + pre.memberType(sym2) + "\nmatch " + rest; + "both " + sym1 + sym1.locationString + " of type " + pre.memberType(sym1) + + "\nand " + sym2 + sym2.locationString + " of type " + pre.memberType(sym2) + + "\nmatch " + rest; if (reportAmbiguousErrors) unit.error(pos, msg) else throw new TypeError(msg); } @@ -137,12 +138,12 @@ class Contexts: Analyzer { override def toString(): String = { if (this == NoContext) "NoContext"; - else owner.toString() + " @ " + tree.toString() + "\n:: " + outer.toString() + else owner.toString() + " @ " + tree.getClass() + " " + tree.toString() + ", scope = " + scope.hashCode() + "\n:: " + outer.toString() } /** Is `sym' accessible as a member of tree `site' with type `pre' in current context? */ - def isAccessible(sym: Symbol, pre: Type, site: Tree): boolean = { + def isAccessible(sym: Symbol, pre: Type, superAccess: boolean): boolean = { /** Are we inside definition of `owner'? */ def accessWithin(owner: Symbol): boolean = { @@ -169,14 +170,14 @@ class Contexts: Analyzer { accessWithin(sym.owner) && (!sym.hasFlag(LOCAL) || pre.isInstanceOf[ThisType]) || (!sym.hasFlag(PRIVATE) && - (site.isInstanceOf[Super] || + (superAccess || (pre.widen.symbol.isSubClass(sym.owner) && isSubClassOfEnclosing(pre.widen.symbol)))) } private var implicitsCache: List[List[ImplicitInfo]] = null; private def collectImplicits(syms: List[Symbol], pre: Type): List[ImplicitInfo] = - for (val sym <- syms; sym.hasFlag(IMPLICIT) && isAccessible(sym, pre, EmptyTree)) + for (val sym <- syms; sym.hasFlag(IMPLICIT) && isAccessible(sym, pre, false)) yield ImplicitInfo(sym.name, pre.memberType(sym), sym); private def collectImplicitImports(imp: ImportInfo): List[ImplicitInfo] = { @@ -200,7 +201,9 @@ class Contexts: Analyzer { if (implicitsCache == null) { val newImplicits: List[ImplicitInfo] = if (owner != outer.owner && owner.isClass && !owner.isPackageClass) { - collectImplicits(owner.info.implicitMembers, owner.thisType) + if (!owner.hasFlag(INITIALIZED)) return outer.implicitss; + if (settings.debug.value) System.out.println("collect member implicits " + owner + ", implicit members = " + owner.thisType.implicitMembers);//debug + collectImplicits(owner.thisType.implicitMembers, owner.thisType) } else if (scope != outer.scope && !owner.isPackageClass) { if (settings.debug.value) System.out.println("collect local implicits " + scope.toList);//debug collectImplicits(scope.toList, NoPrefix) diff --git a/sources/scala/tools/nsc/typechecker/EtaExpansion.scala b/sources/scala/tools/nsc/typechecker/EtaExpansion.scala index 0d38a1b687..8ead3de9ae 100644 --- a/sources/scala/tools/nsc/typechecker/EtaExpansion.scala +++ b/sources/scala/tools/nsc/typechecker/EtaExpansion.scala @@ -8,7 +8,7 @@ package scala.tools.nsc.typechecker; import util.ListBuffer; import symtab.Flags._; -class EtaExpansion: Analyzer { +abstract class EtaExpansion: Analyzer { import global._; import posAssigner.atPos; @@ -44,7 +44,7 @@ class EtaExpansion: Analyzer { } tree match { case Apply(fn, args) => - copy.Apply(tree, liftoutPrefix(fn), args mapConserve liftout); + copy.Apply(tree, liftoutPrefix(fn), List.mapConserve(args)(liftout)); case TypeApply(fn, args) => copy.TypeApply(tree, liftoutPrefix(fn), args) case Select(qual, name) => diff --git a/sources/scala/tools/nsc/typechecker/Infer.scala b/sources/scala/tools/nsc/typechecker/Infer.scala index 5980f46881..814d84bd9f 100755 --- a/sources/scala/tools/nsc/typechecker/Infer.scala +++ b/sources/scala/tools/nsc/typechecker/Infer.scala @@ -5,7 +5,7 @@ // $Id$ package scala.tools.nsc.typechecker; -class Infer: Analyzer { +abstract class Infer: Analyzer { import symtab.Flags._; import global._; import definitions._; @@ -17,11 +17,16 @@ class Infer: Analyzer { /** The formal parameter types corresponding to `formals'. * If `formals' has a repeated last parameter, a list of * (nargs - params.length + 1) copies of its type is returned. */ - def formalTypes(formals: List[Type], nargs: int): List[Type] = - if (!formals.isEmpty && (formals.last.symbol == RepeatedParamClass)) { - val ft = formals.last.typeArgs.head; - formals.init ::: (for (val i <- List.range(formals.length - 1, nargs)) yield ft) - } else formals; + def formalTypes(formals: List[Type], nargs: int): List[Type] = { + val formals1 = formals map { + case TypeRef(_, sym, List(arg)) if (sym == ByNameParamClass) => arg + case formal => formal + } + if (!formals1.isEmpty && (formals1.last.symbol == RepeatedParamClass)) { + val ft = formals1.last.typeArgs.head; + formals1.init ::: (for (val i <- List.range(formals1.length - 1, nargs)) yield ft) + } else formals1 + } /** A fresh type varable with given type parameter as origin. */ def freshVar(tparam: Symbol): TypeVar = new TypeVar(tparam.tpe, new TypeConstraint); @@ -205,10 +210,12 @@ class Infer: Analyzer { def checkAccessible(tree: Tree, sym: Symbol, pre: Type, site: Tree): Tree = if (sym.isError) { tree setSymbol sym setType ErrorType - } else if (sym.owner.hasFlag(INCONSTRUCTOR) && !sym.isTypeParameter && site.isInstanceOf[This]) { + } else if (sym.owner.hasFlag(INCONSTRUCTOR) && + !sym.isTypeParameter && !sym.isConstructor && + site.isInstanceOf[This]) { errorTree(tree, "" + sym + " cannot be accessed from constructor"); } else { - val sym1 = sym filter (alt => context.isAccessible(alt, pre, site)); + val sym1 = sym filter (alt => context.isAccessible(alt, pre, site.isInstanceOf[Super])); if (sym1 == NoSymbol) { errorTree(tree, sym.toString() + " cannot be accessed in " + pre.widen) } else { @@ -216,7 +223,6 @@ class Infer: Analyzer { } } - def isCompatible(tp: Type, pt: Type): boolean = { val tp1 = normalize(tp); (tp1 <:< pt) || isCoercible(tp, pt) @@ -325,11 +331,11 @@ class Infer: Analyzer { () } val targs = solve(tvars, tparams, tparams map varianceInTypes(formals), false); - List.map2(tparams, targs) ((tparam, targ) => + List.map2(tparams, targs) {(tparam, targ) => if (targ.symbol == AllClass && (varianceInType(restpe)(tparam) & COVARIANT) == 0) { uninstantiated += tparam; tparam.tpe - } else targ) + } else targ} } @@ -354,7 +360,7 @@ class Infer: Analyzer { } } case PolyType(tparams, restpe) => - val tparams1 = tparams map (.cloneSymbol); + val tparams1 = cloneSymbols(tparams); isApplicable(tparams1 ::: undetparams, restpe.substSym(tparams, tparams1), argtpes, pt) case ErrorType => true @@ -476,7 +482,7 @@ class Infer: Analyzer { * If several alternatives match `pt', take parameterless one. * Error if no or several such alternatives exist. */ - def inferExprAlternative(tree: Tree, pt: Type): unit = { + def inferExprAlternative(tree: Tree, pt: Type): unit = tryTwice { val pre = tree.symbol.info.prefix; val alts = tree.symbol.alternatives filter (alt => isCompatible(pre.memberType(alt), pt)); @@ -516,7 +522,7 @@ class Infer: Analyzer { * with pt = WildcardType. * Otherwise, if there is no best alternative, error. */ - def inferMethodAlternative(tree: Tree, undetparams: List[Symbol], argtpes: List[Type], pt: Type): unit = { + def inferMethodAlternative(tree: Tree, undetparams: List[Symbol], argtpes: List[Type], pt: Type): unit = tryTwice { val pre = tree.symbol.info.prefix; if (settings.debug.value) System.out.println("infer method alt " + tree.symbol + " with alternatives " + (tree.symbol.alternatives map pre.memberType) + ", argtpes = " + argtpes + ", pt = " + pt);//debug val alts = tree.symbol.alternatives filter (alt => @@ -540,12 +546,28 @@ class Infer: Analyzer { "argument types " + argtpes.mkString("(", ",", ")") + (if (pt == WildcardType) "" else " and expected result type " + pt)); setError(tree); - () + () } else { tree.setSymbol(best).setType(pre.memberType(best)) } } + /** Try inference twice, once without views and once with views, unless views are already disabled. + */ + def tryTwice(infer: => unit): unit = { + if (context.reportGeneralErrors) { + context.reportGeneralErrors = false; + try { + infer + } catch { + case ex: TypeError => + context.reportGeneralErrors = true; + infer + } + context.reportGeneralErrors = true + } else infer + } + /** Assign `tree' the type of unique polymorphic alternative with `nparams' * as the number of type parameters, if it exists. * If several or none such polymorphic alternatives exist, error. @@ -553,10 +575,10 @@ class Infer: Analyzer { def inferPolyAlternative(tree: Tree, nparams: int): unit = { val pre = tree.symbol.info.prefix; val alts = tree.symbol.alternatives filter (alt => - alt.info.typeParams.length == nparams); + alt.typeParams.length == nparams); if (alts.isEmpty) { errorTree(tree, - if (tree.symbol.alternatives exists (alt => alt.info.typeParams.length > 0)) + if (tree.symbol.alternatives exists (alt => alt.typeParams.length > 0)) "wrong number of type parameters for " + treeSymTypeMsg(tree) else treeSymTypeMsg(tree) + " does not take type parameters") } else if (!alts.tail.isEmpty) { diff --git a/sources/scala/tools/nsc/typechecker/Namers.scala b/sources/scala/tools/nsc/typechecker/Namers.scala index 12341ee961..34cf558385 100755 --- a/sources/scala/tools/nsc/typechecker/Namers.scala +++ b/sources/scala/tools/nsc/typechecker/Namers.scala @@ -21,7 +21,16 @@ trait Namers: Analyzer { class Namer(context: Context) { - val typer = new Typer(context); + val typer = { + def isTemplateContext(context: Context): boolean = context.tree match { + case Template(_, _) => true + case Import(_, _) => isTemplateContext(context.outer) + case _ => false + } + new Typer( + if (isTemplateContext(context)) context.make(context.tree, context.owner, new Scope()) + else context) + } private def doubleDefError(pos: int, sym: Symbol): unit = context.error(pos, @@ -144,7 +153,7 @@ trait Namers: Analyzer { tree.symbol = if ((mods & DEFERRED) == 0) owner.newValue(tree.pos, name) - .setFlag(mods | PRIVATE | LOCAL).setInfo(typer.typeCompleter(tree)) + .setFlag(mods & FieldFlags | PRIVATE | LOCAL).setInfo(typer.typeCompleter(tree)) else getter; } else { tree.symbol = diff --git a/sources/scala/tools/nsc/typechecker/TypeCheckers.scala b/sources/scala/tools/nsc/typechecker/TypeCheckers.scala index ccc1156b3d..e6085ce1c1 100755 --- a/sources/scala/tools/nsc/typechecker/TypeCheckers.scala +++ b/sources/scala/tools/nsc/typechecker/TypeCheckers.scala @@ -10,11 +10,16 @@ import symtab.Flags._; import scala.tools.util.Position; /** Methods to create symbols and to enter them into scopes. */ -trait TypeCheckers: Analyzer { +abstract class TypeCheckers: Analyzer { import global._; import definitions._; import posAssigner.atPos; + var appcnt = 0; + var idcnt = 0; + var selcnt = 0; + var implcnt = 0; + class TypeCheckPhase(prev: Phase) extends StdPhase(prev) { def name = "typechecker"; val global: TypeCheckers.this.global.type = TypeCheckers.this.global; @@ -75,7 +80,7 @@ trait TypeCheckers: Analyzer { // of a type application. When set we do not // decompose PolyTypes. - private val stickyModes: int = EXPRmode | PATTERNmode | TYPEmode | INCONSTRmode; + private val stickyModes: int = EXPRmode | PATTERNmode | TYPEmode; /** Report a type error. * @param pos The position where to report the error @@ -123,6 +128,7 @@ trait TypeCheckers: Analyzer { this.owner = owner; this.scope = scope; badSymbol = NoSymbol; + assert(tree.tpe != null, tree);//debug apply(tree.tpe); if (badSymbol == NoSymbol) tree else { @@ -173,6 +179,8 @@ trait TypeCheckers: Analyzer { private def literalType(value: Any): Type = if (value.isInstanceOf[unit]) UnitClass.tpe else if (value.isInstanceOf[boolean]) BooleanClass.tpe + else if (value.isInstanceOf[byte]) ByteClass.tpe + else if (value.isInstanceOf[short]) ShortClass.tpe else if (value.isInstanceOf[char]) CharClass.tpe else if (value.isInstanceOf[int]) IntClass.tpe else if (value.isInstanceOf[long]) LongClass.tpe @@ -189,10 +197,10 @@ trait TypeCheckers: Analyzer { * (3) Apply polymorphic types to fresh instances of their type parameters and * store these instances in context.undetparams, * unless followed by explicit type application. - * (4) In mode EXPRmode but not FUNmode, do the following to unapplied methods: - * (4.1) if the method has only implicit parameters, pass implicit arguments - * (4.2) otherwise, convert to function by eta-expansion, unless function is - * a constructor, in which case we issue an error. + * (4) Do the following to unapplied methods used as values: + * (4.1) If the method has only implicit parameters pass implicit arguments + * (4.2) otherwise, convert to function by eta-expansion, + * except if the method is a constructor, in which case we issue an error. * (5) Convert a class type that serves as a constructor in a pattern as follows: * (5.1) If this type refers to a case class, set tree's type to the unique * instance of its primary constructor that is a subtype of the expected type. @@ -210,19 +218,21 @@ trait TypeCheckers: Analyzer { * (13) When in mode EXPRmode, apply a view * If all this fails, error */ +// def adapt(tree: Tree, mode: int, pt: Type): Tree = { private def adapt(tree: Tree, mode: int, pt: Type): Tree = tree.tpe match { case OverloadedType(pre, alts) if ((mode & FUNmode) == 0) => // (1) inferExprAlternative(tree, pt); adapt(tree, mode, pt) case PolyType(List(), restpe) => // (2) transform(constfold(tree.setType(restpe)), mode, pt); + case TypeRef(_, sym, List(arg)) + if ((mode & EXPRmode) != 0 && sym == ByNameParamClass) => // (2) + adapt(tree setType arg, mode, pt); case PolyType(tparams, restpe) if ((mode & TAPPmode) == 0) => // (3) if (tree.symbol != null) { if (settings.debug.value) System.out.println("adapting " + tree + " " + tree.symbol.tpe + " " + tree.symbol.getClass() + " " + tree.symbol.hasFlag(CASE));//debug } - val tparams1 = tparams map (.cloneSymbol); - for (val tparam1 <- tparams1) - tparam1.setInfo(tparam1.info.substSym(tparams, tparams1)); + val tparams1 = cloneSymbols(tparams); val tree1 = if (tree.isType) tree else TypeApply(tree, tparams1 map (tparam => TypeTree() setPos tparam.pos setType tparam.tpe)) setPos tree.pos; @@ -239,35 +249,42 @@ trait TypeCheckers: Analyzer { if (tree.isType) { val clazz = tree.tpe.symbol; if ((mode & PATTERNmode) != 0) { // (5) - clazz.initialize; - if (clazz.hasFlag(CASE)) { // (5.1) - val tree1 = TypeTree() setPos tree.pos - setType tree.tpe.prefix.memberType(clazz.primaryConstructor); - inferConstructorInstance(tree1, clazz.typeParams, pt); - tree1 - } else if (clazz.isSubClass(SeqClass)) { // (5.2) - pt.baseType(clazz).baseType(SeqClass) match { - case TypeRef(pre, seqClass, args) => - tree.setType(MethodType(List(typeRef(pre, RepeatedParamClass, args)), pt)) - case NoType => - errorTree(tree, "expected pattern type " + pt + - " does not conform to sequence " + clazz) - } + if (tree.tpe.isInstanceOf[MethodType]) { + tree // everything done already } else { - System.out.println("bad: " + clazz + flagsToString(clazz.flags) + clazz.hasFlag(CASE));//debug - errorTree(tree, clazz.toString() + " is neither a case class nor a sequence class") + clazz.initialize; + if (clazz.hasFlag(CASE)) { // (5.1) + val tree1 = TypeTree() setPos tree.pos + setType + clazz.primaryConstructor.tpe.asSeenFrom(tree.tpe.prefix, clazz.owner); + // tree.tpe.prefix.memberType(clazz.primaryConstructor); //!!! + inferConstructorInstance(tree1, clazz.unsafeTypeParams, pt); + tree1 + } else if (clazz.isSubClass(SeqClass)) { // (5.2) + pt.baseType(clazz).baseType(SeqClass) match { + case TypeRef(pre, seqClass, args) => + tree.setType(MethodType(List(typeRef(pre, RepeatedParamClass, args)), pt)) + case NoType => + errorTree(tree, "expected pattern type " + pt + + " does not conform to sequence " + clazz) + } + } else { + System.out.println("bad: " + clazz + ":" + tree.tpe + " " + flagsToString(clazz.flags) + clazz.hasFlag(CASE));//debug + errorTree(tree, clazz.toString() + " is neither a case class nor a sequence class") + } } } else if ((mode & FUNmode) != 0) { tree - } else if (tree.symbol != null && !tree.symbol.typeParams.isEmpty) { // (7) + } else if (tree.symbol != null && !tree.symbol.unsafeTypeParams.isEmpty) { // (7) errorTree(tree, "" + clazz + " takes type parameters"); } else tree match { // (6) case TypeTree() => tree case _ => TypeTree() setPos tree.pos setType tree.tpe } } else if ((mode & (EXPRmode | FUNmode)) == (EXPRmode | FUNmode) && - tree.tpe.member(nme.apply).filter( - m => m.tpe.paramSectionCount > 0) != NoSymbol) { // (8) + ((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), mode, pt) } else if (!context.undetparams.isEmpty & (mode & POLYmode) == 0) { // (9) val tparams = context.undetparams; @@ -295,29 +312,36 @@ trait TypeCheckers: Analyzer { } } } +// System.out.println("adapt " + tree + ":" + tree.tpe + ", mode = " + mode + ", pt = " + pt); +// adapt(tree, mode, pt) +// } - def completeSuperType(supertpt: Tree, tparams: List[Symbol], vparamss: List[List[ValDef]], superargs: List[Tree]): Type = { + private def completeSuperType(supertpt: Tree, tparams: List[Symbol], vparamss: List[List[ValDef]], superargs: List[Tree]): Type = { + tparams foreach context.scope.enter; new Typer(context).enterValueParams(context.owner, vparamss); - context.undetparams = tparams; - transformExpr(atPos(supertpt.pos)(Apply(Select(New(supertpt), nme.CONSTRUCTOR), superargs))) - .tpe + 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))); + 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; // If first parent is trait, make it first mixin and add its superclass as first parent - if (supertpt.tpe.symbol != null && supertpt.tpe.symbol.isTrait) { + if (supertpt.tpe.symbol != null && supertpt.tpe.symbol.initialize.isTrait) { + mixins = supertpt :: mixins; supertpt = gen.TypeTree(supertpt.tpe.parents(0)) setPos supertpt.pos; - mixins = templ.parents } if (supertpt.symbol != null) { val tparams = supertpt.symbol.typeParams; if (!tparams.isEmpty) { val constr @ DefDef(_, _, _, vparamss, _, Apply(_, superargs)) = treeInfo.firstConstructor(templ.body); + val outercontext = context.outer.outer; supertpt = gen.TypeTree( - new TypeChecker(context.makeNewScope(constr, context.owner.owner)) + new TypeChecker(context.outer.outer.makeNewScope(constr, context.outer.outer.owner)) .completeSuperType( supertpt, tparams, @@ -325,7 +349,7 @@ trait TypeCheckers: Analyzer { superargs map (.duplicate))) setPos supertpt.pos; } } - (supertpt :: mixins) mapConserve (tpt => checkNoEscaping.privates(context.owner, tpt)) + List.mapConserve(supertpt :: mixins)(tpt => checkNoEscaping.privates(context.owner, tpt)) } /** Check that @@ -345,7 +369,7 @@ trait TypeCheckers: Analyzer { def validateParentClass(parent: Tree, isFirst: boolean): unit = if (!parent.tpe.isError) { - val psym = parent.tpe.symbol; + val psym = parent.tpe.symbol.initialize; if (!psym.isClass) error(parent.pos, "class type expected"); else if (!isFirst && !psym.isTrait) @@ -383,7 +407,7 @@ trait TypeCheckers: Analyzer { def transformClassDef(cdef: ClassDef): Tree = { val clazz = cdef.symbol; reenterTypeParams(cdef.tparams); - val tparams1 = cdef.tparams mapConserve transformAbsTypeDef; + val tparams1 = List.mapConserve(cdef.tparams)(transformAbsTypeDef); val tpt1 = checkNoEscaping.privates(clazz.thisSym, transformType(cdef.tpt)); val impl1 = new TypeChecker(context.make(cdef.impl, clazz, new Scope())) .transformTemplate(cdef.impl); @@ -420,7 +444,11 @@ trait TypeCheckers: Analyzer { def transformTemplate(templ: Template): Template = { templ setSymbol context.owner.newLocalDummy(templ.pos); val parents1 = parentTypes(templ); - validateParentClasses(parents1, context.owner.typeOfThis); + val selfType = + if (context.owner.isAnonymousClass) + refinedType(context.owner.info.parents, context.owner.owner) + else context.owner.typeOfThis; + validateParentClasses(parents1, selfType); val body1 = templ.body flatMap addGetterSetter; val body2 = transformStats(body1, templ.symbol); copy.Template(templ, parents1, body2) setType context.owner.tpe @@ -431,7 +459,7 @@ trait TypeCheckers: Analyzer { var tpt1 = checkNoEscaping.privates(sym, transformType(vdef.tpt)); val rhs1 = if (vdef.rhs.isEmpty) vdef.rhs - else new TypeChecker(context.make(vdef, sym)).transform(vdef.rhs, EXPRmode, tpt1.tpe); + else new TypeChecker(context.make(vdef, sym)).transform(vdef.rhs, EXPRmode, tpt1.tpe.deconst); copy.ValDef(vdef, vdef.mods, vdef.name, tpt1, rhs1) setType NoType } @@ -439,8 +467,9 @@ trait TypeCheckers: Analyzer { val meth = ddef.symbol; reenterTypeParams(ddef.tparams); reenterValueParams(ddef.vparamss); - val tparams1 = ddef.tparams mapConserve transformAbsTypeDef; - val vparamss1 = ddef.vparamss mapConserve (.mapConserve(transformValDef)); + val tparams1 = List.mapConserve(ddef.tparams)(transformAbsTypeDef); + val vparamss1 = List.mapConserve(ddef.vparamss)(vparams1 => + List.mapConserve(vparams1)(transformValDef)); var tpt1 = checkNoEscaping.privates(meth, transformType(ddef.tpt)); val rhs1 = if (ddef.name == nme.CONSTRUCTOR) { @@ -468,7 +497,7 @@ trait TypeCheckers: Analyzer { def transformAliasTypeDef(tdef: AliasTypeDef): AliasTypeDef = { reenterTypeParams(tdef.tparams); - val tparams1 = tdef.tparams mapConserve transformAbsTypeDef; + val tparams1 = List.mapConserve(tdef.tparams)(transformAbsTypeDef); val rhs1 = checkNoEscaping.privates(tdef.symbol, transformType(tdef.rhs)); copy.AliasTypeDef(tdef, tdef.mods, tdef.name, tparams1, rhs1) setType NoType } @@ -492,6 +521,8 @@ trait TypeCheckers: Analyzer { } val expr1 = transform(block.expr, mode & ~(FUNmode | QUALmode), pt); val block1 = copy.Block(block, stats1, expr1) setType expr1.tpe.deconst; + if (block1.tpe.symbol.isAnonymousClass) + block1 setType refinedType(block1.tpe.parents, block1.tpe.symbol.owner); if (isFullyDefined(pt)) block1 else checkNoEscaping.locals(context.scope, block1) } @@ -506,7 +537,7 @@ trait TypeCheckers: Analyzer { def transformFunction(fun: Function, mode: int, pt: Type): Function = { val Triple(clazz, argpts, respt) = pt match { case TypeRef(_, sym, argtps) - if (sym == FunctionClass(fun.vparams.length) || + if (fun.vparams.length <= MaxFunctionArity && sym == FunctionClass(fun.vparams.length) || sym == PartialFunctionClass && fun.vparams.length == 1 && fun.body.isInstanceOf[Match]) => Triple(sym, argtps.init, argtps.last) case _ => @@ -523,7 +554,7 @@ trait TypeCheckers: Analyzer { namer.enterSym(vparam); vparam.symbol } - val vparams1 = fun.vparams mapConserve transformValDef; + val vparams1 = List.mapConserve(fun.vparams)(transformValDef); val body1 = transform(fun.body, EXPRmode, respt); copy.Function(fun, vparams1, body1) setType typeRef(clazz.tpe.prefix, clazz, (vparamSyms map (.tpe)) ::: List(body1.tpe)) @@ -536,7 +567,7 @@ trait TypeCheckers: Analyzer { } def transformStats(stats: List[Tree], exprOwner: Symbol): List[Tree] = - stats mapConserve { stat => + List.mapConserve(stats) { stat => if (context.owner.isRefinementClass && !treeInfo.isDeclaration(stat)) errorTree(stat, "only declarations allowed here"); stat match { @@ -544,7 +575,7 @@ trait TypeCheckers: Analyzer { context = context.makeNewImport(imp); EmptyTree case _ => - (if (stat.isDef && exprOwner != context.owner) + (if (!stat.isDef && exprOwner != context.owner) new TypeChecker(context.make(stat, exprOwner)) else this).transformExpr(stat) } } @@ -554,8 +585,8 @@ trait TypeCheckers: Analyzer { def funmode = mode & stickyModes | FUNmode | POLYmode; def transformCases(cases: List[CaseDef], pattp: Type): List[CaseDef] = { - cases mapConserve (cdef => new TypeChecker(context.makeNewScope(tree, context.owner)) - .transformCase(cdef, pattp, pt)) + List.mapConserve(cases)(cdef => + new TypeChecker(context.makeNewScope(tree, context.owner)).transformCase(cdef, pattp, pt)) } def transformTypeApply(fun: Tree, args: List[Tree]): Tree = fun.tpe match { @@ -574,18 +605,20 @@ trait TypeCheckers: Analyzer { case ErrorType => setError(tree) case _ => - errorTree(tree, treeSymTypeMsg(fun) + " takes type parameters."); + System.out.println(fun.toString() + " " + args);//debug + errorTree(tree, treeSymTypeMsg(fun) + " does not take type parameters."); } def transformApply(fun: Tree, args: List[Tree]): Tree = fun.tpe match { case OverloadedType(pre, alts) => - val args1 = args mapConserve (arg => + val args1 = List.mapConserve(args)(arg => transform(arg, mode & stickyModes, WildcardType)); inferMethodAlternative(fun, context.undetparams, args1 map (.tpe.deconst), pt); transformApply(adapt(fun, funmode, WildcardType), args1); case MethodType(formals0, restpe) => val formals = formalTypes(formals0, args.length); if (formals.length != args.length) { + System.out.println("" + formals.length + " " + args.length); errorTree(tree, "wrong number of arguments for " + treeSymTypeMsg(fun)) } else { val tparams = context.undetparams; @@ -593,7 +626,11 @@ trait TypeCheckers: Analyzer { if (tparams.isEmpty) { val args1 = List.map2(args, formals) ((arg, formal) => transform(arg, mode & stickyModes, formal)); - val tree1 = copy.Apply(tree, fun, args1).setType(restpe); + 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 (tree1 == tree2) tree2 else transform(tree2, mode, pt) } else { @@ -658,9 +695,12 @@ trait TypeCheckers: Analyzer { return transform( copy.Select(tree, Apply(coercion, List(qual)) setPos qual.pos, name), mode, pt) } - if (sym.info == NoType) + 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) - else { + } else { val tree1 = tree match { case Select(_, _) => copy.Select(tree, qual, name) case SelectFromTypeTree(_, _) => copy.SelectFromTypeTree(tree, qual, name); @@ -687,10 +727,11 @@ trait TypeCheckers: Analyzer { while (defSym == NoSymbol && cx != NoContext) { pre = cx.enclClass.owner.thisType; defEntry = cx.scope.lookupEntry(name); - if (defEntry != null) defSym = defEntry.sym + if (defEntry != null) + defSym = defEntry.sym else { cx = cx.enclClass; - defSym = pre.member(name); + defSym = pre.member(name) filter (sym => context.isAccessible(sym, pre, false)); if (defSym == NoSymbol) cx = cx.outer; } } @@ -708,13 +749,18 @@ trait TypeCheckers: Analyzer { // update `pre' to be `sym's prefix type in case it is an imported member, // and compute value of: var qual: Tree = EmptyTree; // the qualififier tree if transformed tree is a select + + // imported symbols take precedence over external package-owned symbols (hack?) + if (defSym.tpe != NoType && impSym.tpe != NoType && defSym.isExternal && defSym.owner.isPackageClass) + defSym = NoSymbol; + if (defSym.tpe != NoType) { if (impSym.tpe != NoType) ambiguousError( "it is both defined in " + defSym.owner + " and imported subsequently by \n" + imports.head); else if (defSym.owner.isClass && !defSym.owner.isPackageClass && !defSym.isTypeParameter) - qual = gen.This(pre.symbol) setPos tree.pos + qual = atPos(tree.pos)(gen.mkQualifier(pre)); else pre = NoPrefix; } else { @@ -766,7 +812,7 @@ trait TypeCheckers: Analyzer { checkStable(tree) else if ((mode & (EXPRmode | QUALmode)) == EXPRmode && !tree.symbol.isValue) // (3) errorTree(tree, tree.symbol.toString() + " is not a value"); - else if (tree.symbol.isStable && pre.isStable && + else if (tree.symbol.isStable && pre.isStable && tree.tpe.symbol != ByNameParamClass && (pt.isStable || (mode & QUALmode) != 0 || tree.symbol.isModule)) // (4) tree.setType(singleType(pre, tree.symbol)) else @@ -822,11 +868,11 @@ trait TypeCheckers: Analyzer { .transformBlock(block, mode, pt) case Sequence(elems) => - val elems1 = elems mapConserve (elem => transform(elem, mode, pt)); + val elems1 = List.mapConserve(elems)(elem => transform(elem, mode, pt)); copy.Sequence(tree, elems1) setType pt case Alternative(alts) => - val alts1 = alts mapConserve (alt => transform(alt, mode, pt)); + val alts1 = List.mapConserve(alts)(alt => transform(alt, mode, pt)); copy.Alternative(tree, alts1) setType pt case Bind(name, body) => @@ -851,13 +897,16 @@ trait TypeCheckers: Analyzer { if (varsym != null && isGetter(varsym)) { lhs1 match { case Select(qual, name) => - transform(Apply(Select(qual, nme.SETTER_NAME(name)), List(rhs)), mode, pt) + transform( + Apply( + Select(qual, nme.SETTER_NAME(name)) setPos lhs.pos, + List(rhs)), mode, pt) setPos tree.pos } } else if (varsym != null && varsym.isVariable) { val rhs1 = transform(rhs, EXPRmode, lhs1.tpe); copy.Assign(tree, lhs1, rhs1) setType UnitClass.tpe; } else { - System.out.println("" + lhs1 + " " + " " + lhs1.getClass() + varsym);//debug + System.out.println("" + lhs1 + " " + varsym + " " + flagsToString(varsym.flags));//debug if (!lhs1.tpe.isError) error(tree.pos, "assignment to non-variable "); setError(tree) } @@ -869,7 +918,7 @@ trait TypeCheckers: Analyzer { copy.If(tree, cond1, thenp1, elsep) setType UnitClass.tpe } else { val thenp1 = transform(thenp, EXPRmode, pt); - val elsep1 = transform(thenp, EXPRmode, pt); + val elsep1 = transform(elsep, EXPRmode, pt); copy.If(tree, cond1, thenp1, elsep1) setType lub(List(thenp1.tpe, elsep1.tpe)); } @@ -882,8 +931,8 @@ trait TypeCheckers: Analyzer { val enclFun = context.owner.enclMethod; if (!enclFun.isMethod || enclFun.isConstructor) errorTree(tree, "return outside method definition") - else if (context.owner.hasFlag(INITIALIZED)) - errorTree(tree, "method with return needs result type") + 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); copy.Return(tree, expr1) setSymbol enclFun setType AllClass.tpe; @@ -904,14 +953,14 @@ trait TypeCheckers: Analyzer { case New(tpt: Tree) => var tpt1 = transform(tpt, TYPEmode | FUNmode, WildcardType); if (tpt1.symbol != null && !tpt1.symbol.typeParams.isEmpty) { - context.undetparams = tpt1.symbol.typeParams; + context.undetparams = cloneSymbols(tpt1.symbol.unsafeTypeParams); tpt1 = TypeTree() setPos tpt1.pos setType appliedType(tpt1.tpe, context.undetparams map (.tpe)); } copy.New(tree, tpt1).setType(tpt1.tpe) - case Typed(expr, tpt @ Ident(nme.WILDCARD_STAR)) => + case Typed(expr, tpt @ Ident(name)) if (name == nme.WILDCARD_STAR.toTypeName) => val expr1 = transform(expr, mode & stickyModes, seqType(pt)); expr1.tpe.baseType(SeqClass) match { case TypeRef(_, _, List(elemtp)) => @@ -925,7 +974,7 @@ trait TypeCheckers: Analyzer { copy.Typed(tree, expr1, tpt1) setType tpt1.tpe case TypeApply(fun, args) => - val args1 = args mapConserve transformType; + val args1 = List.mapConserve(args)(transformType); // do args first in order to maintain conext.undetparams on the function side. transformTypeApply(transform(fun, funmode | TAPPmode, WildcardType), args1) @@ -934,6 +983,7 @@ trait TypeCheckers: Analyzer { var fun1 = transform(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 if (fun1.hasSymbol && fun1.symbol.hasFlag(OVERLOADED)) { val argtypes = args map (arg => AllClass.tpe); val pre = fun1.symbol.tpe.prefix; @@ -942,6 +992,7 @@ trait TypeCheckers: Analyzer { if (sym != NoSymbol) fun1 = adapt(fun1 setSymbol sym setType pre.memberType(sym), funmode, WildcardType) } + appcnt = appcnt + 1; transformApply(fun1, args) case Super(qual, mix) => @@ -980,19 +1031,21 @@ trait TypeCheckers: Analyzer { transformSelect(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); if (name.isTypeName) qual1 = checkStable(qual1); - val res = transformSelect(qual1, name); - res + transformSelect(qual1, name); case Ident(name) => + idcnt = idcnt + 1; if (name == nme.WILDCARD && (mode & (PATTERNmode | FUNmode)) == PATTERNmode) tree setType pt else - transformIdent(name); + transformIdent(name); case Literal(value) => - tree setType literalType(value) + tree setType ConstantType(literalType(value), value) case SingletonTypeTree(ref) => val ref1 = checkStable(transform(ref, EXPRmode | QUALmode, AnyRefClass.tpe)); @@ -1003,7 +1056,7 @@ trait TypeCheckers: Analyzer { case CompoundTypeTree(templ: Template) => tree setType { - val parents1 = templ.parents mapConserve transformType; + val parents1 = List.mapConserve(templ.parents)(transformType); if (parents1 exists (.tpe.isError)) ErrorType else { val decls = new Scope(); @@ -1015,8 +1068,8 @@ trait TypeCheckers: Analyzer { case AppliedTypeTree(tpt, args) => val tpt1 = transform(tpt, mode | FUNmode | TAPPmode, WildcardType); - val tparams = tpt1.tpe.symbol.info.typeParams; - val args1 = args mapConserve transformType; + val tparams = tpt1.tpe.symbol.typeParams; + val args1 = List.mapConserve(args)(transformType); if (tpt1.tpe.isError) setError(tree) else if (tparams.length == args1.length) @@ -1031,6 +1084,7 @@ trait TypeCheckers: Analyzer { def transform(tree: Tree, mode: int, pt: Type): Tree = try { if (settings.debug.value) assert(pt != null, tree);//debug + if (settings.debug.value) System.out.println("transforming " + tree);//debug val tree1 = if (tree.tpe != null) tree else transform1(tree, mode, pt); if (tree1.isEmpty) tree1 else adapt(tree1, mode, pt) } catch { @@ -1038,7 +1092,7 @@ trait TypeCheckers: Analyzer { reportTypeError(tree.pos, ex); setError(tree) case ex: Throwable => - if (settings.debug.value) + if (true || settings.debug.value)//!!! System.out.println("exception when tranforming " + tree + ", pt = " + pt); throw(ex) } @@ -1051,6 +1105,7 @@ trait TypeCheckers: Analyzer { private def transformImplicit(pos: int, info: ImplicitInfo, pt: Type): Tree = if (isCompatible(info.tpe, pt)) { + implcnt = implcnt + 1; var tree: Tree = EmptyTree; try { tree = transform1(Ident(info.name) setPos pos, EXPRmode, pt); @@ -1068,6 +1123,8 @@ trait TypeCheckers: Analyzer { } 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 = + (sym1.owner != sym2.owner) && (sym1.owner isSubClass sym2.owner) && (tpe1 matches tpe2); val tc = new TypeChecker(context.makeImplicit(reportAmbiguous)); var iss = context.implicitss; var tree: Tree = EmptyTree; @@ -1082,16 +1139,21 @@ trait TypeCheckers: Analyzer { if (tree != EmptyTree) { while (!is.isEmpty) { val tree1 = tc.transformImplicit(pos, is.head, pt); - if (tree1 != EmptyTree) - error(pos, - "ambiguous implicit value:\n" + - " both " + is0.head.sym + is0.head.sym.locationString + - "\n and" + is.head.sym + is.head.sym.locationString + - (if (isView) - "\n are possible conversion functions from " + - pt.typeArgs(0) + " to " + pt.typeArgs(1) - else - "\n match expected type " + 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)); + } is = is.tail } } diff --git a/sources/scala/tools/nsc/typechecker/Typers.scala b/sources/scala/tools/nsc/typechecker/Typers.scala index eb3df2491d..7f574b06f8 100755 --- a/sources/scala/tools/nsc/typechecker/Typers.scala +++ b/sources/scala/tools/nsc/typechecker/Typers.scala @@ -56,14 +56,14 @@ trait Typers: Analyzer { override def complete(sym: Symbol): unit = { val clazz = tree.symbol; var tpe = clazz.primaryConstructor.tpe; - val tparams = clazz.typeParams; + val tparams = clazz.unsafeTypeParams; if (!tparams.isEmpty) tpe = PolyType(tparams, tpe).cloneInfo(sym); sym.setInfo(tpe); } } private def deconstIfNotFinal(sym: Symbol, tpe: Type): Type = - if (sym.isVariable || sym.hasFlag(FINAL)) tpe.deconst else tpe; + if (sym.isVariable || !sym.isFinal) tpe.deconst else tpe; def enterValueParams(owner: Symbol, vparamss: List[List[ValDef]]): List[List[Symbol]] = { def enterValueParam(param: ValDef): Symbol = { @@ -192,7 +192,6 @@ trait Typers: Analyzer { * - `override' modifier never for classes * - `def' modifier never for parameters of case classes * - declarations only in traits or abstract classes - * - todo: in desugarize: replace ABSTRACT OVERRIDE with ABSOVERRIDE */ def validate(sym: Symbol): unit = { def checkNoConflict(flag1: int, flag2: int): unit = diff --git a/sources/scala/tools/nsc/typechecker/Variances.scala b/sources/scala/tools/nsc/typechecker/Variances.scala index 10f40fca54..f3e5f52b9f 100755 --- a/sources/scala/tools/nsc/typechecker/Variances.scala +++ b/sources/scala/tools/nsc/typechecker/Variances.scala @@ -5,9 +5,9 @@ // $Id$ package scala.tools.nsc.typechecker; -/** Variances form a lattice, 0 <= COVARIANT <= Variances, 0 <= CONTRAVARIANT <= Variances +/** Variances form a lattice, 0 <= COVARIANT <= Variances, 0 <= CONTRAVARIANT <= VARIANCES */ -class Variances: Analyzer { +abstract class Variances: Analyzer { import global._; import symtab.Flags._; @@ -19,13 +19,13 @@ class Variances: Analyzer { else v } - /** Map everything below Variances to 0 */ + /** Map everything below VARIANCES to 0 */ private def cut(v: int): int = - if (v == Variances) v else 0; + if (v == VARIANCES) v else 0; /** Compute variance of type parameter `tparam' in types of all symbols `sym'. */ def varianceInSyms(syms: List[Symbol])(tparam: Symbol): int = - (Variances /: syms) ((v, sym) => v & varianceInSym(sym)(tparam)); + (VARIANCES /: syms) ((v, sym) => v & varianceInSym(sym)(tparam)); /** Compute variance of type parameter `tparam' in type of symbol `sym'. */ def varianceInSym(sym: Symbol)(tparam: Symbol): int = @@ -34,16 +34,16 @@ class Variances: Analyzer { /** Compute variance of type parameter `tparam' in all types `tps'. */ def varianceInTypes(tps: List[Type])(tparam: Symbol): int = - (Variances /: tps) ((v, tp) => v & varianceInType(tp)(tparam)); + (VARIANCES /: tps) ((v, tp) => v & varianceInType(tp)(tparam)); /** Compute variance of type parameter `tparam' in all type arguments - * `tps' which correspond to formal type parameters `tparams'. */ - def varianceInArgs(tps: List[Type], tparams: List[Symbol])(tparam: Symbol): int = { - var v: int = Variances; - for (val Pair(tp, tparam) <- tps zip tparams) { + * `tps' which correspond to formal type parameters `tparams1'. */ + def varianceInArgs(tps: List[Type], tparams1: List[Symbol])(tparam: Symbol): int = { + var v: int = VARIANCES; + for (val Pair(tp, tparam1) <- tps zip tparams1) { val v1 = varianceInType(tp)(tparam); - v = v & (if (tparam.hasFlag(COVARIANT)) v1 - else if (tparam.hasFlag(CONTRAVARIANT)) flip(v1) + v = v & (if (tparam1.hasFlag(COVARIANT)) v1 + else if (tparam1.hasFlag(CONTRAVARIANT)) flip(v1) else cut(v1)) } v @@ -52,7 +52,7 @@ class Variances: Analyzer { /** Compute variance of type parameter `tparam' in type `tp'. */ def varianceInType(tp: Type)(tparam: Symbol): int = tp match { case ErrorType | WildcardType | NoType | NoPrefix | ThisType(_) | ConstantType(_, _) => - Variances + VARIANCES case SingleType(pre, sym) => cut(varianceInType(pre)(tparam)) case TypeRef(pre, sym, args) => diff --git a/sources/scala/tools/nsc/util/CharArrayReader.scala b/sources/scala/tools/nsc/util/CharArrayReader.scala index 3cb70e6565..465a2e08fa 100644 --- a/sources/scala/tools/nsc/util/CharArrayReader.scala +++ b/sources/scala/tools/nsc/util/CharArrayReader.scala @@ -50,7 +50,7 @@ class CharArrayReader(buf: Array[char], start: int, startline: int, startcol: in def evenSlashPrefix: boolean = { var p = bp - 2; while (p >= 0 && buf(p) == '\\') p = p - 1; - p % 2 == 0 + (bp - p) % 2 == 0 } def udigit: int = { val d = digit2int(buf(bp), 16); diff --git a/sources/scala/util/automata/DetWordAutom.scala b/sources/scala/util/automata/DetWordAutom.scala index 58dc9ef937..12049e0012 100644 --- a/sources/scala/util/automata/DetWordAutom.scala +++ b/sources/scala/util/automata/DetWordAutom.scala @@ -34,7 +34,7 @@ abstract class DetWordAutom[T <: AnyRef] { sb.append(" finals="); var map = new scala.collection.immutable.ListMap[Int,Int]; var j = 0; while( j < nstates ) { - if(finals.isDefinedAt(j)) + if(j < finals.length) map = map.update(j,finals(j)); j = j + 1; } @@ -45,7 +45,7 @@ abstract class DetWordAutom[T <: AnyRef] { sb.append("->"); sb.append(delta(i).toString()); sb.append('\n'); - if(default.isDefinedAt(i)) { + if(i < default.length) { sb.append("_>"); sb.append(default(i).toString()); sb.append('\n'); diff --git a/sources/scala/util/automata/NondetWordAutom.scala b/sources/scala/util/automata/NondetWordAutom.scala index f17bb97150..a0a2757233 100644 --- a/sources/scala/util/automata/NondetWordAutom.scala +++ b/sources/scala/util/automata/NondetWordAutom.scala @@ -45,7 +45,7 @@ abstract class NondetWordAutom[T <: AnyRef] { /** returns a bitset with the next states for given state and label */ def next(q:Int, a: T): immutable.BitSet = { - delta(q).get(a).match { + delta(q).get(a) match { case Some(bs) => bs case _ => default(q) } diff --git a/sources/scala/util/automata/WordBerrySethi.scala b/sources/scala/util/automata/WordBerrySethi.scala index f99a66b084..fbc09872da 100644 --- a/sources/scala/util/automata/WordBerrySethi.scala +++ b/sources/scala/util/automata/WordBerrySethi.scala @@ -183,7 +183,7 @@ abstract class WordBerrySethi extends BaseBerrySethi { val finalsArr = new Array[Int](pos); { var k = 0; while(k < pos) { - finalsArr(k) = finals.get(k).match { + finalsArr(k) = finals.get(k) match { case Some(z) => z; case None => 0; // 0 == not final }; diff --git a/sources/scala/util/parsing/Parsers.scala b/sources/scala/util/parsing/Parsers.scala index 63c628fbc7..e0064f12e5 100755 --- a/sources/scala/util/parsing/Parsers.scala +++ b/sources/scala/util/parsing/Parsers.scala @@ -31,14 +31,14 @@ abstract class Parsers { } } - def ||| (def p: Parser[a]) = new Parser[a] { + def ||| (p: => Parser[a]) = new Parser[a] { def apply(in: inputType): Result = Parser.this.apply(in) match { case None => p(in) case s => s } } - def &&& [b](def p: Parser[b]): Parser[b] = + def &&& [b](p: => Parser[b]): Parser[b] = for (val _ <- this; val x <- p) yield x; } diff --git a/sources/scala/util/regexp/WordExp.scala b/sources/scala/util/regexp/WordExp.scala index 3c7b74b126..63817e0151 100644 --- a/sources/scala/util/regexp/WordExp.scala +++ b/sources/scala/util/regexp/WordExp.scala @@ -16,7 +16,7 @@ trait WordExp extends Base { var pos = -1; } - case class Wildcard extends RegExp { + case class Wildcard() extends RegExp { final val isNullable = false; var pos = -1; } diff --git a/sources/scala/xml/MetaData.scala b/sources/scala/xml/MetaData.scala index d6c0620e37..a7284b231f 100644 --- a/sources/scala/xml/MetaData.scala +++ b/sources/scala/xml/MetaData.scala @@ -40,7 +40,7 @@ abstract class MetaData extends Iterable[MetaData] with java.io.Serializable { /** deep equals method */ override def equals(that: Any) = { - that.match { + that match { case m:MetaData => var res = (this.length == m.length) && (this.hashCode() == m.hashCode()); val it = this.elements; diff --git a/sources/scala/xml/NodeBuffer.scala b/sources/scala/xml/NodeBuffer.scala index 93d3e9387c..23495f22b9 100644 --- a/sources/scala/xml/NodeBuffer.scala +++ b/sources/scala/xml/NodeBuffer.scala @@ -33,7 +33,7 @@ class NodeBuffer extends scala.collection.mutable.ArrayBuffer[Node] { * @param n */ def +(o: Any): NodeBuffer = { - o.match { + o match { case n:Node => super.+(n); case ns:Iterable[AnyRef] => val it = ns.elements; diff --git a/sources/scala/xml/Utility.scala b/sources/scala/xml/Utility.scala index afff9c8317..bf09a68448 100644 --- a/sources/scala/xml/Utility.scala +++ b/sources/scala/xml/Utility.scala @@ -16,7 +16,7 @@ import scala.collection.mutable; * Utility functions for processing instances of bound and not bound XML * classes, as well as escaping text nodes */ -object Utility with parsing.TokenTests { +object Utility extends AnyRef with parsing.TokenTests { def view(s: String): Text = Text(s); @@ -56,7 +56,7 @@ object Utility with parsing.TokenTests { def collectNamespaces(n: Node, set: mutable.Set[String]): Unit = { if( n.typeTag$ >= 0 ) { set += n.namespace; - for (val a <- n.attributes) a.match { + for (val a <- n.attributes) a match { case _:PrefixedAttribute => set += a.getNamespace(n) case _ => diff --git a/sources/scala/xml/dtd/Parser.scala b/sources/scala/xml/dtd/Parser.scala index 75ad2def5b..0f43d3b1fd 100644 --- a/sources/scala/xml/dtd/Parser.scala +++ b/sources/scala/xml/dtd/Parser.scala @@ -2,7 +2,7 @@ package scala.xml.dtd ; /** Parser for regexps (content models in DTD element declarations) */ -object Parser with Scanner { // a bit too permissive concerning #PCDATA +object Parser extends Scanner { // a bit too permissive concerning #PCDATA import ContentModel._ ; /** parses the argument to a regexp */ diff --git a/sources/scala/xml/dtd/Scanner.scala b/sources/scala/xml/dtd/Scanner.scala index 0d42e06b4a..4d531cc001 100644 --- a/sources/scala/xml/dtd/Scanner.scala +++ b/sources/scala/xml/dtd/Scanner.scala @@ -3,7 +3,7 @@ package scala.xml.dtd ; /** Scanner for regexps (content models in DTD element declarations) * todo: cleanup */ -class Scanner with Tokens with parsing.TokenTests { +class Scanner extends Tokens with parsing.TokenTests { // zzz constants zzz final val ENDCH = '\u0000'; diff --git a/sources/scala/xml/dtd/Tokens.scala b/sources/scala/xml/dtd/Tokens.scala index 589e3e4f13..27935c1d08 100644 --- a/sources/scala/xml/dtd/Tokens.scala +++ b/sources/scala/xml/dtd/Tokens.scala @@ -16,7 +16,7 @@ class Tokens { final val END = 10; final val S = 13; - final def token2string( i:int ):String = i.match { + final def token2string( i:int ):String = i match { case 0 => "#PCDATA"; case 1 => "NAME"; case 3 => "("; |