*** empty log message ***
git-svn-id: http://lampsvn.epfl.ch/svn-repos/scala/scala/trunk@2331 5e8d7ff9-d8ef-0310-90f0-a4852d11357a
This commit is contained in:
parent
541fc8dd62
commit
267fb5b923
|
@ -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
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
*/
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
package scala.runtime;
|
||||
|
||||
/** @meta class [?A] extends scala.Object;
|
||||
/** @meta class [?A] extends java.lang.Object;
|
||||
*/
|
||||
public class ResultOrException {
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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++) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
return templ;
|
||||
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 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;
|
||||
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
trait A extends scala.Object {}
|
||||
trait A extends java.lang.Object {}
|
||||
|
||||
object test {
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
trait A extends scala.Object {}
|
||||
trait A extends java.lang.Object {}
|
||||
|
||||
object test {
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue