summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--config/list/library.lst3
-rw-r--r--doc/reference/ScalaByExample.tex72
-rw-r--r--doc/reference/ScalaReference.tex29
-rw-r--r--sources/scala/Array.java2
-rw-r--r--sources/scala/Object.java24
-rw-r--r--sources/scala/Ref.java4
-rw-r--r--sources/scala/concurrent/MailBox.scala2
-rw-r--r--sources/scala/runtime/ResultOrException.java2
-rw-r--r--sources/scala/tools/scalac/ast/parser/Parser.scala22
-rw-r--r--sources/scalac/ast/TreeGen.java4
-rw-r--r--sources/scalac/ast/parser/Parser.java24
-rw-r--r--sources/scalac/symtab/Definitions.java2
-rw-r--r--sources/scalac/symtab/Type.java16
-rw-r--r--sources/scalac/symtab/classfile/CLRPackageParser.java1
-rw-r--r--sources/scalac/typechecker/RefCheck.java35
-rw-r--r--sources/scalac/util/Names.java3
-rw-r--r--test/files/neg/bug228.check2
-rw-r--r--test/files/pos/A.scala2
-rw-r--r--test/files/pos/MailBox.scala2
-rw-r--r--test/neg/bug228.check2
-rw-r--r--test/pos/A.scala2
-rw-r--r--test/pos/MailBox.scala2
22 files changed, 136 insertions, 121 deletions
diff --git a/config/list/library.lst b/config/list/library.lst
index f3d82effe4..f1ad7ba66e 100644
--- a/config/list/library.lst
+++ b/config/list/library.lst
@@ -37,12 +37,12 @@ MatchError.java
Monitor.scala
Nil.scala
None.scala
-Object.java
Option.scala
Ord.scala
PartialFunction.scala
Predef.scala
Ref.java
+ScalaObject.java
Seq.scala
Short.java
Some.scala
@@ -110,7 +110,6 @@ collection/immutable/Queue.scala
collection/immutable/Set.scala
collection/immutable/Stack.scala
-concurrent/LinkedList.scala
concurrent/Actor.scala
concurrent/MailBox.scala
concurrent/Channel.scala
diff --git a/doc/reference/ScalaByExample.tex b/doc/reference/ScalaByExample.tex
index 90c45145a3..786d83611d 100644
--- a/doc/reference/ScalaByExample.tex
+++ b/doc/reference/ScalaByExample.tex
@@ -1409,17 +1409,18 @@ Every class in Scala has a superclass which it extends.
only the root class \code{Object}, which does not have a superclass,
and which is indirectly extended by every other class. }
If a class
-does not mention a superclass in its definition, the root class
-\code{scala.Object} is implicitly assumed. For instance, class
+does not mention a superclass in its definition, the root type
+\code{scala.AnyRef} is implicitly assumed (for Java implementations,
+this type is an alias for \code{java.lang.Object}. For instance, class
\code{Rational} could equivalently be defined as
\begin{lstlisting}
-class Rational(n: int, d: int) extends Object {
+class Rational(n: int, d: int) extends AnyRef {
... // as before
}
\end{lstlisting}
A class inherits all members from its superclass. It may also redefine
(or: {\em override}) some inherited members. For instance, class
-\code{Object} defines
+\code{java.lang.Object} defines
a method
\code{toString} which returns a representation of the object as a string:
\begin{lstlisting}
@@ -1433,7 +1434,7 @@ forms a string consisting of the object's class name and a number. It
makes sense to redefine this method for objects that are rational
numbers:
\begin{lstlisting}
-class Rational(n: int, d: int) extends Object {
+class Rational(n: int, d: int) extends AnyRef {
... // as before
override def toString() = "" + numer + "/" + denom;
}
@@ -1444,10 +1445,10 @@ by an \code{override} modifier.
If class $A$ extends class $B$, then objects of type $A$ may be used
wherever objects of type $B$ are expected. We say in this case that
type $A$ {\em conforms} to type $B$. For instance, \code{Rational}
-conforms to \code{Object}, so it is legal to assign a \code{Rational}
-value to a variable of type \code{Object}:
+conforms to \code{AnyRef}, so it is legal to assign a \code{Rational}
+value to a variable of type \code{AnyRef}:
\begin{lstlisting}
-var x: Object = new Rational(1,2);
+var x: AnyRef = new Rational(1,2);
\end{lstlisting}
\paragraph{Parameterless Methods}
@@ -1462,7 +1463,7 @@ Unlike in Java, methods in Scala do not necessarily take a
parameter list. An example is the \code{square} method below. This
method is invoked by simply mentioning its name.
\begin{lstlisting}
-class Rational(n: int, d: int) extends Object {
+class Rational(n: int, d: int) extends AnyRef {
... // as before
def square = Rational(numer*numer, denom*denom);
}
@@ -1665,8 +1666,8 @@ For efficiency, the compiler usually represents values of type
\code{scala.Int} by 32 bit integers, values of type
\code{scala.Boolean} by Java's booleans, etc. But it converts these
specialized representations to objects when required, for instance
-when a primitive \code{int} value is passed to a function that with a
-parameter of type \code{Object}. Hence, the special representation of
+when a primitive \code{int} value is passed to a function with a
+parameter of type \code{AnyRef}. Hence, the special representation of
primitive values is just an optimization, it does not change the
meaning of a program.
@@ -2032,7 +2033,7 @@ Sum(Sum(Number(1), Number(2)), Number(3))
\item Case classes and case objects
implicity come with implementations of methods
\code{toString}, \code{equals} and \code{hashCode}, which override the
-methods with the same name in class \code{Object}. The implementation
+methods with the same name in class \code{AnyRef}. The implementation
of these methods takes in each case the structure of a member of a
case class into account. The \code{toString} method represents an
expression tree the way it was constructed. So,
@@ -2040,7 +2041,7 @@ expression tree the way it was constructed. So,
Sum(Sum(Number(1), Number(2)), Number(3))
\end{lstlisting}
would be converted to exactly that string, whereas the default
-implementation in class \code{Object} would return a string consisting
+implementation in class \code{AnyRef} would return a string consisting
of the outermost constructor name \code{Sum} and a number. The
\code{equals} methods treats two case members of a case class as equal
if they have been constructed with the same constructor and with
@@ -2052,7 +2053,7 @@ Sum(Number(1), Number(2)) == Sum(Number(1), Number(2))
\end{lstlisting}
will yield \code{true}. If \code{Sum} or \code{Number} were not case
classes, the same expression would be \code{false}, since the standard
-implementation of \code{equals} in class \code{Object} always treats
+implementation of \code{equals} in class \code{AnyRef} always treats
objects created by different constructor calls as being different.
The \code{hashCode} method follows the same principle as other two
methods. It computes a hash code from the case class constructor name
@@ -2435,9 +2436,9 @@ trait Ord[t <: Ord[t]]: t {
The combination of type parameters and subtyping poses some
interesting questions. For instance, should \code{Stack[String]} be a
-subtype of \code{Stack[Object]}? Intuitively, this seems OK, since a
+subtype of \code{Stack[AnyRef]}? Intuitively, this seems OK, since a
stack of \code{String}s is a special case of a stack of
-\code{Object}s. More generally, if \code{T} is a subtype of type \code{S}
+\code{AnyRef}s. More generally, if \code{T} is a subtype of type \code{S}
then \code{Stack[T]} should be a subtype of \code{Stack[S]}.
This property is called {\em co-variant} subtyping.
@@ -2568,9 +2569,9 @@ also have generalized the definition of \code{push}. Before, we were
required to push only elements with types that conform to the declared
element type of the stack. Now, we can push also elements of a
supertype of this type, but the type of the returned stack will change
-accordingly. For instance, we can now push an \code{Object} onto a
+accordingly. For instance, we can now push an \code{AnyRef} onto a
stack of \code{String}s, but the resulting stack will be a stack of
-\code{Object}s instead of a stack of \code{String}s!
+\code{AnyRef}s instead of a stack of \code{String}s!
In summary, one should not hesitate to add variance annotations to
your data structures, as this yields rich natural subtyping
@@ -2594,7 +2595,7 @@ which is a subtype of all other types. Hence, for co-variant stacks,
\code{T}. This makes it possible to use a single empty stack object
in user code. For instance:
\begin{lstlisting}
-val s = EmptyStack.push("abc").push(new Object());
+val s = EmptyStack.push("abc").push(new AnyRef());
\end{lstlisting}
Let's analyze the type assignment for this expression in detail. The
\code{EmptyStack} object is of type \code{Stack[All]}, which has a
@@ -2610,10 +2611,10 @@ should be instantiated to \code{String} in the application
push[b >: String](elem: b): Stack[b] .
\end{lstlisting}
The final part of the value definition above is the application of
-this method to \code{new Object()}. Local type inference will
+this method to \code{new AnyRef()}. Local type inference will
determine that the type parameter \code{b} should this time be
-instantiated to \code{Object}, with result type \code{Stack[Object]}.
-Hence, the type assigned to value \code{s} is \code{Stack[Object]}.
+instantiated to \code{AnyRef}, with result type \code{Stack[AnyRef]}.
+Hence, the type assigned to value \code{s} is \code{Stack[AnyRef]}.
Besides \code{scala.All}, which is a subtype of every other type,
there is also the type \code{scala.AllRef}, which is a subtype of
@@ -2733,12 +2734,12 @@ shorthand for \code{a.apply(i)}.
Functions are an example where a contra-variant type parameter
declaration is useful. For example, consider the following code:
\begin{lstlisting}
-val f: (Object => int) = x => x.hashCode();
+val f: (AnyRef => int) = x => x.hashCode();
val g: (String => int) = f
g("abc")
\end{lstlisting}
It's sound to bind the value \code{g} of type \code{String => int} to
-\code{f}, which is of type \code{Object => int}. Indeed, all one can
+\code{f}, which is of type \code{AnyRef => int}. Indeed, all one can
do with function of type \code{String => int} is pass it a string in
order to obtain an integer. Clearly, the same works for function
\code{f}: If we pass it a string (or any other object), we obtain an
@@ -5714,7 +5715,7 @@ TypeScheme(List(TyVar("a"), TyVar("b")), Arrow(Tyvar("a"), Tyvar("b"))) .
\end{lstlisting}
The class definition of type schemes does not carry an extends
clause; this means that type schemes extend directly class
-\code{Object}. Even though there is only one possible way to
+\code{AnyRef}. Even though there is only one possible way to
construct a type scheme, a case class representation was chosen
since it offers convenient ways to decompose an instance of this type into its
parts.
@@ -6101,7 +6102,7 @@ time, only one thread can execute a \code{synchronized} argument of a
given monitor.
Threads can suspend inside a monitor by waiting on a signal. The
-standard \code{java.lang.Object} class offers for this prupose methods
+standard \code{java.lang.Object} class offers for this purpose methods
\code{send} and \code{notify}. Threads that call the \code{wait}
method wait until a \code{notify} method of the same object is called
subsequently by some other thread. Calls to \code{notify} with no
@@ -6629,7 +6630,7 @@ one for sent but unconsumed messages, the other for waiting receivers.
if (r1 != null) {
r.next = r1.next; r1.elem.msg = msg; r1.elem.notify;
} else {
- lastSent = lastSent.insert(msg);
+ lastSent = insert(lastSent, msg);
}
}
\end{lstlisting}
@@ -6646,7 +6647,7 @@ Otherwise, the message is appended to the linked list of sent messages.
if (s1 != null) {
s.next = s1.next; s1.elem
} else {
- val r = lastReceiver.insert(new Receiver {
+ val r = insert(lastReceiver, new Receiver {
def isDefined(msg: Any) = f.isDefinedAt(msg);
});
lastReceiver = r;
@@ -6663,8 +6664,16 @@ was not yet consumed. If yes, the thread continues immediately by
applying \code{f} to the message. Otherwise, a new receiver is created
and linked into the \code{receivers} list, and the thread waits for a
notification on this receiver. Once the thread is woken up again, it
-continues by applying \code{f} to the message that was stored in the receiver.
-
+continues by applying \code{f} to the message that was stored in the
+receiver. The insert method on linked lists is defined as follows.
+\begin{lstlisting}
+ def insert(l: LinkedList[a], x: a): LinkedList[a] = {
+ l.next = new LinkedList[a];
+ l.next.elem = x;
+ l.next.next = l.next;
+ l
+ }
+\end{lstlisting}
The mailbox class also offers a method \code{receiveWithin}
which blocks for only a specified maximal amount of time. If no
message is received within the specified time interval (given in
@@ -6681,7 +6690,7 @@ with the special \code{TIMEOUT} message. The implementation of
if (s1 != null) {
s.next = s1.next; s1.elem
} else {
- val r = lastReceiver.insert(new Receiver {
+ val r = insert(lastReceiver, new Receiver {
def isDefined(msg: Any) = f.isDefinedAt(msg);
});
lastReceiver = r;
@@ -6877,6 +6886,7 @@ class Bidder (auction: Process, minBid: int, maxBid: int)
def transferPayment(seller: Process, amount: int)
}
\end{lstlisting}
+}
\bibliographystyle{alpha}
\bibliography{Scala}
diff --git a/doc/reference/ScalaReference.tex b/doc/reference/ScalaReference.tex
index c62e0f04b4..5c106a3e58 100644
--- a/doc/reference/ScalaReference.tex
+++ b/doc/reference/ScalaReference.tex
@@ -1194,7 +1194,7 @@ type Abs = Comparable[Abs]; // recursive type alias
type S <: T; // S, T are bounded by themselves.
type T <: S;
-type T <: Object with T; // T is abstract, may not be part of
+type T <: AnyRef with T; // T is abstract, may not be part of
// compound type
type T >: Comparable[T.That]; // Cannot select from T.
@@ -1310,7 +1310,7 @@ class P[a, b] {
}\end{lstlisting}
With this variance annotation, elements
of type $P$ subtype covariantly with respect to their arguments.
-For instance, ~\lstinline@P[IOExeption, String] <: P[Throwable, Object]@.
+For instance, ~\lstinline@P[IOExeption, String] <: P[Throwable, AnyRef]@.
If we make the elements of $P$ mutable,
the variance annotation becomes illegal.
@@ -1348,7 +1348,7 @@ trait OutputChannel[-a] {
}
\end{lstlisting}
With that annotation, we have that
-\lstinline@OutputChannel[Object]@ conforms to \lstinline@OutputChannel[String]@.
+\lstinline@OutputChannel[AnyRef]@ conforms to \lstinline@OutputChannel[String]@.
That is, a
channel on which one can write any object can substitute for a channel
on which one can write only strings.
@@ -1965,7 +1965,7 @@ $sc$ with $mc_1$ with $\ldots$ with $mc_n$ { $stats$ }
which defines the base classes, behavior and initial state of objects of
the class. The extends clause ~\lstinline@extends $sc$ with $\ldots$ with $mc_n$@~
can be omitted, in which case
-~\lstinline@extends scala.Object@~ is assumed. The class body
+~\lstinline@extends scala.AnyRef@~ is assumed. The class body
~\lstinline@{$stats\,$}@~ may also be omitted, in which case the empty body
\lstinline@{}@ is assumed.
\end{itemize}
@@ -2077,10 +2077,10 @@ $x$ that defines $x$ to be an alias of the parameter.
%parameters.
Every case class implicitly overrides some method definitions of class
-\lstinline@scala.Object@ (\sref{sec:cls-object}) unless a definition of the same
+\lstinline@scala.AnyRef@ (\sref{sec:cls-object}) unless a definition of the same
method is already given in the case class itself or a concrete
definition of the same method is given in some base class of the case
-class different from \code{Object}. In particular:
+class different from \code{AnyRef}. In particular:
\begin{itemize}
\item[] Method ~\lstinline@equals: (Any)boolean@~ is structural equality, where two
instances are equal if they belong to the same class and
@@ -2211,7 +2211,7 @@ $sc$ with $mc_1$ with $\ldots$ with $mc_n$ { $stats$ }
which defines the base classes, behavior and initial state of $m$.
The extends clause ~\lstinline@extends $sc$ with $\ldots$ with $mc_n$@~
can be omitted, in which case
-~\lstinline@extends scala.Object@~ is assumed. The class body
+~\lstinline@extends scala.AnyRef@~ is assumed. The class body
~\lstinline@{$stats\,$}@~ may also be omitted, in which case the empty body
\lstinline@{}@ is assumed.
\end{itemize}
@@ -2711,7 +2711,7 @@ object, which is initialized by evaluating the expression template.
\example Consider the class
\begin{lstlisting}
abstract class C {
- type T; val x: T; def f(x: T): Object
+ type T; val x: T; def f(x: T): AnyRef
}
\end{lstlisting}
and the instance creation expression
@@ -3637,11 +3637,12 @@ indirectly from this class. Class \code{Any} has two direct
subclasses: \code{AnyRef} and\code{AnyVal}.
The subclass \code{AnyRef} represents all values which are represented
-as objects in the underlying host system. A subclass of \code{AnyRef}
-is class \code{Object}. Every user-defined Scala class inherits
-directly or indirectly from this class. Classes written in other
-languages still inherit from \code{scala.AnyRef}, but not necessarily
-from \code{scala.Object}.
+as objects in the underlying host system. Every user-defined Scala
+class inherits directly or indirectly from this class. Furthermore,
+every user-defined Scala class also inherits the trait
+\code{scala.ScalaObject}. Classes written in other languages still
+inherit from \code{scala.AnyRef}, but not from
+\code{scala.ScalaObject}.
The class \code{AnyVal} has a fixed number subclasses, which describe
values which are not implemented as objects in the underlying host
@@ -3695,7 +3696,7 @@ abstract class Any {
}
final class AnyVal extends Any;
class AnyRef extends Any;
-class Object extends AnyRef;
+trait ScalaObject extends AnyRef;
\end{lstlisting}
The type cast operation \verb@asInstanceOf@ has a special meaning (not
diff --git a/sources/scala/Array.java b/sources/scala/Array.java
index 4cd1deee97..6a139ffd98 100644
--- a/sources/scala/Array.java
+++ b/sources/scala/Array.java
@@ -14,7 +14,7 @@ package scala;
/** @meta class [?T] extends scala.Function1[scala.Int, ?T];
*/
public abstract class Array
- extends scala.Object
+ extends java.lang.Object
implements Function1, Cloneable, java.io.Serializable {
/** @meta constr (scala.Int);
diff --git a/sources/scala/Object.java b/sources/scala/Object.java
deleted file mode 100644
index 4a44ad0caa..0000000000
--- a/sources/scala/Object.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2002, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-// $OldId: Object.java,v 1.7 2002/03/12 13:32:46 zenger Exp $
-// $Id$
-
-package scala;
-
-/** @meta class extends scala.AnyRef;
- */
-public class Object {
-
- /** This method is needed for optimizing pattern matching expressions
- * which match on constructors of case classes.
- */
- public int $tag() {
- return 0;
- }
-}
diff --git a/sources/scala/Ref.java b/sources/scala/Ref.java
index 5635e433a5..4f45a28569 100644
--- a/sources/scala/Ref.java
+++ b/sources/scala/Ref.java
@@ -11,9 +11,9 @@
package scala;
-/** @meta class [?T] extends scala.Object;
+/** @meta class [?T] extends java.lang.Object;
*/
-public class Ref extends scala.Object {
+public class Ref extends java.lang.Object {
/** @meta field ?T;
*/
diff --git a/sources/scala/concurrent/MailBox.scala b/sources/scala/concurrent/MailBox.scala
index d8c59c774b..f173a2912f 100644
--- a/sources/scala/concurrent/MailBox.scala
+++ b/sources/scala/concurrent/MailBox.scala
@@ -1,7 +1,7 @@
package scala.concurrent;
//class MailBox with Monitor with LinkedListQueueCreator {
-class MailBox with Monitor with ListQueueCreator {
+class MailBox extends Monitor with ListQueueCreator {
type Message = AnyRef;
diff --git a/sources/scala/runtime/ResultOrException.java b/sources/scala/runtime/ResultOrException.java
index 870ed2ce50..4961c785d7 100644
--- a/sources/scala/runtime/ResultOrException.java
+++ b/sources/scala/runtime/ResultOrException.java
@@ -10,7 +10,7 @@
package scala.runtime;
-/** @meta class [?A] extends scala.Object;
+/** @meta class [?A] extends java.lang.Object;
*/
public class ResultOrException {
diff --git a/sources/scala/tools/scalac/ast/parser/Parser.scala b/sources/scala/tools/scalac/ast/parser/Parser.scala
index 07414ae936..830c507e44 100644
--- a/sources/scala/tools/scalac/ast/parser/Parser.scala
+++ b/sources/scala/tools/scalac/ast/parser/Parser.scala
@@ -247,9 +247,13 @@ class Parser(unit: Unit) {
def scalaBooleanDot(pos: int, name: Name): Tree =
make.Select(pos, scalaDot(pos, Names.Boolean), name);
+ def scalaAnyRefConstr(pos: int): Tree =
+ make.Apply(
+ pos, scalaDot(pos, Names.AnyRef.toTypeName()), Tree.EMPTY_ARRAY);
+
def scalaObjectConstr(pos: int): Tree =
make.Apply(
- pos, scalaDot(pos, Names.Object.toTypeName()), Tree.EMPTY_ARRAY);
+ pos, scalaDot(pos, Names.ScalaObject.toTypeName()), Tree.EMPTY_ARRAY);
/** Create tree for for-comprehension <for (enums) do body> or
* <for (enums) yield body> where mapName and flatmapName are chosen
@@ -1737,22 +1741,24 @@ class Parser(unit: Unit) {
*/
def classTemplate(): Tree$Template = {
val pos = s.pos;
+ val parents = new myTreeList();
if (s.token == EXTENDS) {
s.nextToken();
- template()
- } else if (s.token == WITH) {
+ parents.append(constr());
+ } else {
+ parents.append(scalaAnyRefConstr(pos));
+ }
+ parents.append(scalaObjectConstr(pos));
+ if (s.token == WITH) {
s.nextToken();
- val parents = new myTreeList();
- parents.append(scalaObjectConstr(pos));
template(parents)
} else if (s.token == LBRACE) {
- make.Template(
- pos, NewArray.Tree(scalaObjectConstr(pos)), templateBody());
+ make.Template(pos, parents.toArray(), templateBody());
} else {
if (!(s.token == SEMI || s.token == COMMA || s.token == RBRACE))
syntaxError("`extends' or `{' expected", true);
make.Template(
- pos, NewArray.Tree(scalaObjectConstr(pos)), Tree.EMPTY_ARRAY);
+ pos, parents.toArray(), Tree.EMPTY_ARRAY);
}
}
diff --git a/sources/scalac/ast/TreeGen.java b/sources/scalac/ast/TreeGen.java
index 1c49620c0f..f9c4e9399d 100644
--- a/sources/scalac/ast/TreeGen.java
+++ b/sources/scalac/ast/TreeGen.java
@@ -1165,7 +1165,7 @@ public class TreeGen implements Kinds, Modifiers, TypeTags {
argtypes[i] = params[i].type();
}
Type[] parentTypes = {
- definitions.OBJECT_TYPE(),
+ definitions.ANYREF_TYPE(),
definitions.FUNCTION_TYPE(argtypes, restype) };
ClassSymbol clazz = new ClassSymbol(
pos, Names.ANON_CLASS_NAME.toTypeName(), owner, 0);
@@ -1196,7 +1196,7 @@ public class TreeGen implements Kinds, Modifiers, TypeTags {
ClassSymbol clazz = new ClassSymbol(
pos, Names.ANON_CLASS_NAME.toTypeName(), owner, 0);
Type[] parentTypes = {
- definitions.OBJECT_TYPE(),
+ definitions.ANYREF_TYPE(),
definitions.PARTIALFUNCTION_TYPE(pattype, restype)};
clazz.setInfo(Type.compoundType(parentTypes, new Scope(), clazz));
clazz.allConstructors().setInfo(
diff --git a/sources/scalac/ast/parser/Parser.java b/sources/scalac/ast/parser/Parser.java
index 5b698764ad..d98324c970 100644
--- a/sources/scalac/ast/parser/Parser.java
+++ b/sources/scalac/ast/parser/Parser.java
@@ -275,9 +275,14 @@ public class Parser implements Tokens {
return make.Select(pos, scalaXmlDot(pos, Names.nobinding), name);
}
+ Tree scalaAnyRefConstr(int pos) {
+ return make.Apply(
+ pos, scalaDot(pos, Names.AnyRef.toTypeName()), Tree.EMPTY_ARRAY);
+ }
+
Tree scalaObjectConstr(int pos) {
return make.Apply(
- pos, scalaDot(pos, Names.Object.toTypeName()), Tree.EMPTY_ARRAY);
+ pos, scalaDot(pos, Names.ScalaObject.toTypeName()), Tree.EMPTY_ARRAY);
}
/** Create tree for for-comprehension <for (enums) do body> or
@@ -1885,22 +1890,25 @@ public class Parser implements Tokens {
*/
Template classTemplate() {
int pos = s.pos;
+ TreeList parents = new TreeList();
if (s.token == EXTENDS) {
s.nextToken();
- return template();
- } else if (s.token == WITH) {
+ parents.append(constr());
+ } else {
+ parents.append(scalaAnyRefConstr(pos));
+ }
+ parents.append(scalaObjectConstr(pos));
+ if (s.token == WITH) {
s.nextToken();
- TreeList parents = new TreeList();
- parents.append(scalaObjectConstr(pos));
- return template(parents);
+ return template(parents);
} else if (s.token == LBRACE) {
return (Template)make.Template(
- pos, new Tree[]{scalaObjectConstr(pos)}, templateBody());
+ pos, parents.toArray(), templateBody());
} else {
if (!(s.token == SEMI || s.token == COMMA || s.token == RBRACE))
syntaxError("`extends' or `{' expected", true);
return (Template)make.Template(
- pos, new Tree[]{scalaObjectConstr(pos)}, Tree.EMPTY_ARRAY);
+ pos, parents.toArray(), Tree.EMPTY_ARRAY);
}
}
diff --git a/sources/scalac/symtab/Definitions.java b/sources/scalac/symtab/Definitions.java
index 79db92a581..8c59358a5e 100644
--- a/sources/scalac/symtab/Definitions.java
+++ b/sources/scalac/symtab/Definitions.java
@@ -491,7 +491,7 @@ public class Definitions {
DOUBLE_CLASS = getClass(Names.scala_Double);
// the scala reference classes
- OBJECT_CLASS = getClass(Names.scala_Object);
+ OBJECT_CLASS = getClass(Names.scala_ScalaObject);
STRING_CLASS = newAlias(SCALA_PACKAGE, Names.String, 0);
REF_CLASS = getClass(Names.scala_Ref);
for (int i = 1; i < TUPLE_COUNT; i++) {
diff --git a/sources/scalac/symtab/Type.java b/sources/scalac/symtab/Type.java
index f0d4a7ce1f..b8b03a9ffb 100644
--- a/sources/scalac/symtab/Type.java
+++ b/sources/scalac/symtab/Type.java
@@ -754,7 +754,8 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags {
}
/** Is this type of the form scala.FunctionN[T_1, ..., T_n, +T] or
- * scala.Object with scala.FunctionN[T_1, ..., T_n, +T]?
+ * scala.AnyRef with scala.FunctionN[T_1, ..., T_n, +T] or
+ * java.lang.Object with scala.FunctionN[T_1, ..., T_n, +T]?
*/
public boolean isFunctionType() {
switch (this) {
@@ -764,7 +765,8 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags {
case CompoundType(Type[] parents, Scope members):
return members.isEmpty() &&
parents.length == 2 &&
- parents[0].symbol().fullName() == Names.scala_Object &&
+ (parents[0].symbol().fullName() == Names.java_lang_Object ||
+ parents[0].symbol().fullName() == Names.scala_AnyRef) &&
parents[1].isFunctionType();
}
return false;
@@ -850,13 +852,17 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags {
// take precedence over abstract ones.
int i = parts.length;
sym = Symbol.NONE;
- while (i > 0 && (sym.kind == NONE || (sym.flags & DEFERRED) != 0)) {
+ while (i > 0) {
i--;
Symbol sym1 = parts[i].lookupNonPrivate(name);
if (sym1.kind != NONE &&
(sym1.flags & PRIVATE) == 0 &&
- (sym.kind == NONE ||
- (sym1.flags & DEFERRED) == 0 ||
+ (sym.kind == NONE
+ ||
+ (sym.flags & DEFERRED) != 0 &&
+ (sym1.flags & DEFERRED) == 0
+ ||
+ (sym.flags & DEFERRED) == (sym1.flags & DEFERRED) &&
sym1.owner().isSubClass(sym.owner())))
sym = sym1;
}
diff --git a/sources/scalac/symtab/classfile/CLRPackageParser.java b/sources/scalac/symtab/classfile/CLRPackageParser.java
index bf2e6971e2..3197389979 100644
--- a/sources/scalac/symtab/classfile/CLRPackageParser.java
+++ b/sources/scalac/symtab/classfile/CLRPackageParser.java
@@ -246,7 +246,6 @@ public class CLRPackageParser extends MetadataParser {
clazz.allConstructors().setInfo(completer.staticsParser(clazz));
clazz.module().setInfo(completer.staticsParser(clazz));
members.enter(clazz);
- // ATTENTION: only if not scala.Object!
Scope.Entry e = members.lookupEntry(clazz.module().name);
if (e != Scope.Entry.NONE)
members.unlink(e);
diff --git a/sources/scalac/typechecker/RefCheck.java b/sources/scalac/typechecker/RefCheck.java
index afe0e0df7a..99603befd9 100644
--- a/sources/scalac/typechecker/RefCheck.java
+++ b/sources/scalac/typechecker/RefCheck.java
@@ -726,12 +726,16 @@ public class RefCheck extends Transformer implements Modifiers, Kinds {
}
private Tree tagMethod(ClassSymbol clazz) {
- Symbol tagSym = new TermSymbol(
- clazz.pos, Names.tag, clazz,
- clazz.isSubClass(defs.OBJECT_CLASS) ? OVERRIDE : 0)
- .setInfo(Type.MethodType(Symbol.EMPTY_ARRAY, defs.INT_TYPE()));
- clazz.info().members().enter(tagSym);
- return gen.DefDef(tagSym, gen.mkIntLit(clazz.pos, clazz.tag()));
+ Symbol tagSym = new TermSymbol(
+ clazz.pos, Names.tag, clazz,
+ clazz.isSubClass(defs.OBJECT_CLASS) ? OVERRIDE : 0)
+ .setInfo(Type.MethodType(Symbol.EMPTY_ARRAY, defs.INT_TYPE()));
+ clazz.info().members().enter(tagSym);
+ return gen.DefDef(
+ tagSym,
+ gen.mkIntLit(
+ clazz.pos,
+ clazz.isCaseClass() ? clazz.tag() : 0));
}
private Tree hashCodeMethod(ClassSymbol clazz) {
@@ -772,18 +776,23 @@ public class RefCheck extends Transformer implements Modifiers, Kinds {
}
// where
- private Template addCaseMethods(Template templ, Symbol sym) {
- if (sym.kind == CLASS && (sym.flags & CASE) != 0) {
- Tree[] body1 = addCaseMethods(templ.body, (ClassSymbol) sym);
- return copy.Template(templ, templ.parents, body1);
+ private Template addCaseMethods(Template templ, ClassSymbol sym) {
+ Tree[] body1;
+ if (sym.isCaseClass()) {
+ body1 = addCaseMethods(templ.body, sym);
+ } else {
+ body1 = new Tree[templ.body.length + 1];
+ System.arraycopy(templ.body, 0, body1, 0, templ.body.length);
+ body1[templ.body.length] = tagMethod(sym);
}
- return templ;
+ return copy.Template(templ, templ.parents, body1);
}
private Tree[] addCaseMethods(Tree[] stats, ClassSymbol clazz) {
TreeList ts = new TreeList();
- if (!hasImplementation(clazz, Names.toString))
+ if (!hasImplementation(clazz, Names.toString)) {
ts.append(toStringMethod(clazz));
+ }
if (!hasImplementation(clazz, Names.equals))
ts.append(equalsMethod(clazz));
if (!hasImplementation(clazz, Names.hashCode))
@@ -934,7 +943,7 @@ public class RefCheck extends Transformer implements Modifiers, Kinds {
validateVariance(sym, sym.info(), CoVariance);
validateVariance(sym, sym.typeOfThis(), CoVariance);
Tree tree1 = super.transform(
- copy.ClassDef(tree, tree.symbol(), tparams, vparams, tpe, addCaseMethods(templ, tree.symbol())));
+ copy.ClassDef(tree, tree.symbol(), tparams, vparams, tpe, addCaseMethods(templ, (ClassSymbol) tree.symbol())));
enclClass = enclClassPrev;
return tree1;
diff --git a/sources/scalac/util/Names.java b/sources/scalac/util/Names.java
index 912f866ada..5b284ca8e3 100644
--- a/sources/scalac/util/Names.java
+++ b/sources/scalac/util/Names.java
@@ -112,6 +112,7 @@ public class Names {
public static final Name Object = Name.fromString("Object");
public static final Name PartialFunction = Name.fromString("PartialFunction");
public static final Name Predef = Name.fromString("Predef");
+ public static final Name ScalaObject = Name.fromString("ScalaObject");
public static final Name ScalaRunTime = Name.fromString("ScalaRunTime");
public static final Name Seq = Name.fromString("Seq");
public static final Name Short = Name.fromString("Short");
@@ -181,7 +182,7 @@ public class Names {
public static final Name scala_Long = Name.fromString("scala.Long");
public static final Name scala_MatchError = Name.fromString("scala.MatchError");
public static final Name scala_Nil = Name.fromString("scala.Nil");
- public static final Name scala_Object = Name.fromString("scala.Object");
+ public static final Name scala_ScalaObject = Name.fromString("scala.ScalaObject");
public static final Name scala_PartialFunction = Name.fromString("scala.PartialFunction");
public static final Name scala_Predef = Name.fromString("scala.Predef");
public static final Name scala_Ref = Name.fromString("scala.Ref");
diff --git a/test/files/neg/bug228.check b/test/files/neg/bug228.check
index 0dc891bced..a099f9fa0e 100644
--- a/test/files/neg/bug228.check
+++ b/test/files/neg/bug228.check
@@ -1,4 +1,4 @@
-/home/odersky/scala/test/pos/bug228.scala:11: constructor java.lang.reflect.AccessibleObject cannot be accessed in Foo
+bug228.scala:11: constructor java.lang.reflect.AccessibleObject cannot be accessed in Foo
val o = new AccessibleObject;
^
one error found
diff --git a/test/files/pos/A.scala b/test/files/pos/A.scala
index 513c8bed45..fc50379d88 100644
--- a/test/files/pos/A.scala
+++ b/test/files/pos/A.scala
@@ -1,4 +1,4 @@
-trait A extends scala.Object {}
+trait A extends java.lang.Object {}
object test {
diff --git a/test/files/pos/MailBox.scala b/test/files/pos/MailBox.scala
index e081735911..9094b73399 100644
--- a/test/files/pos/MailBox.scala
+++ b/test/files/pos/MailBox.scala
@@ -8,7 +8,7 @@ class MailBox with Monitor {
var next: LinkedList[a] = null;
}
- def insert(l: LinkedList[a], x: a): LinkedList[a] {
+ def insert[a](l: LinkedList[a], x: a): LinkedList[a] = {
l.next = new LinkedList[a];
l.next.elem = x;
l.next.next = l.next;
diff --git a/test/neg/bug228.check b/test/neg/bug228.check
index 0dc891bced..a099f9fa0e 100644
--- a/test/neg/bug228.check
+++ b/test/neg/bug228.check
@@ -1,4 +1,4 @@
-/home/odersky/scala/test/pos/bug228.scala:11: constructor java.lang.reflect.AccessibleObject cannot be accessed in Foo
+bug228.scala:11: constructor java.lang.reflect.AccessibleObject cannot be accessed in Foo
val o = new AccessibleObject;
^
one error found
diff --git a/test/pos/A.scala b/test/pos/A.scala
index 513c8bed45..fc50379d88 100644
--- a/test/pos/A.scala
+++ b/test/pos/A.scala
@@ -1,4 +1,4 @@
-trait A extends scala.Object {}
+trait A extends java.lang.Object {}
object test {
diff --git a/test/pos/MailBox.scala b/test/pos/MailBox.scala
index e081735911..9094b73399 100644
--- a/test/pos/MailBox.scala
+++ b/test/pos/MailBox.scala
@@ -8,7 +8,7 @@ class MailBox with Monitor {
var next: LinkedList[a] = null;
}
- def insert(l: LinkedList[a], x: a): LinkedList[a] {
+ def insert[a](l: LinkedList[a], x: a): LinkedList[a] = {
l.next = new LinkedList[a];
l.next.elem = x;
l.next.next = l.next;