summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/reference/ScalaByExample.tex64
-rw-r--r--doc/reference/ScalaReference.tex65
-rw-r--r--sources/examples/parsers.scala12
-rw-r--r--sources/scala/tools/scalac/typechecker/Analyzer.scala42
4 files changed, 92 insertions, 91 deletions
diff --git a/doc/reference/ScalaByExample.tex b/doc/reference/ScalaByExample.tex
index b0aed6d462..cb75ba7ddd 100644
--- a/doc/reference/ScalaByExample.tex
+++ b/doc/reference/ScalaByExample.tex
@@ -6210,23 +6210,23 @@ A synchronized variable (or syncvar for short) offers \code{get} and
block until the variable has been defined. An \code{unset} operation
resets the variable to undefined state.
-Synchronized variables can be implemented as follows.
+Here's the standard implementation of synchronized variables.
\begin{lstlisting}
-class SyncVar[a] extends Monitor {
- private val defined = new Signal;
- private var isDefined: boolean = false;
- private var value: a;
+package scala.concurrent;
+class SyncVar[a] with Monitor {
+ private var isDefined: Boolean = false;
+ private var value: a = _;
def get = synchronized {
- if (!isDefined) defined.wait;
+ if (!isDefined) wait();
value
}
def set(x: a) = synchronized {
- value = x ; isDefined = true ; defined.send;
+ value = x ; isDefined = true ; notifyAll();
}
- def isSet: boolean =
+ def isSet: Boolean =
isDefined;
- def unset = synchronized {
- isDefined = false;
+ def unset = synchronized {
+ isDefined = false;
}
}
\end{lstlisting}
@@ -6240,18 +6240,20 @@ Futures are used in order to make good use of parallel processing
resources. A typical usage is:
\begin{lstlisting}
+import scala.concurrent.ops._;
+...
val x = future(someLengthyComputation);
anotherLengthyComputation;
val y = f(x()) + g(x());
\end{lstlisting}
-Futures can be implemented in Scala as follows.
-
+The \code{future} method is defined in object
+\code{scala.concurrent.ops} as follows.
\begin{lstlisting}
def future[a](def p: a): unit => a = {
val result = new SyncVar[a];
fork { result.set(p) }
- (=> result.get)
+ (() => result.get)
}
\end{lstlisting}
@@ -6275,31 +6277,33 @@ The next example presents a function \code{par} which takes a pair of
computations as parameters and which returns the results of the computations
in another pair. The two computations are performed in parallel.
+The function is defined in object
+\code{scala.concurrent.ops} as follows.
\begin{lstlisting}
-def par[a, b](def xp: a, def yp: b): (a, b) = {
- val y = new SyncVar[a];
- fork { y.set(yp) }
- (xp, y)
-}
+ def par[a, b](def xp: a, def yp: b): Pair[a, b] = {
+ val y = new SyncVar[b];
+ spawn { y set yp }
+ Pair(xp, y.get)
+ }
\end{lstlisting}
-
-The next example presents a function \code{replicate} which performs a
+Defined in the same place is a function \code{replicate} which performs a
number of replicates of a computation in parallel. Each
replication instance is passed an integer number which identifies it.
-
\begin{lstlisting}
-def replicate(start: int, end: int)(def p: int => unit): unit = {
- if (start == end) {
- } else if (start + 1 == end) {
- p(start)
- } else {
- val mid = (start + end) / 2;
- par ( replicate(start, mid)(p), replicate(mid, end)(p) )
+ def replicate(start: Int, end: Int)(p: Int => Unit): Unit = {
+ if (start == end)
+ ()
+ else if (start + 1 == end)
+ p(start)
+ else {
+ val mid = (start + end) / 2;
+ spawn { replicate(start, mid)(p) }
+ replicate(mid, end)(p)
+ }
}
-}
\end{lstlisting}
-The next example shows how to use \code{replicate} to perform parallel
+The next function uses \code{replicate} to perform parallel
computations on all elements of an array.
\begin{lstlisting}
diff --git a/doc/reference/ScalaReference.tex b/doc/reference/ScalaReference.tex
index fa5a795b65..c62e0f04b4 100644
--- a/doc/reference/ScalaReference.tex
+++ b/doc/reference/ScalaReference.tex
@@ -304,7 +304,7 @@ referenced entity in $T$.
Type ::= Type1 `=>' Type
| `(' [Types] `)' `=>' Type
| Type1
- Type1 ::= SimpleType {with SimpleType} [Refinement]
+ Type1 ::= SimpleType {with SimpleType}
SimpleType ::= StableId
| SimpleType `#' id
| Path `.' type
@@ -318,14 +318,12 @@ take type parameters and yield types. A subset of first-order types
called {\em value types} represents sets of (first-class) values.
Value types are either {\em concrete} or {\em abstract}. Every
concrete value type can be represented as a {\em class type}, i.e.\ a
-type designator (\sref{sec:type-desig}) that refers to a
-class\footnote{We assume that objects and packages also
-implicitly define a class (of the same name as the object or package,
-but inaccessible to user programs).} (\sref{sec:classes}),
-or as a {\em compound type} (\sref{sec:compound-types})
-consisting of class types and possibly
-also a refinement (\sref{sec:refinements}) that further constrains the
-types of its members.
+type designator (\sref{sec:type-desig}) that refers to a
+class\footnote{We assume that objects and packages also implicitly
+define a class (of the same name as the object or package, but
+inaccessible to user programs).} (\sref{sec:classes}), or as a {\em
+compound type} (\sref{sec:compound-types}) of class types.
+\todo{verify whether operands need to be class types}
A shorthand exists for denoting function types
(\sref{sec:function-types}). Abstract value types are introduced by
@@ -474,25 +472,14 @@ the following types are ill-formed:
\label{sec:compound-types}
\syntax\begin{lstlisting}
- Type ::= SimpleType {with SimpleType} [Refinement]
- Refinement ::= `{' [RefineStat {`;' RefineStat}] `}'
- RefineStat ::= Dcl
- | type TypeDef {`,' TypeDef}
- |
+ Type ::= SimpleType {with SimpleType}
\end{lstlisting}
-A compound type ~\lstinline@$T_1$ with $\ldots$ with $T_n$ {$R\,$}@~ represents
-objects with members as given in the component types $T_1 \commadots
-T_n$ and the refinement \lstinline@{$R\,$}@. Each component type $T_i$ must be a
-class type and the base class sequence generated by types $T_1
-\commadots T_n$ must be well-formed (\sref{sec:basetypes-wf}). A
-refinement \lstinline@{$R\,$}@ contains declarations and type
-definitions. Each declaration or definition in a refinement must
-override a declaration or definition in one of the component types
-$T_1 \commadots T_n$. The usual rules for overriding (\sref{})
-apply. If no refinement is given, the empty refinement is implicitly
-added, i.e. ~\lstinline@$T_1$ with $\ldots$ with $T_n$@~ is a shorthand for
-~\lstinline@$T_1$ with $\ldots$ with $T_n$ {}@.
+A compound type ~\lstinline@$T_1$ with $\ldots$ with $T_n$ {$R\,$}@~
+represents objects with members as given in the component types $T_1
+\commadots T_n$. Each component type $T_i$ must be a class type and
+the base class sequence generated by types $T_1 \commadots T_n$ must
+be well-formed (\sref{sec:basetypes-wf}).
\subsection{Function Types}
\label{sec:function-types}
@@ -758,10 +745,7 @@ consisting only of package or object selectors and ending in $O$, then
~\lstinline@$O$.this.type $\equiv p$.type@.
\item
Two compound types are equivalent if their component types are
-pairwise equivalent and their refinements are equivalent. Two
-refinements are equivalent if they bind the same names and the
-modifiers, types and bounds of every declared entity are equivalent in
-both refinements.
+pairwise equivalent.
\item
Two method types are equivalent if they have equivalent result
types, both have the same number of parameters, and corresponding
@@ -938,9 +922,8 @@ the expression is typed and evaluated is if it was
\end{lstlisting}
A {\em declaration} introduces names and assigns them types. It can
-appear as one of the statements of a class definition
-(\sref{sec:templates}) or as part of a refinement in a compound
-type (\sref{sec:refinements}).
+only appear as one of the statements of a class definition
+(\sref{sec:templates}).
A {\em definition} introduces names that denote terms or types. It can
form part of an object or class definition or it can be local to a
@@ -2720,13 +2703,7 @@ constructor invocations (of types $S, T_1 \commadots T_n$, say) and
$stats$ is a statement sequence containing initializer statements and
member definitions (\sref{sec:members}). The type of such an instance
creation expression is then the compound type
-\lstinline@$S$ with $T_1$ with $\ldots$ with $T_n$ {$R\,$}@,
-where \lstinline@{$R\,$}@ is
-a refinement (\sref{sec:compound-types}) which declares exactly those
-members of $stats$ that override a member of $S$ or $T_1 \commadots
-T_n$. \todo{what about methods and overloaded defs?} For this type to
-be well-formed, $R$ may not reference types defined in $stats$ which
-do not themselves form part of $R$.
+\lstinline@$S$ with $T_1$ with $\ldots$ with $T_n$@.
The instance creation expression is evaluated by creating a fresh
object, which is initialized by evaluating the expression template.
@@ -3398,7 +3375,7 @@ Concretely, we distinguish the following kinds of patterns.
A {\em wild-card pattern} \_ matches any value.
A {\em typed pattern} $\_: T$ matches values of type $T$. The type $T$ may be
- a class type or a compound type; it may not contain a refinement (\sref{sec:refinements}).
+ a class type or a compound type.
This pattern matches any non-null value of type $T$. $T$ must conform to the pattern's expected
type. A pattern $x:T$ is treated the same way as $x @ (_:T)$
@@ -4260,7 +4237,7 @@ grammar.
Type ::= Type1 `=>' Type
| `(' [Types] `)' `=>' Type
| Type1
- Type1 ::= SimpleType {with SimpleType} [Refinement]
+ Type1 ::= SimpleType {with SimpleType}
SimpleType ::= SimpleType TypeArgs
| SimpleType `#' id
| StableId
@@ -4268,10 +4245,6 @@ grammar.
| `(' Type ')'
TypeArgs ::= `[' Types `]'
Types ::= Type {`,' Type}
- Refinement ::= `{' [RefineStat {`;' RefineStat}] `}'
- RefineStat ::= Dcl
- | type TypeDef {`,' TypeDef}
- |
Exprs ::= Expr {`,' Expr}
Expr ::= Bindings `=>' Expr
diff --git a/sources/examples/parsers.scala b/sources/examples/parsers.scala
index 3112e0346d..bef1e960cb 100644
--- a/sources/examples/parsers.scala
+++ b/sources/examples/parsers.scala
@@ -1,5 +1,8 @@
package examples;
-abstract class Parsers[intype] {
+
+abstract class Parsers {
+
+ type intype;
abstract class Parser {
@@ -39,7 +42,7 @@ abstract class Parsers[intype] {
def rep1(p: Parser): Parser = p &&& rep(p); // p+ = p p*
}
-abstract class ListParsers[intype] extends Parsers[intype] {
+abstract class ListParsers extends Parsers {
def chr(p: char => boolean): Parser;
@@ -55,7 +58,8 @@ abstract class ListParsers[intype] extends Parsers[intype] {
def expr : Parser = ident ||| number ||| list;
}
-class ParseString(s: String) extends Parsers[int] {
+class ParseString(s: String) extends Parsers {
+ type intype = int;
val input = 0;
def chr(p: char => boolean) = new Parser {
def apply(in: int): Parser#Result =
@@ -68,7 +72,7 @@ object Test {
def main(args: Array[String]): unit =
if (args.length == 1) {
- val ps = new ListParsers[int] with ParseString(args(0));
+ val ps = new ListParsers with ParseString(args(0));
ps.exprs(input) match {
case Some(n) =>
System.out.println("parsed: " + args(0).substring(0, n));
diff --git a/sources/scala/tools/scalac/typechecker/Analyzer.scala b/sources/scala/tools/scalac/typechecker/Analyzer.scala
index bfc9082add..c80cf712ab 100644
--- a/sources/scala/tools/scalac/typechecker/Analyzer.scala
+++ b/sources/scala/tools/scalac/typechecker/Analyzer.scala
@@ -250,6 +250,7 @@ class Analyzer(global: scalac_Global, descr: AnalyzerPhase) extends Transformer(
if (isAccessible(sym, site, sitetype)) {
symtype
} else {
+ System.out.println(sym.flags & (PRIVATE | PROTECTED));//debug
error(pos, "" + sym + " cannot be accessed in " + sitetype.widen());
Type.ErrorType
}
@@ -288,8 +289,9 @@ class Analyzer(global: scalac_Global, descr: AnalyzerPhase) extends Transformer(
accessWithin(owner)
||
((sym.flags & PRIVATE) == 0) &&
- sitetype.symbol().isSubClass(owner) &&
- (site.isInstanceOf[Tree$Super] || isSubClassOfEnclosing(sitetype.symbol()))
+ (site.isInstanceOf[Tree$Super] ||
+ (sitetype.symbol().isSubClass(owner) &&
+ isSubClassOfEnclosing(sitetype.symbol())))
}
}
@@ -1021,9 +1023,10 @@ class Analyzer(global: scalac_Global, descr: AnalyzerPhase) extends Transformer(
var rhs = _rhs;
var restype: Type = null;
pushContext(tree, sym, new Scope(context.scope));
- if (name == Names.CONSTRUCTOR)
+ if (name == Names.CONSTRUCTOR) {
context.enclClass.owner.flags =
context.enclClass.owner.flags | INCONSTRUCTOR;
+ }
val tparamSyms = enterParams(tparams);
val vparamSyms = enterParams(vparams);
if (tpe != Tree.Empty) {
@@ -1031,8 +1034,10 @@ class Analyzer(global: scalac_Global, descr: AnalyzerPhase) extends Transformer(
(tree.asInstanceOf[Tree$DefDef]).tpe = tpe;
restype = tpe.getType();
} else if (name == Names.CONSTRUCTOR) {
- restype = context.enclClass.owner.getType().subst(
- context.enclClass.owner.typeParams(), tparamSyms);
+ if (context.enclClass.owner.typeParams().length != 0)
+ error(tree.pos, "secondary constructors for parameterized classes not yet implemented");
+ restype = context.enclClass.owner.getType();/*.subst(
+ context.enclClass.owner.typeParams(), tparamSyms)*/;
context.enclClass.owner.flags =
context.enclClass.owner.flags & ~INCONSTRUCTOR;
} else {
@@ -2449,14 +2454,29 @@ class Analyzer(global: scalac_Global, descr: AnalyzerPhase) extends Transformer(
val constr: Symbol = c.allConstructors();
val fn0: Tree = fn1;
fn1 = gen.mkRef(fn1.pos, pre, constr);
- fn1 match {
- case Tree$Select(fn1qual, _) =>
+ if (constr.owner().isPackage()) {
+ var c = context;
+ while (c != Context.NONE &&
+ !c.tree.isInstanceOf[Tree$ClassDef] &&
+ !c.tree.isInstanceOf[Tree$Template])
+ c = c.outer;
+ if (c.owner.isConstructor())
+ // we are in a superclass constructor call
+ fn1.setType(checkAccessible(
+ fn1.pos, constr, fn1.getType(), make.Super(tree.pos, Names.EMPTY.toTypeName(), Names.EMPTY.toTypeName()), c.owner.constructorClass().typeConstructor()));
+ else
fn1.setType(checkAccessible(
- fn1.pos, constr, fn1.getType(), fn1qual, fn1qual.getType()));
- case _ =>
- if (constr.owner().isPackage())
+ fn1.pos, constr, fn1.getType(), c.tree, c.owner.typeConstructor()));
+ } else {
+ fn1 match {
+ case Tree$Select(fn1qual, _) =>
fn1.setType(checkAccessible(
- fn1.pos, constr, fn1.getType(), Tree.Empty, constr.owner().getType()));
+ fn1.pos, constr, fn1.getType(), fn1qual, fn1qual.getType()));
+ case _ =>
+ if (constr.owner().isPackage())
+ fn1.setType(checkAccessible(
+ fn1.pos, constr, fn1.getType(), Tree.Empty, constr.owner().getType()));
+ }
}
if (tsym == c) {
fn0 match {