summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/reference/reference.verb.tex154
-rw-r--r--sources/scala/tools/scalai/Environment.java2
-rw-r--r--sources/scalac/Global.java3
-rw-r--r--sources/scalac/ast/parser/SourceRepresentation.java14
-rw-r--r--sources/scalac/symtab/EntryTags.java2
-rw-r--r--sources/scalac/symtab/SourceCompleter.java15
-rw-r--r--sources/scalac/symtab/Symbol.java90
-rw-r--r--sources/scalac/symtab/SymbolTablePrinter.java2
-rw-r--r--sources/scalac/symtab/classfile/PackageParser.java7
-rw-r--r--sources/scalac/symtab/classfile/Pickle.java5
-rw-r--r--sources/scalac/symtab/classfile/SymblParser.java7
-rw-r--r--sources/scalac/symtab/classfile/UnPickle.java114
-rw-r--r--sources/scalac/transformer/ExpandMixinsPhase.java1
-rw-r--r--sources/scalac/typechecker/Analyzer.java253
-rw-r--r--sources/scalac/util/ClassPath.java13
-rw-r--r--test/files/pos/cls1.scala2
-rw-r--r--test/files/pos/michel1.scala2
-rw-r--r--test/pos/cls1.scala2
-rw-r--r--test/pos/michel1.scala2
19 files changed, 463 insertions, 227 deletions
diff --git a/doc/reference/reference.verb.tex b/doc/reference/reference.verb.tex
index d7737dd004..ababae0d54 100644
--- a/doc/reference/reference.verb.tex
+++ b/doc/reference/reference.verb.tex
@@ -1245,13 +1245,13 @@ d.hours = 25; \=// throws a DateError exception
\label{sec:typealias}
\syntax\begin{verbatim}
- Dcl \=::= \= type TypeDcl {`,' TypeDcl}
+ Dcl \=::= \= class TypeDcl {`,' TypeDcl}
TypeDcl \>::= \> Id [>: Type] [<: Type]
Def \>::= \> type TypeDef {`,' TypeDef}
TypeDef \>::= \> Id `=' Type
\end{verbatim}
-A {\em type declaration} \verb@type t >: L <: U@ declares \verb@t@ to
+A {\em type declaration} \verb@class t >: L <: U@ declares \verb@t@ to
be an abstract type with lower bound type \verb@L@ and upper bound
type \verb@U@. If such a declaration appears as a member declaration
of a type, implementations of the type may implement \verb@t@ with any
@@ -1260,7 +1260,7 @@ be omitted. If the lower bound \verb@L@ is missing, the bottom type
\verb@scala.All@ is assumed. If the upper bound \verb@U@ is missing,
the top type \verb@scala.Any@ is assumed.
-A {\em type alias} \verb@type t = T@ defines \verb@t@ to be an alias
+A {\em type alias} \verb@class t = T@ defines \verb@t@ to be an alias
name for the type \verb@T@. Type declarations and type aliases are
collectively called {\em type bindings}.
@@ -1268,30 +1268,46 @@ The scope rules for definitions (\sref{sec:defs}) and type parameters
(\sref{sec:funsigs}) make it possible that a type name appears in its
own bound or in its right-hand side. However, it is a static error if
a type alias refers recursively to the defined type itself. That is,
-the type \verb@T@ in a type alias \verb@type t = T@ may not refer
+the type \verb@T@ in a type alias \verb@class t = T@ may not refer
directly or indirectly to the name \verb@t@. It is also an error if
an abstract type is directly or indirectly its own bound.
\example The following are legal type declarations and definitions:
\begin{verbatim}
-type IntList = List[Integer];
-type T extends Comparable[T];
+class IntList = List[Integer];
+class T extends Comparable[T];
\end{verbatim}
The following are illegal:
\begin{verbatim}
-type Abs = Comparable[Abs]; \=// recursive type alias
+class Abs = Comparable[Abs]; \=// recursive type alias
-type S <: T; \>// S, T are bounded by themselves.
-type T <: S;
+class S <: T; \>// S, T are bounded by themselves.
+class T <: S;
-type T <: Object with T; \>// T is abstract, may not be part of
+class T <: Object with T; \>// T is abstract, may not be part of
\>// compound type
-type T >: Comparable[T.That]; \>// Cannot select from T.
+class T >: Comparable[T.That]; \>// Cannot select from T.
\>// T is a type, not a value
\end{verbatim}
+Neither type declarations nor type aliases may carry type
+parameters. However, it is possible to alias a type constructor of a
+parameterized type, as is shown in the following example.
+
+\example The \verb@Predef@ module contains a definition which establishes \verb@Pair@
+as an alias of the parameterized class \verb@Tuple2@:
+\begin{verbatim}
+class Pair = Tuple2;
+\end{verbatim}
+As a consequence, for any two types \verb@S@ and \verb@T@, the type
+\verb@Pair[S, T]@ is equivalent to the type \verb@Tuple2[S, T]@.
+\verb@Pair@ can also be used as a constructor instead of \verb@Tuple2@, as in
+\begin{verbatim}
+new Pair[Int, Int](1, 2) .
+\end{verbatim}
+
\section{Function Declarations and Definitions}
\label{sec:defdef}
\label{sec:funsigs}
@@ -1836,13 +1852,13 @@ Here,
\begin{itemize}
\item[]
\verb@c@ is the name of the class to be defined.
-\item[]
-\verb@tps@ is a non-empty list of type parameters of the class being
-defined. The scope of a type parameter is the whole class definition,
-including the type parameter section itself. It is illegal to define
-two type parameters with the same name. The type parameter section
-\verb@[tps]@ may be omitted. A class with a type parameter section is
-called {\em polymorphic}, otherwise it is called {\em monomorphic}.
+\item[] \verb@tps@ is a non-empty list of type parameters of the class
+being defined. The scope of a type parameter is the whole class
+definition including the type parameter section itself. It is
+illegal to define two type parameters with the same name. The type
+parameter section \verb@[tps]@ may be omitted. A class with a type
+parameter section is called {\em polymorphic}, otherwise it is called
+{\em monomorphic}.
\item[]
\verb@ps@ is a formal parameter clause for the {\em primary
constructor} of the class. The scope of a formal parameter includes
@@ -1879,7 +1895,7 @@ initializes instances of type \verb@c[tps]@ by evaluating the template
\syntax\begin{verbatim}
FunDef \=::=\= this ParamClause `=' ConstrExpr
ConstrExpr \>::=\> this ArgumentExpr
- \> |\> `{' {BlockStat `;'} ConstrExpr {`;' Blockstat} `}'
+ \> |\> `{' {BlockStat `;'} ConstrExpr `}'
\end{verbatim}
A class may have additional constructors besides the primary
@@ -1890,10 +1906,13 @@ formal parameter list \verb@ps@, and whose evaluation is defined by
the constructor expression \verb@e@. The scope of each formal
parameter is the constructor expression \verb@e@. A constructor
expression is either a self constructor invocation \verb@this(args)@
-or a block which contains a constructor expression as one of its
-statements. A constructor expression may not refer to \verb@this@,
-nor to any of the value parameters or members of the object being
-constructed, until after the self constructor has been called.
+or a block which ends in a constructor expression. In terms of
+visibility rules, constructor definitions are conceptually outside
+their enclosing class. Hence, they can access neither value
+parameters nor members of the enclosing class by simple name, and the
+value \verb@this@ refers to an object of the class enclosing the class
+of the object being constructed. However, constructor definitions can
+access type parameters of the enclosing class.
If there are auxilary constructors of a class \verb@C@, they define
together with \verb@C@'s primary constructor an overloaded constructor
@@ -1906,11 +1925,31 @@ invocation must refer to a constructor definition which precedes it
(i.e. it must refer to either a preceding auxiliary constructor or the
primary constructor of the class). The type of a constructor
expression must be always so that a generic instance of the class is
-constructed. I.e. if the class in question has name \verb@C@ and type
+constructed. I.e., if the class in question has name \verb@C@ and type
parameters \verb@[tps]@, then each constructor must construct an
instance of \verb@C[tps]@; it is not permitted to instantiate formal
type parameters.
+\example Consider the class definition
+
+\begin{verbatim}
+class LinkedList[a <: AnyRef](x: a, xs: LinkedList[a]) {
+ var head = x;
+ var tail = xs;
+ def isEmpty = tail != null;
+ def this() = this(null, null);
+ def this(x: a) = { val empty = new LinkedList(); this(x, empty) }
+}
+\end{verbatim}
+This defines a class \verb@LinkedList@ with an overloaded constructor of type
+\begin{verbatim}
+[a <: AnyRef](x: a, xs: LinkList[a]): LinkedList[a] $\overload$
+[a <: AnyRef](): LinkedList[a] $\overload$
+[a <: AnyRef](x: a): LinkedList[a] .
+\end{verbatim}
+The second constructor alternative constructs an empty list, while the
+third one constructs a list with one element.
+
\subsection{Case Classes}
\label{sec:case-classes}
@@ -2159,7 +2198,7 @@ module FileSystem with {
\> |\> for `(' Enumerators `)' (do | yield) Expr
\> |\> [SimpleExpr `.'] Id `=' Expr
\> |\> SimpleExpr ArgumentExpr `=' Expr
- \> |\> PostfixExpr [`:' Type1 | as Type1 | is Type1]
+ \> |\> PostfixExpr [`:' Type1]
PostfixExpr \>::=\> InfixExpr [Id]
InfixExpr \>::=\> PrefixExpr
\> |\> InfixExpr Id InfixExpr
@@ -2186,6 +2225,39 @@ discussed subsequently in decreasing order of precedence.
Typing and evaluation of literals are analogous to Java.
+\section{Boolean constants}
+
+\begin{verbatim}
+ SimpleExpr \=::= \= true | false
+\end{verbatim}
+
+The boolean truth values are denoted by the reserved words \verb@true@
+and \verb@false@. The type of these expressions is \verb@boolean@, and
+their evaluation is immediate.
+
+\section{The $\NULL$ Reference}
+
+\syntax\begin{verbatim}
+ SimpleExpr \=::= \= null
+\end{verbatim}
+
+The \verb@null@ expression is of type \verb@scala.AllRef@. It
+denotes a reference value which refers to a special ``null' object,
+which implements methods in class \verb@scala.AnyRef@ as follows:
+\begin{itemize}
+\item[]
+\verb@eq(x)@, \verb@==(x)@, \verb@equals(x)@ return \verb@true@ iff their
+argument \verb@x@ is also the ``null'' object.
+\item[]
+\verb@isInstance[T]@ always returns \verb@false@.
+\item[]
+\verb@asInstance[T]@ always returns the ``null'' object itself.
+\item[]
+\verb@toString@ returns the string ``\verb@null@''.
+\end{itemize}
+A reference to any other member of the ``null'' object causes a
+ \verb@NullPointerException@ to be thrown.
+
\section{Designators}
\label{sec:designators}
@@ -2206,30 +2278,6 @@ The selection $e.x$ is evaluated by first evaluating the qualifier
expression $e$. The selection's result is then the value to which the
selector identifier is bound in the selected object designated by $e$.
-\section{The $\NULL$ Reference}
-
-\syntax\begin{verbatim}
- SimpleExpr \=::= \= null
-\end{verbatim}
-
-The reserved word \verb@null@ refers to a polymorphic parameterless
-function of type \verb@[a extends scala.AnyRef]a@. Its result is the
-special ``null'' object, which implements methods in class
-\verb@scala.AnyRef@ as follows:
-\begin{itemize}
-\item[]
-\verb@eq(x)@, \verb@==(x)@, \verb@equals(x)@ return \verb@True@ iff their
-argument \verb@x@ is also the ``null'' object.
-\item[]
-\verb@is[T]@ always returns \verb@False@.
-\item[]
-\verb@as[T]@ always returns the ``null'' object itself.
-\item[]
-\verb@toString@ returns the string ``\verb@null@''.
-\end{itemize}
-A reference to any member of the ``null'' object which is not defined in class
-\verb@Object@ causes a \verb@NullPointerException@ to be thrown.
-
\section{This and Super}
\label{sec:this-super}
@@ -4157,9 +4205,6 @@ grammar.
\> |\> charLit
\> |\> stringLit
\> |\> symbolLit
- \> |\> true
- \> |\> false
- \> |\> null
Id \>::=\> id | `+' | `-' | `!'
QualId \>::=\> Id {`.' Id}
@@ -4198,12 +4243,15 @@ grammar.
\> |\> for `(' Enumerators `)' (do | yield) Expr
\> |\> [SimpleExpr `.'] Id `=' Expr
\> |\> SimpleExpr ArgumentExpr `=' Expr
- \> |\> PostfixExpr [`:' Type1 | as Type1 | is Type1]
+ \> |\> PostfixExpr [`:' Type1]
PostfixExpr \>::=\> InfixExpr [Id]
InfixExpr \>::=\> PrefixExpr
\> |\> InfixExpr Id InfixExpr
PrefixExpr \>::=\> [`-' | `+' | `~' | `!'] SimpleExpr
SimpleExpr \>::=\> literal
+ \> |\> true
+ \> |\> false
+ \> |\> null
\> |\> Path
\> |\> `(' [Expr] `)'
\> |\> BlockExpr
diff --git a/sources/scala/tools/scalai/Environment.java b/sources/scala/tools/scalai/Environment.java
index 9174e31be8..a5ae958990 100644
--- a/sources/scala/tools/scalai/Environment.java
+++ b/sources/scala/tools/scalai/Environment.java
@@ -152,7 +152,7 @@ public class Environment {
private void loadOwner(String what, Symbol symbol) {
assert Debug.log("search ", what, ": ", symbol);
assert symbol.owner().isType() : Debug.show(symbol);
- assert!symbol.owner().isJava() : Debug.show(symbol);
+ assert!symbol.owner().isJava() : symbol;
loadTemplate(symbol.owner());
}
diff --git a/sources/scalac/Global.java b/sources/scalac/Global.java
index 36c25ce503..7b68fa43d5 100644
--- a/sources/scalac/Global.java
+++ b/sources/scalac/Global.java
@@ -315,8 +315,7 @@ public class Global {
imports.clear();
for (Iterator it = compiledNow.keySet().iterator(); it.hasNext();) {
Symbol sym = (Symbol) it.next();
- SourceFile f = (SourceFile) compiledNow.get(sym);
- sym.reset(new SourceCompleter(this, f.name()));
+ sym.reset(new SourceCompleter(this));
}
}
compiledNow.clear();
diff --git a/sources/scalac/ast/parser/SourceRepresentation.java b/sources/scalac/ast/parser/SourceRepresentation.java
index 2a20e13fab..4218bc2ead 100644
--- a/sources/scalac/ast/parser/SourceRepresentation.java
+++ b/sources/scalac/ast/parser/SourceRepresentation.java
@@ -8,6 +8,9 @@
package scalac.ast.parser;
+import java.io.File;
+import scalac.util.Name;
+
public final class SourceRepresentation {
public static int digit2int(byte ch, int base) {
@@ -202,4 +205,15 @@ public final class SourceRepresentation {
char[] s = {c};
return escape(new String(s));
}
+
+ /** return external representation of file name s,
+ * converting '.' to File.separatorChar
+ */
+ public static String externalizeFileName(Name n) {
+ if ((n == null) || (n.length() == 0))
+ return ".";
+ byte[] ascii = n.toAscii();
+ String s = ascii2string(ascii, 0, ascii.length);
+ return s.replace('.', File.separatorChar);
+ }
}
diff --git a/sources/scalac/symtab/EntryTags.java b/sources/scalac/symtab/EntryTags.java
index 41e71464ac..512027944b 100644
--- a/sources/scalac/symtab/EntryTags.java
+++ b/sources/scalac/symtab/EntryTags.java
@@ -30,7 +30,7 @@ public interface EntryTags {
* | 15 METHODtpe len_Nat tpe_Ref {tpe_Ref}
* | 16 POLYTtpe len_Nat tpe_Ref {sym_Ref}
* | 17 OVERLOADEDtpe len_Nat {sym_Ref} {tpe_Ref}
- * | 20 FLAGGEDtype len_Nat flags_Nat tpe_Ref
+ * | 20 FLAGGEDtpe len_Nat flags_Nat tpe_Ref
* SymbolInfo = name_Ref owner_Ref flags_Nat info_Ref
* NameInfo = <character sequence of length len_Nat in Utf8 format>
* Ref = Nat
diff --git a/sources/scalac/symtab/SourceCompleter.java b/sources/scalac/symtab/SourceCompleter.java
index cf4938ccde..f835160b50 100644
--- a/sources/scalac/symtab/SourceCompleter.java
+++ b/sources/scalac/symtab/SourceCompleter.java
@@ -21,12 +21,10 @@ public class SourceCompleter extends Type.LazyType {
/** the global compilation environment
*/
protected Global global;
- protected String filename;
private boolean completed = false;
- public SourceCompleter(Global global, String filename) {
+ public SourceCompleter(Global global) {
this.global = global;
- this.filename = filename;
}
/** complete class symbol c by loading the unit
@@ -34,15 +32,16 @@ public class SourceCompleter extends Type.LazyType {
public void complete(Symbol c) {
if (completed) {
c.setInfo(Type.NoType);
- } else if (filename != null) {
+ } else {
try {
- String fname = filename;
long msec = System.currentTimeMillis();
- Unit unit = new Unit(global, new SourceFile(filename), false);
- filename = null;
+ String filename = SourceRepresentation.externalizeFileName(
+ c.fullName()) + ".scala";
+ java.io.File f = global.classPath.openJavaFile(filename);
+ Unit unit = new Unit(global, new SourceFile(f), false);
global.PHASE.PARSER.apply(unit);
global.PHASE.ANALYZER.lateEnter(global, unit, c);
- global.operation("added " + fname + " in " +
+ global.operation("added " + filename + " in " +
(System.currentTimeMillis() - msec) + "ms");
} catch (IOException e) {
e.printStackTrace();
diff --git a/sources/scalac/symtab/Symbol.java b/sources/scalac/symtab/Symbol.java
index 6f1444f827..280d3f73e6 100644
--- a/sources/scalac/symtab/Symbol.java
+++ b/sources/scalac/symtab/Symbol.java
@@ -71,6 +71,12 @@ public abstract class Symbol implements Modifiers, Kinds {
this.flags = flags & ~(INITIALIZED | LOCKED); // safety first
}
+ protected void update(int pos, int flags) {
+ this.pos = pos;
+ this.flags = (flags & ~(INITIALIZED | LOCKED)) |
+ (this.flags & (INITIALIZED | LOCKED));
+ }
+
/** Return a fresh symbol with the same fields as this one.
*/
public final Symbol cloneSymbol() {
@@ -631,7 +637,7 @@ public abstract class Symbol implements Modifiers, Kinds {
throw new CyclicReference(this, info);
}
flags |= LOCKED;
- //System.out.println("completing " + this.name);//DEBUG
+ //System.out.println("completing " + this);//DEBUG
info.complete(this);
flags = flags & ~LOCKED;
if (info instanceof SourceCompleter && (flags & SNDTIME) == 0) {
@@ -642,7 +648,7 @@ public abstract class Symbol implements Modifiers, Kinds {
assert !(rawInfoAt(id) instanceof Type.LazyType) : this;
//flags |= INITIALIZED;
}
- //System.out.println("done: " + this.name);//DEBUG
+ //System.out.println("done: " + this);//DEBUG
}
return rawInfoAt(id);
}
@@ -666,6 +672,7 @@ public abstract class Symbol implements Modifiers, Kinds {
/** get info at phase #id, without forcing lazy types.
*/
public Type rawInfoAt(int id) {
+ //if (infos == TypeIntervalList.EMPTY) return Type.NoType;//DEBUG
assert infos != TypeIntervalList.EMPTY : this;
int nextid = infos.limit;
if (nextid < id) {
@@ -1009,6 +1016,18 @@ public class TermSymbol extends Symbol {
super(VAL, pos, name, owner, flags);
}
+ public static TermSymbol define(
+ int pos, Name name, Symbol owner, int flags, Scope scope) {
+ Scope.Entry e = scope.lookupEntry(name);
+ if (e.owner == scope && e.sym.pos == Position.NOPOS && e.sym.kind == VAL) {
+ TermSymbol sym = (TermSymbol) e.sym;
+ sym.update(pos, flags);
+ return sym;
+ } else {
+ return new TermSymbol(pos, name, owner, flags);
+ }
+ }
+
public static TermSymbol newConstructor(Symbol clazz, int flags) {
TermSymbol sym = new TermSymbol(
clazz.pos, clazz.name, clazz.owner(), flags | FINAL);
@@ -1020,30 +1039,28 @@ public class TermSymbol extends Symbol {
return newConstructor(clazz, clazz.flags & (ACCESSFLAGS | JAVA));
}
- public static TermSymbol newModule(int pos, Name name, Symbol owner,
- int flags, ClassSymbol clazz) {
- TermSymbol sym = new TermSymbol(pos, name, owner, flags | MODUL | FINAL);
- sym.clazz = clazz;
- clazz.setModule(sym);
- sym.setInfo(clazz.typeConstructor());
- return sym;
+ public TermSymbol makeModule(ClassSymbol clazz) {
+ flags |= MODUL | FINAL;
+ this.clazz = clazz;
+ clazz.setModule(this);
+ setInfo(clazz.typeConstructor());
+ return this;
}
- public static TermSymbol newModule(int pos, Name name, Symbol owner,
- int flags) {
+ public TermSymbol makeModule() {
ClassSymbol clazz = new ClassSymbol(
- pos, name.toTypeName(), owner, flags | MODUL | FINAL);
+ pos, name.toTypeName(), owner(), flags | MODUL | FINAL);
clazz.primaryConstructor().setInfo(
Type.MethodType(Symbol.EMPTY_ARRAY, clazz.typeConstructor()));
-
- return newModule(pos, name, owner, flags, clazz);
+ return makeModule(clazz);
}
/** Constructor for companion modules to classes, which need to be completed.
*/
public static TermSymbol newCompanionModule(Symbol clazz, int flags, Type.LazyType parser) {
- TermSymbol sym = newModule(Position.NOPOS, clazz.name.toTermName(), clazz.owner(),
- flags);
+ TermSymbol sym = new TermSymbol(
+ Position.NOPOS, clazz.name.toTermName(), clazz.owner(), flags)
+ .makeModule();
sym.clazz.setInfo(parser);
return sym;
}
@@ -1051,7 +1068,8 @@ public class TermSymbol extends Symbol {
/** Java package module constructor
*/
public static TermSymbol newJavaPackageModule(Name name, Symbol owner, Type.LazyType parser) {
- TermSymbol sym = newModule(Position.NOPOS, name, owner, JAVA | PACKAGE);
+ TermSymbol sym = new TermSymbol(Position.NOPOS, name, owner, JAVA | PACKAGE)
+ .makeModule();
sym.clazz.flags |= SYNTHETIC;
sym.clazz.setInfo(parser != null ? parser : Type.compoundType(Type.EMPTY_ARRAY, new Scope(), sym));
return sym;
@@ -1080,7 +1098,7 @@ public class TermSymbol extends Symbol {
assert !isPrimaryConstructor() : Debug.show(this);
TermSymbol other;
if (isModule()) {
- other = newModule(pos, name, owner, flags);
+ other = new TermSymbol(pos, name, owner, flags).makeModule();
} else {
other = new TermSymbol(pos, name, owner, flags);
other.clazz = clazz;
@@ -1123,6 +1141,17 @@ public class TypeSymbol extends Symbol {
super(kind, pos, name, owner, flags);
}
+ public static TypeSymbol define(
+ int pos, Name name, Symbol owner, int flags, Scope scope) {
+ Scope.Entry e = scope.lookupEntry(name);
+ if (e.owner == scope && e.sym.pos == Position.NOPOS && e.sym.kind == ALIAS) {
+ TypeSymbol sym = (TypeSymbol) e.sym;
+ sym.update(pos, flags);
+ return sym;
+ } else {
+ return new TypeSymbol(ALIAS, pos, name, owner, flags);
+ }
+ }
/** Return a fresh symbol with the same fields as this one.
*/
@@ -1283,6 +1312,18 @@ public class AbsTypeSymbol extends TypeSymbol {
super(TYPE, pos, name, owner, flags);
}
+ public static AbsTypeSymbol define(
+ int pos, Name name, Symbol owner, int flags, Scope scope) {
+ Scope.Entry e = scope.lookupEntry(name);
+ if (e.owner == scope && e.sym.pos == Position.NOPOS && e.sym.kind == TYPE) {
+ AbsTypeSymbol sym = (AbsTypeSymbol) e.sym;
+ sym.update(pos, flags);
+ return sym;
+ } else {
+ return new AbsTypeSymbol(pos, name, owner, flags);
+ }
+ }
+
/** Return a fresh symbol with the same fields as this one.
*/
public Symbol cloneSymbol(Symbol owner) {
@@ -1356,6 +1397,19 @@ public class ClassSymbol extends TypeSymbol {
this.mangled = name;
}
+ public static ClassSymbol define(
+ int pos, Name name, Symbol owner, int flags, Scope scope) {
+ Scope.Entry e = scope.lookupEntry(name);
+ if (e.owner == scope && e.sym.pos == Position.NOPOS && e.sym.kind == CLASS) {
+ ClassSymbol sym = (ClassSymbol) e.sym;
+ sym.update(pos, flags);
+ sym.template = null;
+ return sym;
+ } else {
+ return new ClassSymbol(pos, name, owner, flags);
+ }
+ }
+
/** Constructor for classes to load as source files
*/
public ClassSymbol(Name name, Symbol owner, SourceCompleter parser) {
diff --git a/sources/scalac/symtab/SymbolTablePrinter.java b/sources/scalac/symtab/SymbolTablePrinter.java
index e934073e94..a28abc9457 100644
--- a/sources/scalac/symtab/SymbolTablePrinter.java
+++ b/sources/scalac/symtab/SymbolTablePrinter.java
@@ -337,6 +337,7 @@ public class SymbolTablePrinter {
/** Prints the full name of the given symbol */
public SymbolTablePrinter printSymbolFullName(Symbol symbol) {
print(getSymbolFullName(symbol));
+ //print("{" + symbol.owner() + "}");//DEBUG
return printSymbolUniqueId(symbol);
}
@@ -514,6 +515,7 @@ public class SymbolTablePrinter {
return printTemplateType(pre.memberInfo(sym).parents());
}
printPrefix(pre).printSymbolName(sym);
+ //print("{" + sym.owner() + "}");//DEBUG
if (args.length != 0) print('[').printTypes(args, ",").print(']');
return this;
case SingleType(Type pre, Symbol sym):
diff --git a/sources/scalac/symtab/classfile/PackageParser.java b/sources/scalac/symtab/classfile/PackageParser.java
index e523bc4dbb..9fdbe797ed 100644
--- a/sources/scalac/symtab/classfile/PackageParser.java
+++ b/sources/scalac/symtab/classfile/PackageParser.java
@@ -101,12 +101,13 @@ public class PackageParser extends Type.LazyType {
locals.enter(module);
locals.enter(module.moduleClass());
}
- } else if (inclClasses && global.separate && fname.endsWith(".symbl")) {
+ } else if (inclClasses && fname.endsWith(".symbl")) {
//todo: compare dates between symbl and scala.
Name n = Name.fromString(fname.substring(0, fname.length() - 6))
.toTypeName();
Symbol sym = locals.lookup(n);
if (sym == Symbol.NONE ||
+ sym.isPackage() ||
sym.rawInfoAt(Symbol.FIRST_ID) instanceof ClassParser &&
!(sym.rawInfoAt(Symbol.FIRST_ID) instanceof SymblParser)) {
ClassSymbol clazz = new ClassSymbol(n, p, symblCompletion);
@@ -121,10 +122,10 @@ public class PackageParser extends Type.LazyType {
.toTypeName();
Symbol sym = locals.lookup(n);
if (sym == Symbol.NONE ||
+ sym.isPackage() ||
sym.rawInfoAt(Symbol.FIRST_ID) instanceof ClassParser &&
!(sym.rawInfoAt(Symbol.FIRST_ID) instanceof SymblParser)) {
- SourceCompleter completer = new SourceCompleter(global,
- dir.getPath() + File.separatorChar + fname);
+ SourceCompleter completer = new SourceCompleter(global);
ClassSymbol clazz = new ClassSymbol(n, p, completer);
//todo: needed?
clazz.allConstructors().setInfo(completer);
diff --git a/sources/scalac/symtab/classfile/Pickle.java b/sources/scalac/symtab/classfile/Pickle.java
index 7deaa52675..a82962dfb5 100644
--- a/sources/scalac/symtab/classfile/Pickle.java
+++ b/sources/scalac/symtab/classfile/Pickle.java
@@ -8,6 +8,7 @@
package scalac.symtab.classfile;
+import ch.epfl.lamp.util.Position;
import java.util.HashMap;
import java.io.*;
import scalac.Global;
@@ -45,8 +46,8 @@ public class Pickle implements Kinds, Modifiers, EntryTags {
/** Pickle all symbols descending from `root'.
*/
public void add(Symbol root) {
- if (root.kind != NONE) {
- if (debug) System.out.println("adding " + root);//debug
+ if (root.pos != Position.NOPOS) {
+ if (Global.instance.debug) System.out.println("pickling " + root);
if (index.get(root) == null) {
this.rootname = root.name.toTermName();
this.rootowner = root.owner();
diff --git a/sources/scalac/symtab/classfile/SymblParser.java b/sources/scalac/symtab/classfile/SymblParser.java
index 1c2ef25618..2f8956d608 100644
--- a/sources/scalac/symtab/classfile/SymblParser.java
+++ b/sources/scalac/symtab/classfile/SymblParser.java
@@ -38,9 +38,10 @@ public class SymblParser extends ClassParser {
new UnPickle(c, data, Name.fromString(filename));
global.operation("loaded " + f.getPath() + " in " +
(System.currentTimeMillis() - msec) + "ms");
- //for (Definition e = c.locals().elems; e != null; e = e.sibling)
- // if (e.def.kind == TYP)
- // e.def.complete();
+ /*
+ if (!global.separate)
+ new SourceCompleter(global).complete(c);//for now
+ */
}
} catch (IOException e) {
e.printStackTrace();
diff --git a/sources/scalac/symtab/classfile/UnPickle.java b/sources/scalac/symtab/classfile/UnPickle.java
index 8f6b817063..de755fd7fd 100644
--- a/sources/scalac/symtab/classfile/UnPickle.java
+++ b/sources/scalac/symtab/classfile/UnPickle.java
@@ -9,6 +9,7 @@
package scalac.symtab.classfile;
import java.util.HashMap;
+import java.io.PrintStream;
import scalac.*;
import scalac.util.*;
import ch.epfl.lamp.util.Position;
@@ -60,28 +61,13 @@ public class UnPickle implements Kinds, Modifiers, EntryTags {
bp = readNat() + bp;
}
entries = new Object[index.length];
- if (global.debug) {
- global.log("length: " + index.length);
- for (int i = 0; i < index.length; i++) {
- System.out.print(i + "," + index[i] + ": ");
- bp = index[i];
- int tag = readByte();
- System.out.print(tag + " ");
- int len = readNat();
- System.out.print(len + " ");
- if (tag == TERMname || tag == TYPEname)
- System.out.print(
- SourceRepresentation.ascii2string(bytes, bp, len));
- else
- for (int j = 0; j < len; j++)
- System.out.print(readByte() + " ");
- System.out.println();
- }
- }
+
+ if (global.debug) print(System.out);
+
for (int i = 0; i < index.length; i++) {
if (isSymbolEntry(i)) getSymbol(i);
}
- if (global.debug) global.log("unpickled " + root);//debug
+ if (global.debug) global.log("unpickled " + root + ":" + root.rawInfo());//debug
if (!root.isInitialized())
throw new BadSignature(this, "it does not define " + root);
}
@@ -98,8 +84,10 @@ public class UnPickle implements Kinds, Modifiers, EntryTags {
params[0].owner() != owner && params[0].owner() != Symbol.NONE) {
params1 = new Symbol[params.length];
for (int i = 0; i < params.length; i++)
- params1[i] = params[i].cloneSymbol().setOwner(owner);
+ params1[i] = params[i].cloneSymbol();
}
+ for (int i = 0; i < params.length; i++)
+ params1[i].setOwner(owner);
Type restpe1 = setOwner(restpe, owner);
if (params1 == params && restpe1 == restpe) return tp;
else return Type.MethodType(params1, restpe1);
@@ -222,7 +210,7 @@ public class UnPickle implements Kinds, Modifiers, EntryTags {
entries[n] = sym;
if (sym.kind == NONE) {
if (global.debug)
- global.log(owner.info().members().toString());//debug
+ global.log(owner.info().members().toString());
throw new BadSignature(this,
"reference " + decode(name) + " of " + owner +
" refers to nonexisting symbol.");
@@ -232,7 +220,7 @@ public class UnPickle implements Kinds, Modifiers, EntryTags {
assert isSymbolEntry(n) : n;
Name name = readNameRef();
if (global.debug)
- global.log("reading " + name + " at " + n);//debug
+ global.log("reading " + name + " at " + n);
owner = readSymbolRef();
if (entries[n] == null) {
int flags = readNat();
@@ -241,14 +229,14 @@ public class UnPickle implements Kinds, Modifiers, EntryTags {
case TYPEsym:
entries[n] = sym = new AbsTypeSymbol(
Position.NOPOS, name, owner, flags);
- sym.setInfo(getType(inforef));
+ sym.setInfo(getType(inforef), Symbol.FIRST_ID);
sym.setLoBound(readTypeRef());
break;
case ALIASsym:
entries[n] = sym = new TypeSymbol(
ALIAS, Position.NOPOS, name, owner, flags);
- sym.setInfo(getType(inforef));
+ sym.setInfo(getType(inforef), Symbol.FIRST_ID);
break;
case CLASSsym:
@@ -261,7 +249,7 @@ public class UnPickle implements Kinds, Modifiers, EntryTags {
sym.copyTo(clr);
entries[n] = sym = clr;
}
- sym.setInfo(getType(inforef));
+ sym.setInfo(getType(inforef), Symbol.FIRST_ID);
sym.setTypeOfThis(readTypeRef());
Symbol constr = readSymbolRef();
if (constr != sym.primaryConstructor()) {
@@ -279,8 +267,9 @@ public class UnPickle implements Kinds, Modifiers, EntryTags {
sym.flags = flags;
} else {
assert (flags & MODUL) != 0 : name;
- entries[n] = sym = TermSymbol.newModule(
- Position.NOPOS, name, owner, flags, clazz);
+ entries[n] = sym = new TermSymbol(
+ Position.NOPOS, name, owner, flags)
+ .makeModule(clazz);
}
} else {
entries[n] = sym = new TermSymbol(
@@ -288,12 +277,12 @@ public class UnPickle implements Kinds, Modifiers, EntryTags {
}
if (name == moduleroot.name && owner == moduleroot.owner()) {
if (global.debug)
- global.log("overwriting " + moduleroot);//debug
+ global.log("overwriting " + moduleroot);
sym.copyTo(moduleroot);
entries[n] = sym = moduleroot;
}
Type tp = getType(inforef);
- sym.setInfo(setOwner(tp, sym));
+ sym.setInfo(setOwner(tp, sym), Symbol.FIRST_ID);
break;
default:
@@ -375,7 +364,7 @@ public class UnPickle implements Kinds, Modifiers, EntryTags {
params[i] = new TermSymbol(
Position.NOPOS, Name.fromString("$" + i),
Symbol.NONE, PARAM | flags[i]);
- params[i].setInfo(argtypes[i]);
+ params[i].setInfo(argtypes[i], Symbol.FIRST_ID);
}
tpe = Type.MethodType(params, restype);
break;
@@ -468,5 +457,70 @@ public class UnPickle implements Kinds, Modifiers, EntryTags {
this(outer, "malformed signature at " + outer.bp);
}
}
+
+// --- print symbl files -------------------------------------------------
+
+ private static String tag2string(int tag) {
+ switch (tag) {
+ case TERMname: return "TERMname";
+ case TYPEname: return "TYPEname";
+ case NONEsym: return "NONEsym";
+ case TYPEsym: return "TYPEsym";
+ case ALIASsym: return "ALIASsym";
+ case CLASSsym: return "CLASSsym";
+ case VALsym: return "VALsym";
+ case EXTref: return "EXTref";
+ case EXTMODCLASSref: return "EXTMODCLASSref";
+ case NOtpe: return "NOtpe";
+ case THIStpe: return "THIStpe";
+ case SINGLEtpe: return "SINGLEtpe";
+ case TYPEREFtpe: return "TYPEREFtpe";
+ case COMPOUNDtpe: return "COMPOUNDtpe";
+ case METHODtpe: return "METHODtpe";
+ case POLYtpe: return "POLYtpe";
+ case OVERLOADEDtpe: return "OVERLOADEDtpe";
+ case UNBOXEDtpe: return "UNBOXEDtpe";
+ case UNBOXEDARRAYtpe: return "UNBOXEDARRAYtpe";
+ case FLAGGEDtpe: return "FLAGGEDtpe";
+ case ERRORtpe: return "ERRORtpe";
+ default: return "***BAD TAG***(" + tag + ")";
+ }
+ }
+
+ private void print(PrintStream out) {
+ out.println("symbl attribute for " + classroot + ":");
+ for (int i = 0; i < index.length; i++) {
+ out.print(i + "," + index[i] + ": ");
+ bp = index[i];
+ int tag = readByte();
+ out.print(tag2string(tag));
+ int len = readNat();
+ int end = len + bp;
+ out.print(" " + len);
+ switch (tag) {
+ case TERMname:
+ case TYPEname:
+ out.print(" " +
+ SourceRepresentation.ascii2string(bytes, bp, len));
+ bp = end;
+ break;
+ case NONEsym:
+ break;
+ case TYPEsym:
+ case ALIASsym:
+ case CLASSsym:
+ case VALsym:
+ out.print(" " + readNat()); //name
+ out.print(" " + readNat()); //owner
+ out.print(" " + Integer.toHexString(readNat())); //flags
+ out.print(" " + readNat()); //type
+ break;
+ case FLAGGEDtpe:
+ out.print(" " + Integer.toHexString(readNat())); //flags
+ }
+ while (bp < end) out.print(" " + readNat());
+ out.println();
+ }
+ }
}
diff --git a/sources/scalac/transformer/ExpandMixinsPhase.java b/sources/scalac/transformer/ExpandMixinsPhase.java
index 383d5123f6..8824559336 100644
--- a/sources/scalac/transformer/ExpandMixinsPhase.java
+++ b/sources/scalac/transformer/ExpandMixinsPhase.java
@@ -109,6 +109,7 @@ public class ExpandMixinsPhase extends PhaseDescriptor {
// Private Methods
private Template getExpandedTemplate(Symbol clasz) {
+ if (global.debug) global.log("get expanded " + clasz + " in " + clasz.owner());
Template template = (Template)expansions.get(clasz);
if (template == null) {
template = (Template)templates.remove(clasz);
diff --git a/sources/scalac/typechecker/Analyzer.java b/sources/scalac/typechecker/Analyzer.java
index 3a7e49944d..f9b0935074 100644
--- a/sources/scalac/typechecker/Analyzer.java
+++ b/sources/scalac/typechecker/Analyzer.java
@@ -91,7 +91,6 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
}
public void lateEnter(Unit unit, Symbol sym) {
- assert sym.rawInfoAt(Symbol.FIRST_ID) instanceof SourceCompleter;
enterUnit(unit);
if (sym.rawInfoAt(Symbol.FIRST_ID) instanceof SourceCompleter) {
sym.setInfo(Type.ErrorType);
@@ -635,7 +634,8 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
}
public void complete(Symbol sym) {
Symbol constr = tree.symbol().primaryConstructor();
- sym.setInfo(constr.type().instanceType().cloneType(constr, sym));
+ if (!sym.isInitialized())
+ sym.setInfo(constr.type().instanceType().cloneType(constr, sym));
}
}
@@ -709,34 +709,37 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
}
case ClassDef(int mods, Name name, Tree.TypeDef[] tparams, Tree.ValDef[][] vparams, _, Tree.Template templ):
- ClassSymbol clazz = new ClassSymbol(tree.pos, name, owner, mods);
+ ClassSymbol clazz = ClassSymbol.define(
+ tree.pos, name, owner, mods, context.scope);
if (clazz.isLocalClass()) unit.mangler.setMangledName(clazz);
- clazz.primaryConstructor().setInfo(new LazyTreeType(tree));
+ if (!clazz.primaryConstructor().isInitialized())
+ clazz.primaryConstructor().setInfo(new LazyTreeType(tree));
if ((mods & CASE) != 0) {
- /* todo: remove
- if (vparams.length == 0) {
- error(tree.pos, "case class needs () parameter section");
- }
- else */
if ((mods & ABSTRACTCLASS) == 0) {
// enter case constructor method.
- enterInScope(
- new TermSymbol(
- tree.pos, name.toTermName(), owner, mods & (ACCESSFLAGS | CASE))
- .setInfo(new LazyConstrMethodType(tree)));
+ Symbol cf = TermSymbol.define(
+ tree.pos, name.toTermName(), owner,
+ mods & ACCESSFLAGS | CASE, context.scope);
+ enterInScope(cf);
+ if (!cf.isInitialized())
+ cf.setInfo(new LazyConstrMethodType(tree));
}
}
return enterSym(tree, clazz);
case ModuleDef(int mods, Name name, _, _):
- TermSymbol modul = TermSymbol.newModule(tree.pos, name, owner, mods);
+ TermSymbol modul = TermSymbol.define(
+ tree.pos, name, owner, mods, context.scope).makeModule();
Symbol clazz = modul.moduleClass();
- clazz.setInfo(new LazyTreeType(tree));
+ if (!clazz.isInitialized())
+ clazz.setInfo(new LazyTreeType(tree));
if (clazz.isLocalClass()) unit.mangler.setMangledName(clazz);
return enterSym(tree, modul);
case ValDef(int mods, Name name, _, _):
- return enterSym(tree, new TermSymbol(tree.pos, name, owner, mods));
+ return enterSym(
+ tree,
+ TermSymbol.define(tree.pos, name, owner, mods, context.scope));
case DefDef(int mods, Name name, _, _, _, _):
Symbol sym;
@@ -752,14 +755,14 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
((DefDef) tree).name = clazz.name;
sym = context.enclClass.owner.addConstructor();
} else {
- sym = new TermSymbol(tree.pos, name, owner, mods);
+ sym = TermSymbol.define(tree.pos, name, owner, mods, context.scope);
}
return enterSym(tree, sym);
case TypeDef(int mods, Name name, _, _):
Symbol tsym = ((mods & (DEFERRED | PARAM)) != 0)
- ? new AbsTypeSymbol( tree.pos, name, owner, mods)
- : new TypeSymbol(ALIAS, tree.pos, name, owner, mods);
+ ? AbsTypeSymbol.define(tree.pos, name, owner, mods, context.scope)
+ : TypeSymbol.define(tree.pos, name, owner, mods, context.scope);
return enterSym(tree, tsym);
case Import(Tree expr, Name[] selectors):
@@ -778,7 +781,10 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
*/
private Symbol enterSym(Tree tree, Symbol sym) {
//if (global.debug) System.out.println("entering " + sym);//DEBUG
- sym.setInfo(new LazyTreeType(tree));
+ if (!sym.isInitialized()) {
+ //System.err.println("undefined: " + sym + ":" + sym.rawInfo());//DEBUG
+ sym.setInfo(new LazyTreeType(tree));
+ }
if (!sym.isConstructor()) {
Symbol owner = sym.owner();
if (sym.kind == VAL && (sym.flags & (PRIVATE | SEALED)) == 0 &&
@@ -814,9 +820,12 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
// handle double and overloaded definitions
Symbol result = sym;
Scope.Entry e = context.scope.lookupEntry(sym.name);
- if (e.owner == context.scope) {
- Symbol other = e.sym;
+ Symbol other = e.sym;
+ if (sym == other) {
+ if (global.debug) global.log("redefined: " + sym + ":" + sym.rawInfo());
+ } else if (e.owner == context.scope) {
if (other.isPreloaded()) {
+ assert false : sym + " " + other;
// symbol was preloaded from package;
// need to overwrite definition.
if (global.debug) global.log(sym + " overwrites " + other);
@@ -886,19 +895,35 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
/** Re-enter type parameters in current scope.
*/
- void reenterParams(Tree[] params) {
- for (int i = 0; i < params.length; i++) {
- context.scope.enter(params[i].symbol());
+ void reenterParams(TypeDef[] tparams, ValDef[][] vparamss, Type mt) {
+ Type rest = mt;
+ switch (rest) {
+ case PolyType(Symbol[] tsyms, Type restp):
+ for (int i = 0; i < tparams.length; i++) {
+ tsyms[i].pos = tparams[i].pos;
+ tsyms[i].name = tparams[i].name;
+ //necessary since tsyms might have been unpickled
+ tparams[i].setSymbol(tsyms[i]);
+ context.scope.enter(tsyms[i]);
+ }
+ rest = restp;
+ }
+ for (int j = 0; j < vparamss.length; j++) {
+ ValDef[] vparams = vparamss[j];
+ switch (rest) {
+ case MethodType(Symbol[] vsyms, Type restp):
+ for (int i = 0; i < vparams.length; i++) {
+ vsyms[i].pos = vparams[i].pos;
+ vsyms[i].name = vparams[i].name;
+ //necessary since vsyms might have been unpickled
+ vparams[i].setSymbol(vsyms[i]);
+ context.scope.enter(vsyms[i]);
+ }
+ rest = restp;
+ }
}
}
- /** Re-enter value parameters in current scope.
- */
- void reenterParams(Tree[][] vparams) {
- for (int i = 0; i < vparams.length; i++)
- reenterParams(vparams[i]);
- }
-
// Definining Symbols -------------------------------------------------------
/** Define symbol associated with `tree' using given `unit' and `context'.
@@ -943,45 +968,19 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
if (tpe != Tree.Empty)
sym.setTypeOfThis(new LazySelfType(tpe));
- defineTemplate(templ, sym);
+ defineTemplate(templ, sym, new Scope());
owntype = templ.type;
popContext();
break;
case ModuleDef(int mods, Name name, Tree tpe, Tree.Template templ):
Symbol clazz = sym.moduleClass();
- defineTemplate(templ, clazz);
+ defineTemplate(templ, clazz, new Scope());
clazz.setInfo(templ.type);
((ModuleDef) tree).tpe = tpe = transform(tpe, TYPEmode);
owntype = (tpe == Tree.Empty) ? clazz.type() : tpe.type;
break;
- case ValDef(int mods, Name name, Tree tpe, Tree rhs):
- if (tpe != Tree.Empty) {
- ((ValDef) tree).tpe = tpe = transform(tpe, TYPEmode);
- } else {
- pushContext(tree, sym, context.scope);
- if (rhs == Tree.Empty) {
- if ((sym.owner().flags & ACCESSOR) != 0) {
- // this is the parameter of a variable setter method.
- assert (sym.flags & PARAM) != 0;
- ((ValDef) tree).tpe = tpe =
- gen.mkType(tree.pos, sym.owner().accessed().type());
- } else {
- error(tree.pos, "missing parameter type");
- ((ValDef) tree).tpe = tpe =
- gen.mkType(tree.pos, Type.ErrorType);
- }
- } else {
- ((ValDef) tree).rhs = rhs = transform(rhs, EXPRmode);
- ((ValDef) tree).tpe = tpe = gen.mkType(tree.pos, rhs.type);
- }
- popContext();
- }
- //checkNonCyclic(tree.pos, tpe.type);
- owntype = tpe.type;
- break;
-
case DefDef(int mods, Name name, Tree.TypeDef[] tparams, Tree.ValDef[][] vparams, Tree tpe, Tree rhs):
Symbol[] tparamSyms;
Symbol[][] vparamSyms;
@@ -995,7 +994,6 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
vparamSyms = enterParams(vparams);
restype = clazz.type().subst(
clazz.typeParams(), tparamSyms);
- ((DefDef) tree).tpe = tpe = gen.mkType(tree.pos, restype);
context = prevContext;
} else {
pushContext(tree, sym, new Scope(context.scope));
@@ -1003,17 +1001,42 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
vparamSyms = enterParams(vparams);
if (tpe != Tree.Empty) {
((DefDef) tree).tpe = tpe = transform(tpe, TYPEmode);
+ restype = tpe.type;
} else {
((DefDef) tree).rhs = rhs = transform(rhs, EXPRmode);
- ((DefDef) tree).tpe = tpe = gen.mkType(tree.pos, rhs.type);
+ restype = rhs.type;
}
- restype = checkNoEscape(tpe.pos, tpe.type);
+ restype = checkNoEscape(tpe.pos, restype);
popContext();
}
owntype = makeMethodType(tparamSyms, vparamSyms, restype);
//System.out.println("methtype " + name + ":" + owntype);//DEBUG
break;
+ case ValDef(int mods, Name name, Tree tpe, Tree rhs):
+ if (tpe != Tree.Empty) {
+ ((ValDef) tree).tpe = tpe = transform(tpe, TYPEmode);
+ owntype = tpe.type;
+ } else {
+ pushContext(tree, sym, context.scope);
+ if (rhs == Tree.Empty) {
+ if ((sym.owner().flags & ACCESSOR) != 0) {
+ // this is the parameter of a variable setter method.
+ assert (sym.flags & PARAM) != 0;
+ owntype = sym.owner().accessed().type();
+ } else {
+ error(tree.pos, "missing parameter type");
+ owntype = Type.ErrorType;
+ }
+ } else {
+ ((ValDef) tree).rhs = rhs = transform(rhs, EXPRmode);
+ owntype = rhs.type;
+ }
+ popContext();
+ }
+ //checkNonCyclic(tree.pos, tpe.type);
+ break;
+
case TypeDef(int mods, Name name, Tree rhs, Tree lobound):
if (sym.kind == TYPE) {
//can't have `sym' as owner since checkNonCyclic would fail.
@@ -1050,7 +1073,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
}
sym.setInfo(owntype);
validate(sym);
- if (global.debug) global.log("defined " + sym);//debug
+ if (global.debug) global.log("defined " + sym);
} catch (Type.Error ex) {
reportTypeError(tree.pos, ex);
tree.type = Type.ErrorType;
@@ -1067,14 +1090,12 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
/** Definition phase for a template. This enters all symbols in template
* into symbol table.
*/
- void defineTemplate(Tree.Template templ, Symbol clazz) {
- //System.out.println("defining " + clazz);//debug
+ void defineTemplate(Tree.Template templ, Symbol clazz, Scope members) {
// attribute parent constructors
Tree[] constrs = transformConstrInvocations(templ.pos, templ.parents);
Type[] parents = Tree.typeOf(constrs);
// enter all members
- Scope members = new Scope();
pushContext(templ, clazz, members);
templ.body = desugarize.Statements(templ.body, false);
enterSyms(templ.body);
@@ -1333,7 +1354,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
// evaluate what was found
if (sym1.kind == NONE) {
if (sym.kind == NONE) {
- //System.out.println(name);//debug
+ //System.out.println(name);//DEBUG
return error(tree.pos, "not found: " + decode(name));
} else {
sym.flags |= ACCESSED;
@@ -1513,14 +1534,18 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
*/
Tree[] transformConstrInvocations(int pos, Tree[] constrs) {
for (int i = 0; i < constrs.length; i++) {
- //!!!pushContext(constrs[i], context.owner, context.scope);
constrs[i] = transform(constrs[i], CONSTRmode | SUPERmode, Type.AnyType);
Symbol f = TreeInfo.methSymbol(constrs[i]);
if (f != null) {
Symbol c = f.primaryConstructorClass();
- if (c.kind == CLASS) c.initialize();//to detect cycles
+ if (c.kind == CLASS) {
+ c.initialize();//to detect cycles
+ if (i > 0 && (c.flags & JAVA) == 0 && c.pos == Position.NOPOS) {
+ // need to load tree for mixins
+ new SourceCompleter(global).complete(c);
+ }
+ }
}
- //!!!popContext();
}
return constrs;
}
@@ -1540,7 +1565,9 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
/** Attribute a template
*/
public Tree.Template transformTemplate(Tree.Template templ, Symbol owner) {
- if (global.debug) global.log("transforming " + owner);//debug
+ if (global.debug) global.log("transforming template of " + owner);//debug
+ if (templ.type == null)
+ defineTemplate(templ, owner, owner.members());//may happen for mixins
//System.out.println(owner.info());//DEBUG
Tree[] parents = templ.parents;
transformConstrInvocationArgs(parents);
@@ -1717,7 +1744,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
}
Symbol sym = tree.symbol();
if (sym != null && !sym.isInitialized()) sym.initialize();
- if (global.debug && TreeInfo.isDefinition(tree)) global.log("transforming " + sym);
+ if (global.debug && TreeInfo.isDefinition(tree)) global.log("transforming definition of " + sym);
try {
switch (tree) {
@@ -1747,11 +1774,13 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
case ClassDef(_, _, Tree.TypeDef[] tparams, Tree.ValDef[][] vparams, Tree tpe, Tree.Template templ):
pushContext(
tree, sym.primaryConstructor(), new Scope(context.scope));
- reenterParams(tparams);
+ reenterParams(tparams, vparams, sym.primaryConstructor().type());
Tree.TypeDef[] tparams1 = transform(tparams);
- reenterParams(vparams);
Tree.ValDef[][] vparams1 = transform(vparams);
- Tree tpe1 = transform(tpe);
+ Tree tpe1 = transform(tpe, TYPEmode);
+ if ((sym.flags & CASE) != 0 && vparams.length > 0 && templ.type == null)
+ templ.body = desugarize.addCaseElements(templ.body, vparams[0]);
+
Tree.Template templ1 = transformTemplate(templ, sym);
checkNoEscape(tree.pos, sym.info());
popContext();
@@ -1759,24 +1788,10 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
.setType(definitions.UNIT_TYPE);
case ModuleDef(_, _, Tree tpe, Tree.Template templ):
+ sym.moduleClass().initialize();
+ Tree tpe1 = transform(tpe, TYPEmode);
Tree.Template templ1 = transformTemplate(templ, sym.moduleClass());
- return copy.ModuleDef(tree, sym, tpe, templ1)
- .setType(definitions.UNIT_TYPE);
-
- case ValDef(_, _, Tree tpe, Tree rhs):
- Tree rhs1 = rhs;
- if (rhs != Tree.Empty) {
- pushContext(tree, sym, context.scope);
- if ((sym.flags & CASEACCESSOR) != 0)
- rhs1.type = rhs1.symbol().type();
- else
- 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)
+ return copy.ModuleDef(tree, sym, tpe1, templ1)
.setType(definitions.UNIT_TYPE);
case DefDef(_, Name name, Tree.TypeDef[] tparams, Tree.ValDef[][] vparams, Tree tpe, Tree rhs):
@@ -1786,25 +1801,54 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
context = context.enclClass.outer.outer;
}
pushContext(tree, sym, new Scope(context.scope));
- reenterParams(tparams);
+ reenterParams(tparams, vparams, sym.type());
Tree.TypeDef[] tparams1 = transform(tparams);
- reenterParams(vparams);
Tree.ValDef[][] vparams1 = transform(vparams);
+ Tree tpe1 = (tpe == Tree.Empty)
+ ? gen.mkType(tree.pos, sym.type().resultType())
+ : transform(tpe, TYPEmode);
Tree rhs1 = rhs;
if (name.isTypeName())
- rhs1 = transform(rhs, CONSTRmode, tpe.type);
+ rhs1 = transform(rhs, CONSTRmode, tpe1.type);
else if (rhs != Tree.Empty)
- rhs1 = transform(rhs, EXPRmode, tpe.type);
+ rhs1 = transform(rhs, EXPRmode, tpe1.type);
context = prevContext;
sym.flags |= LOCKED;
- checkNonCyclic(tree.pos, tpe.type);
+ checkNonCyclic(tree.pos, tpe1.type);
sym.flags &= ~LOCKED;
- return copy.DefDef(tree, sym, tparams1, vparams1, tpe, rhs1)
+ return copy.DefDef(tree, sym, tparams1, vparams1, tpe1, rhs1)
.setType(definitions.UNIT_TYPE);
- case TypeDef(_, _, _, _):
+ case ValDef(_, _, Tree tpe, Tree rhs):
+ Tree tpe1 = (tpe == Tree.Empty)
+ ? gen.mkType(tree.pos, sym.type())
+ : transform(tpe, TYPEmode);
+ Tree rhs1 = rhs;
+ if (rhs != Tree.Empty) {
+ pushContext(tree, sym, context.scope);
+ if ((sym.flags & CASEACCESSOR) != 0)
+ rhs1.type = rhs1.symbol().type();
+ else
+ rhs1 = transform(rhs, EXPRmode, tpe1.type);
+ popContext();
+ }
+ sym.flags |= LOCKED;
+ checkNonCyclic(tree.pos, tpe1.type);
+ sym.flags &= ~LOCKED;
+ return copy.ValDef(tree, sym, tpe1, rhs1)
+ .setType(definitions.UNIT_TYPE);
+
+ case TypeDef(_, _, Tree rhs, Tree lobound):
+ Tree rhs1, lobound1;
+ if (sym.kind == TYPE) {
+ rhs1 = transform(rhs, TYPEmode);
+ lobound1 = transform(lobound, TYPEmode);
+ } else { // sym.kind == ALIAS
+ rhs1 = transform(rhs, TYPEmode | FUNmode);
+ lobound1 = lobound;
+ }
checkNonCyclic(tree.pos, sym.type());
- return tree
+ return copy.TypeDef(tree, sym, rhs1, lobound1)
.setType(definitions.UNIT_TYPE);
case Import(Tree expr, Name[] selectors):
@@ -1890,7 +1934,12 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
desugarize.isDefinedAtVisitor(tree),
pattype, definitions.BOOLEAN_TYPE);
Tree applyVisitor = transformVisitor(tree, pattype, restype);
- if (!infer.isFullyDefined(restype)) restype = applyVisitor.type;
+ if (!infer.isFullyDefined(restype))
+ restype = applyVisitor.type;
+ if (definitions.PARTIALFUNCTION_CLASS.pos == Position.NOPOS)
+ // need to load tree for mixins
+ new SourceCompleter(global).complete(
+ definitions.PARTIALFUNCTION_CLASS);
return gen.mkPartialFunction(
tree.pos, applyVisitor, isDefinedAtVisitor,
pattype, restype, context.owner);
diff --git a/sources/scalac/util/ClassPath.java b/sources/scalac/util/ClassPath.java
index b083c5485b..574121b4cc 100644
--- a/sources/scalac/util/ClassPath.java
+++ b/sources/scalac/util/ClassPath.java
@@ -142,6 +142,19 @@ public class ClassPath {
"' not found in classpath");
}
+ public java.io.File openJavaFile(String name) throws FileNotFoundException {
+ if (printSearch)
+ System.out.println("looking for " + name);
+ for (int i = 0; i < root.length; i++) {
+ if (printSearch)
+ System.out.println(" in " + root[i]);
+ java.io.File f = new File(root[i], name);
+ if (f.exists()) return f;
+ }
+ throw new FileNotFoundException("file '" + name +
+ "' not found in classpath");
+ }
+
public String[] components() {
return root;
}
diff --git a/test/files/pos/cls1.scala b/test/files/pos/cls1.scala
index fd64a57073..20ac12d59a 100644
--- a/test/files/pos/cls1.scala
+++ b/test/files/pos/cls1.scala
@@ -6,4 +6,4 @@ trait A {
trait B extends A {
type T = A.this.T;
}
-} \ No newline at end of file
+}
diff --git a/test/files/pos/michel1.scala b/test/files/pos/michel1.scala
index 88ef206ff0..2fc409b4e5 100644
--- a/test/files/pos/michel1.scala
+++ b/test/files/pos/michel1.scala
@@ -6,4 +6,4 @@ trait C {}
class B[Tb] (b : Tb) extends C with A[Tb] (b) {
def g = 2
-} \ No newline at end of file
+}
diff --git a/test/pos/cls1.scala b/test/pos/cls1.scala
index fd64a57073..20ac12d59a 100644
--- a/test/pos/cls1.scala
+++ b/test/pos/cls1.scala
@@ -6,4 +6,4 @@ trait A {
trait B extends A {
type T = A.this.T;
}
-} \ No newline at end of file
+}
diff --git a/test/pos/michel1.scala b/test/pos/michel1.scala
index 88ef206ff0..2fc409b4e5 100644
--- a/test/pos/michel1.scala
+++ b/test/pos/michel1.scala
@@ -6,4 +6,4 @@ trait C {}
class B[Tb] (b : Tb) extends C with A[Tb] (b) {
def g = 2
-} \ No newline at end of file
+}