summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sources/examples/buffer1.scala16
-rw-r--r--sources/scala/ConsStreamClass.scala13
-rw-r--r--sources/scala/EmptyStream.scala9
-rw-r--r--sources/scala/Except.scala10
-rw-r--r--sources/scala/LinkedList.scala2
-rw-r--r--sources/scala/Predef.scala15
-rw-r--r--sources/scala/concurrent/MailBox.scala61
-rw-r--r--sources/scalac/ast/printer/TextTreePrinter.java1
-rw-r--r--sources/scalac/symtab/Type.java33
-rw-r--r--sources/scalac/typechecker/Analyzer.java42
-rw-r--r--sources/scalac/typechecker/ImportList.java14
-rw-r--r--test/files/pos/S1.scala2
-rw-r--r--test/files/pos/cls1.scala4
-rw-r--r--test/pos/S1.scala2
-rw-r--r--test/pos/cls1.scala4
15 files changed, 161 insertions, 67 deletions
diff --git a/sources/examples/buffer1.scala b/sources/examples/buffer1.scala
new file mode 100644
index 0000000000..40be8431be
--- /dev/null
+++ b/sources/examples/buffer1.scala
@@ -0,0 +1,16 @@
+package examples;
+
+import scala.concurrent._;
+
+class OnePlaceBuffer() {
+ private val m = new MailBox(); // An internal mailbox
+ private case class Empty(), Full(x: Int); // Types of messages we deal with
+
+ m send Empty(); // Initialization
+
+ def write(x: Int): Unit =
+ m receive { case Empty() => m send Full(x) }
+
+ def read: Int =
+ m receive { case Full(x) => m send Empty() ; x }
+}
diff --git a/sources/scala/ConsStreamClass.scala b/sources/scala/ConsStreamClass.scala
deleted file mode 100644
index a8f6d46e73..0000000000
--- a/sources/scala/ConsStreamClass.scala
+++ /dev/null
@@ -1,13 +0,0 @@
-package scala;
-
-final class ConsStreamClass[b](hd: b, tl: () => Stream[b]) extends Stream[b] with {
- def isEmpty = False;
- def head = hd;
- private var tlVal: Stream[b] = null;
- private var tlDefined: Boolean = False;
- def tail: Stream[b] = {
- if (!tlDefined) { tlVal = tl(); tlDefined = True; }
- tlVal
- }
- override def toString(): String = "ConsStream(" + hd + ", ?)";
-}
diff --git a/sources/scala/EmptyStream.scala b/sources/scala/EmptyStream.scala
deleted file mode 100644
index de7f0e025e..0000000000
--- a/sources/scala/EmptyStream.scala
+++ /dev/null
@@ -1,9 +0,0 @@
-package scala;
-
-final class EmptyStream[c]() extends Stream[c] with {
- def isEmpty = True;
- def head: c = error("head of empty stream");
- def tail: Stream[c] = error("tail of empty stream");
- override def toString(): String = "EmptyStream";
-}
-
diff --git a/sources/scala/Except.scala b/sources/scala/Except.scala
new file mode 100644
index 0000000000..123fe4dc07
--- /dev/null
+++ b/sources/scala/Except.scala
@@ -0,0 +1,10 @@
+package scala;
+
+class Except[a](r: scala.runtime.ResultOrException[a]) {
+ def except(handler: PartialFunction[Throwable, a]): a =
+ if (r.exc == null) r.result as a
+ else if (handler isDefinedAt r.exc) handler(r.exc)
+ else r.exc.throw;
+ def finally(def handler: Unit): a =
+ if (r.exc == null) r.result as a else { handler; r.exc.throw }
+}
diff --git a/sources/scala/LinkedList.scala b/sources/scala/LinkedList.scala
index e2a71c979e..064fe011c2 100644
--- a/sources/scala/LinkedList.scala
+++ b/sources/scala/LinkedList.scala
@@ -4,7 +4,7 @@ class LinkedList[a]() {
var elem: a = _;
var next: LinkedList[a] = null;
def append(x: a): LinkedList[a] = {
- val l = new LinkedList();
+ val l = new LinkedList[a]();
l.elem = x;
this.next = l;
l
diff --git a/sources/scala/Predef.scala b/sources/scala/Predef.scala
index 56cd07ed60..456847e08e 100644
--- a/sources/scala/Predef.scala
+++ b/sources/scala/Predef.scala
@@ -7,12 +7,7 @@ module Predef {
val List = scala.List;
- def List[a](x: a*): List[a] = {
- def mkList(elems: Iterator[a]): List[a] =
- if (elems.hasNext) elems.next :: mkList(elems)
- else Nil();
- mkList(x.elements);
- }
+ def List[a](x: a*): List[a] = x as List[a];
def error[err](x: String):err = new java.lang.RuntimeException(x).throw;
@@ -48,14 +43,6 @@ module Predef {
def Triple[a, b, c](x: a, y: b, z: c) = Tuple3(x, y, z);
}
-class Except[a](r: scala.runtime.ResultOrException[a]) {
- def except(handler: PartialFunction[Throwable, a]): a =
- if (r.exc == null) r.result as a
- else if (handler isDefinedAt r.exc) handler(r.exc)
- else r.exc.throw;
- def finally(def handler: Unit): a =
- if (r.exc == null) r.result as a else { handler; r.exc.throw }
-}
diff --git a/sources/scala/concurrent/MailBox.scala b/sources/scala/concurrent/MailBox.scala
new file mode 100644
index 0000000000..2e74d8e1fa
--- /dev/null
+++ b/sources/scala/concurrent/MailBox.scala
@@ -0,0 +1,61 @@
+package scala.concurrent;
+
+class MailBox() extends Monitor() {
+
+ type Message = AnyRef;
+
+ private abstract class Receiver() extends Monitor() {
+ type t;
+ val receiver: PartialFunction[Message, t];
+ var msg: Message = _;
+ def receive(): t = synchronized {
+ if (msg != null) wait();
+ receiver(msg)
+ }
+ def receiveWithin(msec: Long): t = synchronized {
+ if (msg != null) wait(msec);
+ receiver(if (msg != null) msg else TIMEOUT)
+ }
+ }
+
+ private val sent = new LinkedList[Message]();
+ private var lastSent = sent;
+ private var receivers = new LinkedList[Receiver]();
+ private var lastReceiver = receivers;
+
+ def send(msg: Message): Unit = synchronized {
+ var rs = receivers, rs1 = rs.next;
+ while (rs1 != null && !rs1.elem.receiver.isDefinedAt(msg)) {
+ rs = rs1; rs1 = rs1.next;
+ }
+ if (rs1 != null) {
+ rs.next = rs1.next; rs1.elem.msg = msg; rs1.elem.notify();
+ } else {
+ lastSent = lastSent.append(msg)
+ }
+ }
+
+ def scanSentMsgs[a](r: Receiver with { type t = a }): Unit = synchronized {
+ var ss = sent, ss1 = ss.next;
+ while (ss1 != null && !r.receiver.isDefinedAt(ss1.elem)) {
+ ss = ss1; ss1 = ss1.next
+ }
+ if (ss1 != null) {
+ ss.next = ss1.next; r.msg = ss1.elem;
+ } else {
+ lastReceiver = lastReceiver append r;
+ }
+ }
+
+ def receive[a](f: PartialFunction[Message, a]): a = {
+ val r = new Receiver() { type t = a; val receiver = f }
+ scanSentMsgs(r);
+ r.receive()
+ }
+
+ def receiveWithin[a](msec: Long)(f: PartialFunction[Message, a]): a = {
+ val r = new Receiver() { type t = a; val receiver = f }
+ scanSentMsgs(r);
+ r.receiveWithin(msec)
+ }
+}
diff --git a/sources/scalac/ast/printer/TextTreePrinter.java b/sources/scalac/ast/printer/TextTreePrinter.java
index b41642af07..a56f1e43c7 100644
--- a/sources/scalac/ast/printer/TextTreePrinter.java
+++ b/sources/scalac/ast/printer/TextTreePrinter.java
@@ -324,6 +324,7 @@ public class TextTreePrinter implements TreePrinter {
print(KW_IMPORT);
print(Text.Space);
print(expr);
+ print(TXT_DOT);
print(TXT_LEFT_BRACE);
for (int i = 0; i < selectors.length; i = i + 2) {
if (i > 0) print(TXT_COMMA_SP);
diff --git a/sources/scalac/symtab/Type.java b/sources/scalac/symtab/Type.java
index 3874954d30..ad862d5cf4 100644
--- a/sources/scalac/symtab/Type.java
+++ b/sources/scalac/symtab/Type.java
@@ -121,7 +121,7 @@ public class Type implements Modifiers, Kinds, TypeTags {
}
public static Type typeRef(Type pre, Symbol sym, Type[] args) {
- if (pre.isStable() || pre == ErrorType)
+ if (pre.isLegalPrefix() || pre == ErrorType)
return TypeRef(pre, sym, args);
else if (sym.kind == ALIAS)
return pre.memberInfo(sym);
@@ -458,6 +458,22 @@ public class Type implements Modifiers, Kinds, TypeTags {
}
}
+ /** Is this type a legal prefix?
+ */
+ public boolean isLegalPrefix() {
+ switch (unalias()) {
+ case ThisType(_):
+ case SingleType(_, _):
+ return true;
+ case TypeRef(_, Symbol sym, _):
+ return sym.kind == CLASS &&
+ ((sym.flags & JAVA) != 0 ||
+ (sym.flags & (TRAIT | ABSTRACTCLASS)) == 0);
+ default:
+ return false;
+ }
+ }
+
/** Is this type a reference to an object type?
*/
public boolean isObjectType() {
@@ -895,7 +911,8 @@ public class Type implements Modifiers, Kinds, TypeTags {
Type toPrefix(Type pre, Symbol clazz) {
if (pre == NoType || clazz.kind != CLASS)
return this;
- else if (pre.widen().symbol().isSubClass(symbol()))
+ else if (symbol().isSubClass(clazz) &&
+ pre.widen().symbol().isSubClass(symbol()))
return pre;
else
return toPrefix(pre.baseType(clazz).prefix(), clazz.owner());
@@ -1218,15 +1235,7 @@ public class Type implements Modifiers, Kinds, TypeTags {
case NoType:
return false;
- case ThisType(Symbol sym1):
- switch (this) {
- case ThisType(Symbol sym):
- return sym.isSubClass(sym1);
- case SingleType(_, _):
- return this.isSameAs(that);
- }
- break;
-
+ case ThisType(_):
case SingleType(_, _):
switch (this) {
case ThisType(_):
@@ -1238,7 +1247,7 @@ public class Type implements Modifiers, Kinds, TypeTags {
case TypeRef(Type pre1, Symbol sym1, Type[] args1):
switch (this) {
case TypeRef(Type pre, Symbol sym, Type[] args):
- if (sym == sym1 && pre.isSubType(pre1) && isSubArgs(args, args1))
+ if (sym == sym1 && pre.isSameAs(pre1) && isSubArgs(args, args1))
return true;
break;
}
diff --git a/sources/scalac/typechecker/Analyzer.java b/sources/scalac/typechecker/Analyzer.java
index f6400b3872..a89da81175 100644
--- a/sources/scalac/typechecker/Analyzer.java
+++ b/sources/scalac/typechecker/Analyzer.java
@@ -481,16 +481,17 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
try {
return checkNoEscapeMap.apply(tp);
} catch (Type.Error ex) {
- error(pos, ex.msg);
+ error(pos, ex.msg + " as part of " + tp.unalias());
return Type.ErrorType;
}
}
//where
private Type.Map checkNoEscapeMap = new Type.Map() {
public Type apply(Type t) {
- switch (t.unalias()) {
- case TypeRef(ThisType(_), Symbol sym, Type[] args):
- checkNoEscape(t, sym);
+ switch (t) {
+ case TypeRef(Type pre, Symbol sym, Type[] args):
+ if (sym.kind == ALIAS) return apply(t.unalias());
+ else if (pre instanceof Type.ThisType) checkNoEscape(t, sym);
break;
case SingleType(ThisType(_), Symbol sym):
checkNoEscape(t, sym);
@@ -636,6 +637,36 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
// Entering Symbols ----------------------------------------------------------
+ Tree transformPackageId(Tree tree) {
+ switch (tree) {
+ case Ident(Name name):
+ return tree
+ .setSymbol(packageSymbol(tree.pos, definitions.ROOT, name))
+ .setType(tree.symbol().type());
+ case Select(Tree qual, Name name):
+ Tree qual1 = transformPackageId(qual);
+ return copy.Select(tree, qual1, name)
+ .setSymbol(packageSymbol(tree.pos, qual1.symbol(), name))
+ .setType(tree.symbol().type());
+ default:
+ return transform(tree);
+ }
+ }
+
+ Symbol packageSymbol(int pos, Symbol base, Name name) {
+ Symbol p = base.members().lookup(name);
+ if (p.kind == NONE) {
+ p = TermSymbol.newModule(
+ Position.NOPOS, name, base.moduleClass(), JAVA | PACKAGE);
+ p.moduleClass().setInfo(Type.compoundType(Type.EMPTY_ARRAY, new Scope(), p));
+ base.members().enter(p);
+ } else if (!p.isPackage()) {
+ error(pos, "package and class with same name");
+ p = Symbol.ERROR;
+ }
+ return p;
+ }
+
/** If `tree' is a definition, create a symbol for it with a lazily
* constructed type, and enter into current scope.
*/
@@ -648,8 +679,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
case Template(_, Tree[] body):
pushContext(tree, context.owner, context.scope);
context.imports = null;
- ((PackageDef) tree).packaged = packaged =
- transform(packaged, QUALmode);
+ ((PackageDef) tree).packaged = packaged = transformPackageId(packaged);
popContext();
Symbol pkg = checkStable(packaged).symbol();
if (pkg != null && pkg.kind != ERROR) {
diff --git a/sources/scalac/typechecker/ImportList.java b/sources/scalac/typechecker/ImportList.java
index 9e7e79110d..ba45996570 100644
--- a/sources/scalac/typechecker/ImportList.java
+++ b/sources/scalac/typechecker/ImportList.java
@@ -49,12 +49,18 @@ class ImportList {
switch (tree) {
case Import(Tree expr, Name[] selectors):
for (int i = 0; i < selectors.length; i = i + 2) {
- if (i + 1 < selectors.length && name == selectors[i + 1])
- return t.lookupNonPrivate(selectors[i]);
- else if (name == selectors[i])
+ if (i + 1 < selectors.length && name.toTermName() == selectors[i + 1]) {
+ if (name.isTypeName())
+ return t.lookupNonPrivate(selectors[i].toTypeName());
+ else if (name.isConstrName())
+ return t.lookupNonPrivate(selectors[i].toConstrName());
+ else
+ return t.lookupNonPrivate(selectors[i]);
+ } else if (name.toTermName() == selectors[i]) {
renamed = true;
- else if (selectors[i] == Names.WILDCARD && !renamed)
+ } else if (selectors[i] == Names.WILDCARD && !renamed) {
return t.lookupNonPrivate(name);
+ }
}
return Symbol.NONE;
default:
diff --git a/test/files/pos/S1.scala b/test/files/pos/S1.scala
index eba81109b3..68706e3dd3 100644
--- a/test/files/pos/S1.scala
+++ b/test/files/pos/S1.scala
@@ -9,5 +9,5 @@
*/
class S1() {
def foo[T <: this.type](x: T) = x;
- foo(this);
+ foo[this.type](this);
}
diff --git a/test/files/pos/cls1.scala b/test/files/pos/cls1.scala
index badc4e793a..fd64a57073 100644
--- a/test/files/pos/cls1.scala
+++ b/test/files/pos/cls1.scala
@@ -1,11 +1,9 @@
-package cls1;
+package test;
trait A {
-
type T;
trait B extends A {
type T = A.this.T;
}
-
} \ No newline at end of file
diff --git a/test/pos/S1.scala b/test/pos/S1.scala
index eba81109b3..68706e3dd3 100644
--- a/test/pos/S1.scala
+++ b/test/pos/S1.scala
@@ -9,5 +9,5 @@
*/
class S1() {
def foo[T <: this.type](x: T) = x;
- foo(this);
+ foo[this.type](this);
}
diff --git a/test/pos/cls1.scala b/test/pos/cls1.scala
index badc4e793a..fd64a57073 100644
--- a/test/pos/cls1.scala
+++ b/test/pos/cls1.scala
@@ -1,11 +1,9 @@
-package cls1;
+package test;
trait A {
-
type T;
trait B extends A {
type T = A.this.T;
}
-
} \ No newline at end of file