*** 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:
odersky 2004-01-09 18:04:18 +00:00
parent 541fc8dd62
commit 267fb5b923
22 changed files with 137 additions and 122 deletions

View File

@ -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

View File

@ -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}

View File

@ -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

View File

@ -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);

View File

@ -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;
}
}

View File

@ -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;
*/

View File

@ -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;

View File

@ -10,7 +10,7 @@
package scala.runtime;
/** @meta class [?A] extends scala.Object;
/** @meta class [?A] extends java.lang.Object;
*/
public class ResultOrException {

View File

@ -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);
}
}

View File

@ -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(

View File

@ -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);
}
}

View File

@ -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++) {

View File

@ -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;
}

View File

@ -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);

View File

@ -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;

View File

@ -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");

View File

@ -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

View File

@ -1,4 +1,4 @@
trait A extends scala.Object {}
trait A extends java.lang.Object {}
object test {

View File

@ -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;

View File

@ -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

View File

@ -1,4 +1,4 @@
trait A extends scala.Object {}
trait A extends java.lang.Object {}
object test {

View File

@ -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;