summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2003-07-04 14:06:34 +0000
committerMartin Odersky <odersky@gmail.com>2003-07-04 14:06:34 +0000
commit00abd39f96ee40da727ccc735d25ca3d96ce01ce (patch)
tree6d7314cd14761335c0dd99d149d8934ef45d4115
parentbf8fd4c5b3e1df5b249f7fa2d765913cf662fd51 (diff)
downloadscala-00abd39f96ee40da727ccc735d25ca3d96ce01ce.tar.gz
scala-00abd39f96ee40da727ccc735d25ca3d96ce01ce.tar.bz2
scala-00abd39f96ee40da727ccc735d25ca3d96ce01ce.zip
*** empty log message ***
-rw-r--r--doc/reference/reference.verb.tex320
-rw-r--r--sources/scalac/ast/parser/Parser.java16
-rw-r--r--sources/scalac/ast/parser/Scanner.java1
-rw-r--r--sources/scalac/ast/parser/Tokens.java1
-rw-r--r--sources/scalac/ast/printer/TextTreePrinter.java9
-rw-r--r--sources/scalac/symtab/Modifiers.java10
-rw-r--r--sources/scalac/symtab/Symbol.java18
-rw-r--r--sources/scalac/symtab/Type.java6
-rw-r--r--sources/scalac/typechecker/Analyzer.java69
-rw-r--r--sources/scalac/util/Names.java1
-rw-r--r--support/latex/verbfilterScala.java5
-rw-r--r--test/files/neg/S6.check2
-rw-r--r--test/files/neg/seqtest.check3
-rw-r--r--test/files/pos/imports.scala2
-rw-r--r--test/neg/S6.check2
-rw-r--r--test/neg/seqtest.check3
-rw-r--r--test/pos/imports.scala2
17 files changed, 228 insertions, 242 deletions
diff --git a/doc/reference/reference.verb.tex b/doc/reference/reference.verb.tex
index f179555f5d..cca510c3aa 100644
--- a/doc/reference/reference.verb.tex
+++ b/doc/reference/reference.verb.tex
@@ -10,7 +10,7 @@
\newcommand{\iffinaltype}[1]{}
\newcommand{\ifpackaging}[1]{}
\newcommand{\ifnewfor}[1]{}
-\renewcommand{\todo}[1]{#1}
+\renewcommand{\todo}[1]{{$\clubsuit$\bf todo: #1$\spadesuit$}}
\newcommand{\notyet}{\footnote{not yet implemented.}}
\title{Report on the Programming Language Scala}
@@ -256,9 +256,9 @@ abstract as case class constr
def do else extends final
false for if is import
new null object override package
-private protected super this trait
-true type val var with
-yield
+private protected sealed super this
+trait true type val var
+with yield
_ : = => <- <: >: # @
\end{verbatim}
@@ -1368,29 +1368,36 @@ entity, of type \verb@T_1 \overload \ldots \overload T_n@
\label{sec:import}
\syntax\begin{verbatim}
- Import \=::=\> import ImportExpr {`,' ImportExpr}
+ Import \=::=\= import ImportExpr {`,' ImportExpr}
ImportExpr \>::=\> StableId `.' (Id | `_' | ImportSelectors)
ImportSelectors \>::=\> `{' {ImportSelector `,'} (ImportSelector | `_') `}'
ImportSelector \>::=\> Id [`=>' Id | `=>' `_']
\end{verbatim}
-An import clause has the form $import;e.I$ where \verb@e@ is a stable
+An import clause has the form \verb@import p.I@ where \verb@p@ is a stable
identifier (\sref{sec:paths}) and \verb@I@ is an import expression.
-The import expression determines a set of names of members of \verb@e@
+The import expression determines a set of names of members of \verb@p@
which are made available without qualification. The most general form
of an import expression is a list of {\em import selectors}
\begin{verbatim}
{ x$_1$ => y$_1$, ..., x$_n$ => y$_n$, _ }
\end{verbatim}
for $n \geq 0$, where the final wildcard `\verb@_@' may be absent. It
-makes available each member \verb@e.x$_i$@ under the unqualified name
-\verb@y$_i$. I.e.\ every import selector \verb@x$_i$ => y$_i$@ renames
-\verb@e.x$_i$@ to
-\verb@y$_i$. If a final wildcard is present, all members \verb@z@ of
-\verb@e@ other than \verb@x$_1$, ..., x$_n$@ are also made available
+makes available each member \verb@p.x$_i$@ under the unqualified name
+\verb@y$_i$@. I.e.\ every import selector \verb@x$_i$ => y$_i$@ renames
+\verb@p.x$_i$@ to
+\verb@y$_i$@. If a final wildcard is present, all members \verb@z@ of
+\verb@p@ other than \verb@x$_1$, ..., x$_n$@ are also made available
under their own unqualfied names.
-If destination in an import selector is a wildcard, the import
+Import selectors work in the same way for members in all three name
+spaces. For instance, an import clause \verb@import p.{x => y}@
+renames the term name \verb@p.x@ to the term name \verb@y@, the type
+name \verb@p.x@ to the type name \verb@y@, and the constructor name
+\verb@p.x@ to the type name \verb@y@. At least one of these three
+names must reference a member of \verb@p@.
+
+If the destination in an import selector is a wildcard, the import
selector hides access to the source member. For instance, the import
selector \verb@x => _@ ``renames'' \verb@x@ to the wildcard symbol
(which is unaccessible as a name in user programs), and thereby
@@ -1398,119 +1405,40 @@ effectively prevents unqualified access to \verb@x@. This is useful if
there is a final wildcard in the same import selector list, which
imports all members not mentioned in previous import selectors.
-
-
-The import selector \verb@x$_i$
-
-
-
-
-
-
-\begin{itemize}
-\item
-An import selet
-If the import selector is an identifier, as in \verb@import e.x@, then
-\verb@x@ can be accessed without qualification.
-\item
-If the import selector is
-
-
- , an clause makes members
-
-expression $e$ available without qualification. The expression $e$
-must be a stable identifier $r$, possibly followed by an explicit type
-$T$. If no type is given, the type of $r$ is assumed. For every
-simple name $x$ of a non-private member of $T$, the simple name $x$ is
-introduced as an alias for $r.x$ in the remainder of the block or
-template that follows the import clause.
-
-An import clause with multiple expressions $\IMPORT;e_1
-\commadots e_n$ is interpreted as a sequence of import clauses
-$\IMPORT;e_1 \ldots \IMPORT;e_n$.
-
-\example Consider the module definition:
-\begin{verbatim}
-module M with { def z = 0; def inc(x: Int): Int = x + 1 }
+Several shorthands exist. An import selector may be just a simple name
+\verb@x@. In this case, \verb@x@ is imported without renaming, so the
+import selector is equivalent to \verb@x => x@. Furthermore, it is
+possible to replace the whole import selector list by a single
+identifier or wildcard. The import clause \verb@import p.x@ is
+equivalent to \verb@import p.{x}@, i.e.\ it makes available without
+qualification the member \verb@x@ of \verb@p@. The import clause
+\verb@import p._@ is equivalent to
+\verb@import p.{_}@,
+i.e.\ it makes available without qualification all members of \verb@p@
+(this is analogous to \verb@import p.*@ in Java).
+
+An import clause with multiple import expressions
+\verb@import p$_1$.I$_1$, ..., p$_n$.I$_n$@ is interpreted as a
+sequence of import clauses
+\verb@import p$_1$.I$_1$; ..., import p$_n$.I$_n$@.
+
+\example Consider the object definition:
+\begin{verbatim}
+object M {
+ def z = 0, one = 1;
+ def add(x: Int, y: Int): Int = x + y
+}
\end{verbatim}
Then the block
-\verb@{ import M; inc(z) }@
-is equivalent to the block \verb@{ M.inc(M.z) }@.
-
-\comment{
-The compiler expands the import clause to a sequence of definitions as
-is described below. Assume first that the imported expression $e$ is a
-stable identifier $r$. For every simple name $x$ of a member of $r$,
-the compiler generates an alias definition (\sref{sec:aliasing}) of
-$x$ for $r.x$. If there are several members of $r$ that have the same
-simple name $x$ but different qualified names, only the member
-identified (\sref{sec:names}) by the simple name $x$ is imported.
-
-
-\subsection*{Alias Definitions}
-\label{sec:aliasing}
-
-With the exception of guards (which are never members of classes or
-objects) it is always possible to define aliases for defined
-entities. An alias definition of the \ifqualified{(possibly qualified)} name $X$ for
-the entity $Y$ takes one of the following forms.
-
-If $Y$ defines a type, then the alias definition is \verb@type X = Y@
-(or the parameterized analogue if $Y$ is a type constructor).
-
-If $Y$ defines a parameterless method of type $[]T$, then the alias definition is
-\bda{l}
-\DEF;X: T = Y \enspace.\eda
-
-If $Y$ defines a monomorpic method of type $(ps_1)\ldots(ps_n)T$,
-then the alias definition is
-\bda{l}
-\DEF;X(ps_1) \ldots (ps_n): T = Y(ps_1)\ldots (ps_n) \enspace.\eda
-
-If $Y$ defines a polymorphic method of type $[a_1 \extends S_1 \commadots a_m \extends S_m](ps_1)\ldots(ps_n) T$,
-then the alias definition is
-\bda{l}
-\DEF;X[a_1 \extends S_1 \commadots a_m \extends S_m](ps_1) \ldots (ps_n): T =
-Y[a_1 \commadots a_m](ps_1)\ldots (ps_n) \enspace.
-\eda
-
-If $Y$ defines an overloaded function of type $T_1 \overload \ldots
-\overload T_n$, then the alias definition consists of $n$ function
-definitions, which correspond to the alternatives $T_1 \commadots T_n$
-of the overloaded type.
-
-If $Y$ is defined by a value (\sref{sec:valdef}),
-let (\sref{sec:letdef}) or module (\sref{sec:modules}) definition, then the alias
-definition is $\VAL;X = Y$.
-
-If $Y$ defines a parameterless class, then the alias definition is
-$\CLASS;X = Y$. If $Y$ defines a class with parameters $[a_1
-\extends S_1 \commadots a_m \extends S_m](ps_1) \ldots (ps_n)$,
-then the alias definition is
-\bda{l}
-\CLASS;X;[a_1\extends S_1 \commadots a_m \extends S_m](ps_1) \ldots (ps_n) = Y[a_1 \commadots a_m](ps_1) \ldots (ps_n)
-\enspace.
-\eda
-
-\example Some alias definitions are:
-
-\begin{verbatim}
-module L = scala.lang;
-type T = L.List[Int];
-def println(s: String) = L.System.println(s);
-val out = L.System.out;
-class IntList = L.List[Int];
-class Nil[a] = L.Nil[a];
-\end{verbatim}
-}
-
+\verb@{ import M.{one, z => zero, _}; add(zero, one) }@
+is equivalent to the block \verb@{ M.add(M.z, M.one) }@.
\chapter{Classes and Modules}
\label{sec:globaldefs}
\syntax\begin{verbatim}
- PureDef \=::= \= [case] class ClassDef {`,' ClassDef}
- \> | \> module ModuleDef {`,' ModuleDef}
+ ClsDef \>::=\> ([case] class | trait) ClassDef {`,' ClassDef}
+ \> |\> [case] object ObjectDef {`,' ObjectDef}
\end{verbatim}
Classes (\sref{sec:classes}) and modules
@@ -1520,28 +1448,34 @@ Classes (\sref{sec:classes}) and modules
\label{sec:templates}
\syntax\begin{verbatim}
- Template \=::= \= Constr {$\WITH$ Constr} [$\WITH$ `(' {TemplateStat `;'} `)']
-\end{verbatim}
-
-Templates define the type signature, behavior and initial state of a
-class of objects. They form part of instance creation expressions,
-class definitions, and module definitions. A template
-$sc;\WITH;mc_1;\WITH;\ldots;\WITH;mc_n;\WITH;(stats)$ consists of a
-constructor invocation $sc$ which defines the template's {\em
-superclass}, constructor invocations $mc_1 \commadots mc_n$ $(n \geq
-0)$, which define the template's {\em mixin classes}, and a statement
-sequence $stats$ which contains additional member definitions for the
-template. The {\em least proper supertype} of a template is the class
-type or compound type (\sref{sec:compound-types}) consisting of its
-superclass and mixin classes. The superclass of a template must be a
-subtype of the superclass of each mixin class.
+ Template \=::=\= Constr {`with' Constr} [TemplateBody]
+ TemplateBody \>::=\> `{' [TemplateStat {`;' TemplateStat}] `}'
+\end{verbatim}
+
+A template defines the type signature, behavior and initial state of a
+class of objects or of a single object. Templates form part of
+instance creation expressions, class definitions, and module
+definitions. A template
+\verb@sc with mc$_1$ with ... with mc$_n$ {stats}@ consists of a
+constructor invocation \verb@sc@ which defines the template's {\em
+superclass}, constructor invocations \verb@mc$_1$ \commadots mc$_n$@
+$(n \geq 0)$, which define the template's {\em mixin classes}, and a
+statement sequence \verb@stats@ which contains additional member
+definitions for the template. The superclass of a template must be a
+subtype of the superclass of each mixin class. The {\em least proper
+supertype} of a template is the class type or compound type
+(\sref{sec:compound-types}) consisting of its superclass and mixin
+classes.
Member definitions define new members or overwrite members in the
superclass and the mixin classes. If the template forms part of a
-class definition, $stats$ may also contain declarations of abstract
-members. The type of each non-private definition or declaration of a
-template must be equivalent to a type which does not refer to any
-private members of that template.
+class definition, \verb@stats@ may also contain declarations of abstract
+members.
+%The type of each non-private definition or declaration of a
+%template must be equivalent to a type which does not refer to any
+%private members of that template.
+
+\paragraph{Connection with Java}
\subsection{Constructor Invocations}
\label{sec:constr-invoke}
@@ -1564,18 +1498,18 @@ sequences of class types: the {\em base classes} and {\em mixin base
classes}. Their definitions are as follows.
The {\em mixin base classes} of a template
-$sc;\WITH;mc_1;\WITH;mc_n;\WITH;(stats)$ are obtained by
+\verb@sc;\WITH;mc_1;\WITH;mc_n;\WITH;(stats)@ are obtained by
concatenating, for each $i = 1 \commadots n$, the mixin base classes
-of the mixin $mc_i$. The mixin base classes of a class type $C$ are
-the mixin base classes of the template represented by $C$, followed by
-$C$ itself. The mixin base classes of a constructor invocation of type
+of the mixin \verb@mc_i@. The mixin base classes of a class type \verb@C@ are
+the mixin base classes of the template represented by \verb@C@, followed by
+\verb@C@ itself. The mixin base classes of a constructor invocation of type
\verb@class T@ are the mixin base classes of class \verb@T@.
The {\em base classes} of a template consist of the base classes of
its superclass, followed by the template's mixin base classes. The
base classes of class \verb@scala.Any@ consist of just the
-class itself. The base classes of some other class type $C$ are the
-base classes of the template represented by $C$, followed by $C$
+class itself. The base classes of some other class type \verb@C@ are the
+base classes of the template represented by \verb@C@, followed by \verb@C@
itself. The base classes of a constructor invocation of type \verb@class T@
are the base classes of \verb@T@.
@@ -1597,25 +1531,25 @@ determination of the meaning of \verb@super@ (\sref{sec:this-super}).
We therefore define two notions of template evaluation: (Plain)
evaluation (as a defining template or superclass) and mixin evaluation
-with a given superclass $sc$. These notions are defined for templates
+with a given superclass \verb@sc@. These notions are defined for templates
and constructor invocations as follows.
-A {\em mixin evaluation with superclass $sc$} of a template
-$sc';\WITH;mc_1;\WITH;mc_n;\WITH;(stats)$ consists of mixin
-evaluations with superclass $sc$ of the mixin constructor invocations
-$mc_1 \commadots mc_n$ in the order they are given, followed by an
-evaluation of the statement sequence $stats$. Within $stats$ the
-actual superclass refers to $sc$. A mixin evaluation with superclass
-$sc$ of a class constructor invocation $ci$ consists of an evaluation
+A {\em mixin evaluation with superclass \verb@sc@} of a template
+\verb@sc';\WITH;mc_1;\WITH;mc_n;\WITH;(stats)@ consists of mixin
+evaluations with superclass \verb@sc@ of the mixin constructor invocations
+\verb@mc_1 \commadots mc_n@ in the order they are given, followed by an
+evaluation of the statement sequence \verb@stats@. Within \verb@stats@ the
+actual superclass refers to \verb@sc@. A mixin evaluation with superclass
+\verb@sc@ of a class constructor invocation \verb@ci@ consists of an evaluation
of the constructor function and its arguments in the order they are
-given, followed by a mixin evaluation with superclass $sc$ of the
+given, followed by a mixin evaluation with superclass \verb@sc@ of the
template represented by the constructor invocation.
An {\em evaluation} of a template
-$sc;\WITH;mc_1;\WITH;mc_n;\WITH;(stats)$ consists of an evaluation of
-the superclass constructor invocation $sc$ (of type $S$, say),
-followed by a mixin evaluation with superclass $sc$ of the template. An
-evaluation of a class constructor invocation $ci$ consists of an
+\verb@sc;\WITH;mc_1;\WITH;mc_n;\WITH;(stats)@ consists of an evaluation of
+the superclass constructor invocation \verb@sc@ (of type \verb@S@, say),
+followed by a mixin evaluation with superclass \verb@sc@ of the template. An
+evaluation of a class constructor invocation \verb@ci@ consists of an
evaluation of the constructor function and its arguments in
the order they are given, followed by an evaluation of the template
represented by the constructor invocation.
@@ -1635,27 +1569,27 @@ member is called {\em abstract} if it is introduced by a declaration,
{\em concrete} otherwise.
\item
A {\em concrete inherited} member is a non-private, concrete member of
-one of the template's base classes $B$, except if a member with the
+one of the template's base classes \verb@B@, except if a member with the
same \ifqualified{qualified} name is already directly bound in the template, or is
directly bound in a base class of the template which is a subclass of
-$B$, or is a directly bound, non-private, concrete member of a base
-class which succeeds $B$ in the base class sequence of the template.
+\verb@B@, or is a directly bound, non-private, concrete member of a base
+class which succeeds \verb@B@ in the base class sequence of the template.
\item
An {\em abstract inherited} member is a non-private, abstract member
-of one of the template's base classes $B$, except if a member with the
+of one of the template's base classes \verb@B@, except if a member with the
same \ifqualified{qualified} name is already directly bound in the template, or is a
concrete inherited member, or is a directly bound, non-private member
-of a base class which succeeds $b$ in the base class sequence of the
+of a base class which succeeds \verb@b@ in the base class sequence of the
template.
\end{enumerate}
-The type of a member $m$ is determined as follows: If $m$ is defined
-in $stats$, then its type is the type as given in the member's
-declaration or definition. Otherwise, if $m$ is inherited from the
-base class $B[T1 \commadots T_n]$, $B$'s class declaration has formal
-parameters $[a_1 \commadots a_n]$, and $M$'s type in $B$ is $U$, then
-$M$'s type in $C$ is $U[a_1 := T_1
-\commadots a_n := T_n]$.
+The type of a member \verb@m@ is determined as follows: If \verb@m@ is defined
+in \verb@stats@, then its type is the type as given in the member's
+declaration or definition. Otherwise, if \verb@m@ is inherited from the
+base class \verb@B[T1 \commadots T_n]@, \verb@B@'s class declaration has formal
+parameters \verb@[a_1 \commadots a_n]@, and \verb@M@'s type in \verb@B@ is \verb@U@, then
+\verb@M@'s type in \verb@C@ is \verb@U[a_1 := T_1
+\commadots a_n := T_n]@.
\ifqualified{
Members of templates have internally qualified names $Q\qex x$ where
@@ -1715,28 +1649,28 @@ in addition to the members inherited from class \verb@Any@.
\subsection{Overriding}
\label{sec:overriding}
-A template member $M$ that has the same \ifqualified{qualified} name as a
-non-private member $M'$ of a base class (and that belongs to the same
+A template member \verb@M$ that has the same \ifqualified{qualified} name as a
+non-private member \verb@M'$ of a base class (and that belongs to the same
namespace) is said to {\em override} that member. In this case the
-binding of the overriding member $M$ must be more specific
-(\sref{sec:subtyping}) than the binding of the overridden member $M'$.
+binding of the overriding member \verb@M$ must be more specific
+(\sref{sec:subtyping}) than the binding of the overridden member \verb@M'$.
Furthermore, the overridden definition may not be a class or module
definition or a type alias. Method definitions may only override
other method definitions (or the methods implicitly defined by a
variable definition). They may not override value or let definitions.
-Finally, the following restrictions on modifiers apply to $M$ and
-$M'$:
+Finally, the following restrictions on modifiers apply to \verb@M$ and
+\verb@M'$:
\begin{itemize}
\item
-$M$ must not be labelled \verb@private@.
+\verb@M$ must not be labelled \verb@private@.
\item
-If $M'$ is not abstract, then $M$ must be labelled \verb@override@.
+If \verb@M'$ is not abstract, then \verb@M$ must be labelled \verb@override@.
\item
-If $M'$ is labelled \verb@protected@, then $M$ must also be
+If \verb@M'$ is labelled \verb@protected@, then \verb@M$ must also be
labelled \verb@protected@.
\iffinaltype{
\item
-$M'$ may be labelled \verb@final@ only if it is an abstract type
+\verb@M'$ may be labelled \verb@final@ only if it is an abstract type
binding.
}
\end{itemize}
@@ -1822,22 +1756,22 @@ Protected members can be accessed from within the template of the defining
class as well as in all templates that have the defining class as a base class.
Furthermore, accesses from the template of the defining class are not
permitted in packagings other than the one
-containing the definition. A protected identifier $x$ may be used as
-a member name in a selection $r.x$ only if $r$ is one of the reserved
+containing the definition. A protected identifier \verb@x$ may be used as
+a member name in a selection \verb@r.x$ only if \verb@r$ is one of the reserved
words \verb@this@ and
-\verb@super@, or if $r$'s type conforms to a type-instance of a class
+\verb@super@, or if \verb@r$'s type conforms to a type-instance of a class
which contains the access.
\item
The \verb@override@ modifier applies to member definitions. If a
-definition of a simple name $x$ is preceded by
+definition of a simple name \verb@x$ is preceded by
\verb@override@, the definition is taken to override
(\sref{sec:overriding}) a member in the least proper supertype
-(\sref{sec:templates}) which is identified by the simple name $x$.
+(\sref{sec:templates}) which is identified by the simple name \verb@x$.
The \verb@override@ modifier may be followed by a qualified name. If
-a definition of a simple name $x$ is preceded by
-\verb@override $Q$@, the definition is taken to override
-a member in the base class referenced by the qualified name $Q$ which
-is identified by the simple name $x$. In both cases, there must exist
+a definition of a simple name \verb@x$ is preceded by
+\verb@override \verb@Q$@, the definition is taken to override
+a member in the base class referenced by the qualified name \verb@Q$ which
+is identified by the simple name \verb@x$. In both cases, there must exist
such a member according to the rules of (\sref{sec:names}).
\verb@override@ may not be combined in one modifier list with
\verb@private@.
@@ -1845,8 +1779,8 @@ such a member according to the rules of (\sref{sec:names}).
\item
The \verb@qualified@ modifier applies to class or module
definitions. When present, all non-overriding member definitions of
-the class or module (named $M$, say) introduce names which are
-qualified by $M$. When absent, non-overriding member definitions of
+the class or module (named \verb@M$, say) introduce names which are
+qualified by \verb@M$. When absent, non-overriding member definitions of
the class or module introduce names which are qualified by the empty
string $\epsilon$.
}
@@ -1864,7 +1798,7 @@ abstract final class C (x: Int) with {
val empty = new C(0) with {}
\end{verbatim}
For instance, in the code above clients can create instances of class
-$C$ only by calling the \verb@nextC@ method of an existing \verb@C@
+\verb@C$ only by calling the \verb@nextC@ method of an existing \verb@C@
object; it is not possible for clients to create objects of class
\verb@C@ directly. Indeed the following two lines are both in error:
@@ -4368,13 +4302,13 @@ grammar.
\> |\>
Binding \>::=\> Id [`:' Type]
- Modifier \>::=\> abstract
- \> |\> final
+ Modifier \>::=\> LocalModifier
\> |\> private
\> |\> protected
\> |\> override
LocalModifier \>::=\> abstract
\> |\> final
+ \> |\> sealed
Template \>::=\> Constr {`with' Constr} [TemplateBody]
TemplateBody \>::=\> `{' [TemplateStat {`;' TemplateStat}] `}'
diff --git a/sources/scalac/ast/parser/Parser.java b/sources/scalac/ast/parser/Parser.java
index 0ec6de68b0..51d926afdf 100644
--- a/sources/scalac/ast/parser/Parser.java
+++ b/sources/scalac/ast/parser/Parser.java
@@ -115,15 +115,16 @@ public class Parser implements Tokens {
boolean isModifier() {
return (s.token == ABSTRACT)
|| (s.token == FINAL)
+ || (s.token == SEALED)
|| (s.token == PRIVATE)
|| (s.token == PROTECTED)
-// || (s.token == QUALIFIED)
|| (s.token == OVERRIDE);
}
boolean isLocalModifier() {
return (s.token == ABSTRACT)
- || (s.token == FINAL);
+ || (s.token == FINAL)
+ || (s.token == SEALED);
}
boolean isDefIntro() {
@@ -921,6 +922,9 @@ public class Parser implements Tokens {
convertToConstr(stats[stats.length - 1]));
else
syntaxError(res.pos, "class constructor expected", false);
+ break;
+ default:
+ res = applyConstr(convertToConstr(res));
}
accept(RBRACE);
return res;
@@ -1190,6 +1194,9 @@ public class Parser implements Tokens {
case FINAL:
mod = Modifiers.FINAL;
break;
+ case SEALED:
+ mod = Modifiers.SEALED;
+ break;
case PRIVATE:
mod = Modifiers.PRIVATE;
break;
@@ -1224,6 +1231,9 @@ public class Parser implements Tokens {
case FINAL:
mod = Modifiers.FINAL;
break;
+ case SEALED:
+ mod = Modifiers.SEALED;
+ break;
default:
return mods;
}
@@ -1386,9 +1396,11 @@ public class Parser implements Tokens {
t = make.Select(pos, t, name);
pos = accept(DOT);
} else {
+ /*
if (name == Names.ASTERISK)
s.unit.warning(
pos, "this imports only the identifier `*';\nuse `import xyz._' to import all members of `xyz'.");
+ */
return make.Import(startpos, t, new Name[]{name, name});
}
}
diff --git a/sources/scalac/ast/parser/Scanner.java b/sources/scalac/ast/parser/Scanner.java
index 82b41f6e3a..5573ce3e05 100644
--- a/sources/scalac/ast/parser/Scanner.java
+++ b/sources/scalac/ast/parser/Scanner.java
@@ -816,6 +816,7 @@ public class Scanner extends TokenData {
enterKeyword("package", PACKAGE);
enterKeyword("private", PRIVATE);
enterKeyword("protected", PROTECTED);
+ enterKeyword("sealed", SEALED);
enterKeyword("super", SUPER);
enterKeyword("this", THIS);
enterKeyword("trait", TRAIT);
diff --git a/sources/scalac/ast/parser/Tokens.java b/sources/scalac/ast/parser/Tokens.java
index cad7a2da8b..f2e3bc39ad 100644
--- a/sources/scalac/ast/parser/Tokens.java
+++ b/sources/scalac/ast/parser/Tokens.java
@@ -60,6 +60,7 @@ public interface Tokens {
YIELD = 50,
DO = 51,
TRAIT = 52,
+ SEALED = 53,
/* special symbols */
COMMA = 61,
diff --git a/sources/scalac/ast/printer/TextTreePrinter.java b/sources/scalac/ast/printer/TextTreePrinter.java
index 39e8f1edcf..a56fb1a656 100644
--- a/sources/scalac/ast/printer/TextTreePrinter.java
+++ b/sources/scalac/ast/printer/TextTreePrinter.java
@@ -154,6 +154,7 @@ public class TextTreePrinter implements TreePrinter {
protected static final Text KW_ELSE = Text.Keyword("else");
protected static final Text KW_EXTENDS = Text.Keyword("extends");
protected static final Text KW_FINAL = Text.Keyword("final");
+ protected static final Text KW_SEALED = Text.Keyword("sealed");
protected static final Text KW_FOR = Text.Keyword("for");
protected static final Text KW_IF = Text.Keyword("if");
protected static final Text KW_IMPORT = Text.Keyword("import");
@@ -643,6 +644,10 @@ public class TextTreePrinter implements TreePrinter {
print(KW_FINAL);
print(Text.Space);
}
+ if ((flags & Modifiers.SEALED) != 0) {
+ print(KW_SEALED);
+ print(Text.Space);
+ }
if ((flags & Modifiers.PRIVATE) != 0) {
print(KW_PRIVATE);
print(Text.Space);
@@ -651,10 +656,6 @@ public class TextTreePrinter implements TreePrinter {
print(KW_PROTECTED);
print(Text.Space);
}
- if ((flags & Modifiers.QUALIFIED) != 0) {
- print(KW_QUALIFIED);
- print(Text.Space);
- }
if ((flags & Modifiers.OVERRIDE) != 0) {
print(KW_OVERRIDE);
print(Text.Space);
diff --git a/sources/scalac/symtab/Modifiers.java b/sources/scalac/symtab/Modifiers.java
index 9c6f12c115..00509ad16b 100644
--- a/sources/scalac/symtab/Modifiers.java
+++ b/sources/scalac/symtab/Modifiers.java
@@ -16,7 +16,7 @@ public interface Modifiers {
int PRIVATE = 0x00000004;
int PROTECTED = 0x00000008;
- int QUALIFIED = 0x00000010;
+ int SEALED = 0x00000010;
int OVERRIDE = 0x00000020;
int CASE = 0x00000040;
int ABSTRACTCLASS = 0x00000080; // abstract class
@@ -36,7 +36,7 @@ public interface Modifiers {
int ACCESSED = 0x00040000; // symbol was accessed at least once
int SELECTOR = 0x00080000; // symbol was used as selector in Select
- int PACKAGE = 0x00100000; // symbol is a java packages.
+ int PACKAGE = 0x00100000; // symbol is a java package.
int LABEL = 0x00200000; // symbol is a label symbol
int STATIC = 0x00400000; // "static" inner classes (i.e. after class norm.)
int STABLE = 0x00800000; // functions that are assumed to be stable
@@ -79,8 +79,8 @@ public interface Modifiers {
return (flags & PROTECTED) != 0;
}
- public static boolean isQualified(int flags) {
- return (flags & QUALIFIED) != 0;
+ public static boolean isSealed(int flags) {
+ return (flags & SEALED) != 0;
}
public static boolean isOverride(int flags) {
@@ -132,7 +132,7 @@ public interface Modifiers {
if (isProtected(flags)) buffer.append("protected ");
if (isAbstract(flags)) buffer.append("abstract ");
if (isFinal(flags)) buffer.append("final ");
- if (isQualified(flags)) buffer.append("qualified ");
+ if (isSealed(flags)) buffer.append("qualified ");
if (isInterface(flags)) buffer.append("interface ");
if (isCase(flags)) buffer.append("case ");
if (isDef(flags)) buffer.append("def ");
diff --git a/sources/scalac/symtab/Symbol.java b/sources/scalac/symtab/Symbol.java
index 23b062800f..5e4e7e2801 100644
--- a/sources/scalac/symtab/Symbol.java
+++ b/sources/scalac/symtab/Symbol.java
@@ -211,6 +211,13 @@ public abstract class Symbol implements Modifiers, Kinds {
return isInitializedMethod();
}
+ /*
+ public final boolean caseClassOfFactory() {
+ if (isMethod() && !isConstructor() && (flags & CASE) != 0)
+ return owner.info().lookup(name.toTypeName()).constructor();
+ }
+ */
+
public final boolean isAbstractClass() {
return (flags & ABSTRACTCLASS) != 0 &&
this != Global.instance.definitions.ARRAY_CLASS;
@@ -542,7 +549,7 @@ public abstract class Symbol implements Modifiers, Kinds {
throw new CyclicReference(this, info);
}
flags |= LOCKED;
- //System.out.println("completing " + this);//DEBUG
+ //System.out.println("completing " + this.name);//DEBUG
info.complete(this);
flags = flags & ~LOCKED;
if (info instanceof SourceCompleter && (flags & SNDTIME) == 0) {
@@ -553,7 +560,7 @@ public abstract class Symbol implements Modifiers, Kinds {
assert !(rawInfoAt(id) instanceof Type.LazyType) : this;
flags |= INITIALIZED;
}
- //System.out.println("done: " + this);//DEBUG
+ //System.out.println("done: " + this.name);//DEBUG
}
return rawInfoAt(id);
}
@@ -741,6 +748,7 @@ public abstract class Symbol implements Modifiers, Kinds {
closurePos(c) >= 0 ||
this == Global.instance.definitions.ALL_CLASS ||
(this == Global.instance.definitions.ALLREF_CLASS &&
+ c != Global.instance.definitions.ALL_CLASS &&
c.isSubClass(Global.instance.definitions.ANYREF_CLASS));
}
@@ -914,8 +922,10 @@ public abstract class Symbol implements Modifiers, Kinds {
owner.thisType().memberType(that));
}
+ /** Reset symbol to initial state
+ */
public void reset(Type completer) {
- this.flags &= (FINAL | MODUL);
+ this.flags &= SOURCEFLAGS;
this.pos = 0;
this.infos = TypeIntervalList.EMPTY;
this.setInfo(completer);
@@ -942,7 +952,7 @@ public class TermSymbol extends Symbol {
}
public static TermSymbol newJavaConstructor(Symbol clazz) {
- return newConstructor(clazz, clazz.flags & (ACCESSFLAGS | QUALIFIED | JAVA));
+ return newConstructor(clazz, clazz.flags & (ACCESSFLAGS | JAVA));
}
public static TermSymbol newModule(int pos, Name name, Symbol owner, int flags) {
diff --git a/sources/scalac/symtab/Type.java b/sources/scalac/symtab/Type.java
index 471c206b9c..33d509c55c 100644
--- a/sources/scalac/symtab/Type.java
+++ b/sources/scalac/symtab/Type.java
@@ -305,6 +305,7 @@ public class Type implements Modifiers, Kinds, TypeTags {
lb = pre.memberLoBound(sym);
}
if (lb.symbol() == Global.instance.definitions.ALL_CLASS &&
+ this.symbol() != Global.instance.definitions.ALL_CLASS &&
this.isSubType(Global.instance.definitions.ANYREF_TYPE)) {
lb = Global.instance.definitions.ALLREF_TYPE;
}
@@ -1389,8 +1390,9 @@ public class Type implements Modifiers, Kinds, TypeTags {
return that.isSubType(Global.instance.definitions.ANY_TYPE);
else if (sym == Global.instance.definitions.ALLREF_CLASS)
return
- that.isSameAs(Global.instance.definitions.ANY_TYPE) ||
- that.isSubType(Global.instance.definitions.ANYREF_TYPE);
+ that.symbol() == Global.instance.definitions.ANY_CLASS ||
+ (that.symbol() != Global.instance.definitions.ALL_CLASS &&
+ that.isSubType(Global.instance.definitions.ANYREF_TYPE));
break;
case OverloadedType(Symbol[] alts, Type[] alttypes):
diff --git a/sources/scalac/typechecker/Analyzer.java b/sources/scalac/typechecker/Analyzer.java
index 03377ef78c..abb6b7067f 100644
--- a/sources/scalac/typechecker/Analyzer.java
+++ b/sources/scalac/typechecker/Analyzer.java
@@ -9,12 +9,11 @@
// todo: (0) propagate target type in cast.
// todo: eliminate Typed nodes.
// todo: use SELECTOR flag to avoid access methods for privates
-// todo: drop requirement that only abstract classes can have abstract
-// type members.
// todo: use mangled name or drop.
// todo: emit warnings for unchecked.
// todo: qualified super.
// todo: pattern definitions with 0 or 1 bound variable.
+// todo: phase sync
package scalac.typechecker;
@@ -259,6 +258,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
void validate(Symbol sym) {
checkNoConflict(sym, DEFERRED, PRIVATE);
checkNoConflict(sym, FINAL, PRIVATE);
+ checkNoConflict(sym, FINAL, SEALED);
checkNoConflict(sym, PRIVATE, PROTECTED);
checkNoConflict(sym, PRIVATE, OVERRIDE);
checkNoConflict(sym, DEFERRED, FINAL);
@@ -331,6 +331,8 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
" does not conform to " + parents[i] + "'s supertype");
}
if ((bsym.flags & FINAL) != 0) {
+ error(constrs[i].pos, "illegal inheritance from final class");
+ } else if ((bsym.flags & SEALED) != 0) {
// are we in same scope as base type definition?
Scope.Entry e = context.scope.lookupEntry(bsym.name);
if (e.sym != bsym || e.owner != context.scope) {
@@ -339,7 +341,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
while (c != Context.NONE && c.owner != bsym)
c = c.outer;
if (c == Context.NONE) {
- error(constrs[i].pos, "illegal inheritance from final class");
+ error(constrs[i].pos, "illegal inheritance from sealed class");
}
}
}
@@ -880,6 +882,8 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
this.mode = EXPRmode;
Type savedPt = this.pt;
this.pt = Type.AnyType;
+ int savedId = global.currentPhase.id;
+ global.currentPhase.id = descr.id;
try {
Symbol sym = tree.symbol();
@@ -942,8 +946,8 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
}
popContext();
}
+ //checkNonCyclic(tree.pos, tpe.type);
owntype = tpe.type;
- checkNonCyclic(tree.pos, owntype);
break;
case DefDef(int mods, Name name, Tree.TypeDef[] tparams, Tree.ValDef[][] vparams, Tree tpe, Tree rhs):
@@ -959,7 +963,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
}
Type restype = checkNoEscape(tpe.pos, tpe.type);
popContext();
- checkNonCyclic(tree.pos, restype);
+ //checkNonCyclic(tree.pos, tpe.type);
owntype = makeMethodType(tparamSyms, vparamSyms, restype);
//System.out.println("methtype " + name + ":" + owntype);//DEBUG
break;
@@ -978,13 +982,21 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
owntype = rhs.type;
popContext();
}
- checkNonCyclic(tree.pos, owntype);
+ //checkNonCyclic(tree.pos, owntype);
break;
case Import(Tree expr, Name[] selectors):
((Import) tree).expr = expr = transform(expr, EXPRmode | QUALmode);
checkStable(expr);
owntype = expr.type;
+ Type tp = owntype.widen();
+ for (int i = 0; i < selectors.length; i = i + 2) {
+ if (selectors[i] != Names.WILDCARD &&
+ tp.lookup(selectors[i]) == Symbol.NONE &&
+ tp.lookup(selectors[i].toTypeName()) == Symbol.NONE &&
+ tp.lookup(selectors[i].toConstrName()) == Symbol.NONE)
+ error(tree.pos, selectors[i] + " is not a member of " + expr);
+ }
break;
default:
@@ -1003,6 +1015,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
this.context = savedContext;
this.mode = savedMode;
this.pt = savedPt;
+ global.currentPhase.id = savedId;
}
/** Definition phase for a template. This enters all symbols in template
@@ -1660,6 +1673,9 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
rhs1 = transform(rhs, EXPRmode, tpe.type);
popContext();
}
+ sym.flags |= LOCKED;
+ checkNonCyclic(tree.pos, tpe.type);
+ sym.flags &= ~LOCKED;
return copy.ValDef(tree, sym, tpe, rhs1)
.setType(definitions.UNIT_TYPE);
@@ -1673,10 +1689,14 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
if (rhs != Tree.Empty)
rhs1 = transform(rhs, EXPRmode, tpe.type);
popContext();
+ sym.flags |= LOCKED;
+ checkNonCyclic(tree.pos, tpe.type);
+ sym.flags &= ~LOCKED;
return copy.DefDef(tree, sym, tparams1, vparams1, tpe, rhs1)
.setType(definitions.UNIT_TYPE);
case TypeDef(_, _, _, _):
+ checkNonCyclic(tree.pos, sym.type());
return tree
.setType(definitions.UNIT_TYPE);
@@ -2073,23 +2093,30 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
infer.applyErrorMsg(
"", fn1, " cannot be applied to ", argtypes, pt));
- case Super(Tree tpe):
- Symbol enclClazz = context.enclClass.owner;
- if (enclClazz != null) {
- // we are in a class or module
- Tree tpe1 = transform(tpe, TYPEmode); // ignored for now.
- switch (enclClazz.info()) {
- case CompoundType(Type[] parents, _):
- return copy.Super(tree, tpe1)
- .setType(Type.compoundType(parents, Scope.EMPTY).symbol().thisType());
- case ErrorType:
- return tree.setType(Type.ErrorType);
- default:
- throw new ApplicationError();
+ case Super(Tree qual):
+ Symbol clazz;
+ Tree qual1;
+ if (qual == Tree.Empty) {
+ clazz = context.enclClass.owner;
+ if (clazz != null) {
+ qual1 = gen.Ident(tree.pos, clazz);
+ } else {
+ return error(
+ tree.pos,
+ "super can be used only in a class, object, or template");
}
} else {
- return error(tree.pos,
- "super can be used only in a class, object, or template");
+ qual1 = transform(qual, TYPEmode | FUNmode);
+ clazz = qual1.symbol();
+ }
+ switch (clazz.info()) {
+ case CompoundType(Type[] parents, _):
+ return copy.Super(tree, qual1)
+ .setType(Type.compoundType(parents, Scope.EMPTY).symbol().thisType());
+ case ErrorType:
+ return tree.setType(Type.ErrorType);
+ default:
+ return error(qual.pos, "class identifier expected");
}
case This(Tree qual):
diff --git a/sources/scalac/util/Names.java b/sources/scalac/util/Names.java
index 0b224b9758..9e338d9d4d 100644
--- a/sources/scalac/util/Names.java
+++ b/sources/scalac/util/Names.java
@@ -21,7 +21,6 @@ public class Names {
public static final Name _EQ = encode("_=");
public static final Name MINUS = encode("-");
public static final Name PLUS = encode("+");
- public static final Name ASTERISK = encode("*");
public static final Name TILDE = encode("~");
public static final Name EQEQ = encode("==");
public static final Name BANG = encode("!");
diff --git a/support/latex/verbfilterScala.java b/support/latex/verbfilterScala.java
index 5c8cf85d13..b8db2fb6e9 100644
--- a/support/latex/verbfilterScala.java
+++ b/support/latex/verbfilterScala.java
@@ -8,8 +8,9 @@ public class verbfilterScala {
"abstract", "as", "case", "class", "constr", "def", "do", "else",
"extends", "false", "final", "for", "if", "import",
"is", "new", "null", "object", "override", "package",
- "private", "protected", "super", "this", "trait",
- "true", "type", "val", "var", "with", "yield"};
+ "private", "protected", "sealed", "super", "this",
+ "trait", "true", "type", "val", "var",
+ "with", "yield"};
static final int TABINC = 8;
diff --git a/test/files/neg/S6.check b/test/files/neg/S6.check
index 6303e4c8e2..0647138103 100644
--- a/test/files/neg/S6.check
+++ b/test/files/neg/S6.check
@@ -1,4 +1,4 @@
-S6.scala:11: illegal cyclic reference involving type S
+S6.scala:11: cyclic aliasing or subtyping involving type S
type S <: T;
^
one error found
diff --git a/test/files/neg/seqtest.check b/test/files/neg/seqtest.check
index d3a04e8e51..42d3a71a9c 100644
--- a/test/files/neg/seqtest.check
+++ b/test/files/neg/seqtest.check
@@ -1,6 +1,7 @@
seqtest.scala:11: ambiguous reference to overloaded definition,
both method L: [a](scala.Seq[a])scala.Seq[a]
-and method L: [a](a*)scala.Seq[a] match.
+and method L: [a](a*)scala.Seq[a]
+match argument types (scala.Seq[scala.Int])
val c = L(a);
^
one error found
diff --git a/test/files/pos/imports.scala b/test/files/pos/imports.scala
index 32b7aace62..65ea090436 100644
--- a/test/files/pos/imports.scala
+++ b/test/files/pos/imports.scala
@@ -1,7 +1,5 @@
package test;
-
-
import java.lang.{System => S}
object test {
diff --git a/test/neg/S6.check b/test/neg/S6.check
index 6303e4c8e2..0647138103 100644
--- a/test/neg/S6.check
+++ b/test/neg/S6.check
@@ -1,4 +1,4 @@
-S6.scala:11: illegal cyclic reference involving type S
+S6.scala:11: cyclic aliasing or subtyping involving type S
type S <: T;
^
one error found
diff --git a/test/neg/seqtest.check b/test/neg/seqtest.check
index d3a04e8e51..42d3a71a9c 100644
--- a/test/neg/seqtest.check
+++ b/test/neg/seqtest.check
@@ -1,6 +1,7 @@
seqtest.scala:11: ambiguous reference to overloaded definition,
both method L: [a](scala.Seq[a])scala.Seq[a]
-and method L: [a](a*)scala.Seq[a] match.
+and method L: [a](a*)scala.Seq[a]
+match argument types (scala.Seq[scala.Int])
val c = L(a);
^
one error found
diff --git a/test/pos/imports.scala b/test/pos/imports.scala
index 32b7aace62..65ea090436 100644
--- a/test/pos/imports.scala
+++ b/test/pos/imports.scala
@@ -1,7 +1,5 @@
package test;
-
-
import java.lang.{System => S}
object test {