summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2003-07-22 09:27:52 +0000
committerMartin Odersky <odersky@gmail.com>2003-07-22 09:27:52 +0000
commite570d189e04924a7f2b59f4f859f642c43939a21 (patch)
treea4d384ddb861de15a04e67b1624711c97478c204
parent74d350a2baff26d149e02110a9c3f079c2e03cac (diff)
downloadscala-e570d189e04924a7f2b59f4f859f642c43939a21.tar.gz
scala-e570d189e04924a7f2b59f4f859f642c43939a21.tar.bz2
scala-e570d189e04924a7f2b59f4f859f642c43939a21.zip
*** empty log message ***
-rw-r--r--config/list/compiler.lst1
-rw-r--r--sources/scalac/CompilerCommand.java5
-rw-r--r--sources/scalac/Global.java2
-rw-r--r--sources/scalac/Unit.java3
-rw-r--r--sources/scalac/symtab/EntryTags.java35
-rw-r--r--sources/scalac/symtab/Modifiers.java1
-rw-r--r--sources/scalac/symtab/Symbol.java34
-rw-r--r--sources/scalac/symtab/Type.java43
-rw-r--r--sources/scalac/symtab/classfile/ClassParser.java56
-rw-r--r--sources/scalac/symtab/classfile/PackageParser.java44
-rw-r--r--sources/scalac/symtab/classfile/Pickle.java178
-rw-r--r--sources/scalac/symtab/classfile/SymblParser.java52
-rw-r--r--sources/scalac/symtab/classfile/UnPickle.java214
-rw-r--r--sources/scalac/transformer/LambdaLift.java4
-rw-r--r--sources/scalac/typechecker/Analyzer.java74
-rw-r--r--sources/scalac/typechecker/Infer.java4
-rw-r--r--sources/scalac/typechecker/RefCheck.java3
-rw-r--r--sources/scalac/util/SourceRepresentation.java13
-rw-r--r--test/files/pos/matthias4.scala4
-rw-r--r--test/files/run/Course-2002-07.scala2
-rw-r--r--test/pos/matthias4.scala4
21 files changed, 539 insertions, 237 deletions
diff --git a/config/list/compiler.lst b/config/list/compiler.lst
index a652e2ad8f..216dcc01f0 100644
--- a/config/list/compiler.lst
+++ b/config/list/compiler.lst
@@ -65,6 +65,7 @@ symtab/classfile/JavaTypeCreator.java
symtab/classfile/JavaTypeFactory.java
symtab/classfile/PackageParser.java
symtab/classfile/Signatures.java
+symtab/classfile/SymblParser.java
symtab/classfile/Pickle.java
symtab/classfile/UnPickle.java
diff --git a/sources/scalac/CompilerCommand.java b/sources/scalac/CompilerCommand.java
index 535b5e92f1..94f04963e7 100644
--- a/sources/scalac/CompilerCommand.java
+++ b/sources/scalac/CompilerCommand.java
@@ -40,6 +40,7 @@ public class CompilerCommand extends CommandParser {
public final BooleanOptionParser uniqid;
public final BooleanOptionParser types;
public final BooleanOptionParser prompt;
+ public final BooleanOptionParser separate;
//public final OptimizeOptionParser optimize;
public final StringOptionParser classpath;
public final StringOptionParser sourcepath;
@@ -105,6 +106,10 @@ public class CompilerCommand extends CommandParser {
"prompt", "Display a prompt after each error (debugging option)",
false),
+ this.separate = new BooleanOptionParser(this,
+ "separate", "read symbol files for separate compilation",
+ false),
+
//this.optimize = new OptimizeOptionParser(this,
// "optimize", "optimize bytecode (-optimize:help for option list)",
// null /* todo: uncomment: phases.OPTIMIZE */),
diff --git a/sources/scalac/Global.java b/sources/scalac/Global.java
index ce18aa3bbe..ad0eed1eb7 100644
--- a/sources/scalac/Global.java
+++ b/sources/scalac/Global.java
@@ -36,6 +36,7 @@ public class Global {
*/
public final boolean noimports;
public final boolean nopredefs;
+ public final boolean separate;
//public final boolean optimize;
public final boolean debug;
public final boolean explaintypes;
@@ -147,6 +148,7 @@ public class Global {
this.start(); // timestamp to compute the total time
this.noimports = args.noimports.value;
this.nopredefs = args.nopredefs.value;
+ this.separate = args.separate.value;
//this.optimize = args.optimize.optimize;
this.debug = args.debug.value;
this.uniqid = args.uniqid.value;
diff --git a/sources/scalac/Unit.java b/sources/scalac/Unit.java
index 354fc1af55..1deb71317b 100644
--- a/sources/scalac/Unit.java
+++ b/sources/scalac/Unit.java
@@ -13,6 +13,7 @@ import ch.epfl.lamp.util.Position;
import scalac.symtab.NameMangler;
import scalac.ast.Tree;
+import java.util.HashMap;
/** A representation for a compilation unit in scala
@@ -39,8 +40,8 @@ public class Unit {
public Tree[] body;
/** the generated symbol data; Symbol -> byte[]
- public SymData symdata;
*/
+ public HashMap/*<Name,Pickle>*/ symdata = new HashMap();
/** the name mangler
*/
diff --git a/sources/scalac/symtab/EntryTags.java b/sources/scalac/symtab/EntryTags.java
index 1b695a213f..b8ae7c2d7a 100644
--- a/sources/scalac/symtab/EntryTags.java
+++ b/sources/scalac/symtab/EntryTags.java
@@ -10,6 +10,35 @@ package scalac.symtab;
public interface EntryTags {
+/***************************************************
+ * Symbol table attribute format:
+ * Symtab = nentries_Nat {Entry}
+ * Entry = 1 TERMNAME len_Nat NameInfo
+ * | 2 CONSTRNAME len_Nat NameInfo
+ * | 3 TYPENAME len_Nat NameInfo
+ * | 4 NONEsym len_Nat
+ * | 5 TYPEsym len_Nat SymbolInfo lobound_Ref
+ * | 6 ALIASsym len_Nat SymbolInfo
+ * | 7 CLASSsym len_Nat SymbolInfo thistype_Ref constrsym_Ref
+ * | 8 VALsym len_Nat SymbolInfo [classsym_Ref]
+ * | 9 EXTsym len_Nat name_Ref [owner_Ref]
+ * | 10 EXTMODCLASSsym len_Nat name_Ref [owner_Ref]
+ * | 11 NOtpe len_Nat
+ * | 12 THIStpe len_Nat sym_Ref
+ * | 13 SINGLEtpe len_Nat type_Ref sym_Ref
+ * | 14 TYPEREFtpe len_Nat type_Ref sym_Ref {targ_Ref}
+ * | 15 COMPOUNDtpe len_Nat classsym_Ref {tpe_Ref}
+ * | 16 METHODtpe len_Nat tpe_Ref {tpe_Ref}
+ * | 17 POLYTtpe len_Nat tpe_Ref {sym_Ref}
+ * | 18 OVERLOADEDtpe len_Nat {sym_Ref} {tpe_Ref}
+ * | 21 FLAGGEDtype 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
+ *
+ * len is remaining length after `len'.
+ */
+
int TERMname = 1,
CONSTRname = 2,
TYPEname = 3,
@@ -17,9 +46,9 @@ public interface EntryTags {
TYPEsym = 5,
ALIASsym = 6,
CLASSsym = 7,
- MODULEsym = 8,
- VALsym = 9,
- EXTsym = 10,
+ VALsym = 8,
+ EXTsym = 9,
+ EXTMODCLASSsym = 10,
NOtpe = 11,
THIStpe = 12,
SINGLEtpe = 13,
diff --git a/sources/scalac/symtab/Modifiers.java b/sources/scalac/symtab/Modifiers.java
index 5948dc2157..9358a2d721 100644
--- a/sources/scalac/symtab/Modifiers.java
+++ b/sources/scalac/symtab/Modifiers.java
@@ -61,6 +61,7 @@ public interface Modifiers {
int SOURCEFLAGS = 0x00000077 | DEF | REPEATED | MODUL | MUTABLE | PACKAGE | PARAM | TRAIT | COVARIANT | CONTRAVARIANT; // these modifiers can be set in source programs.
int ACCESSFLAGS = PRIVATE | PROTECTED;
int VARIANCES = COVARIANT | CONTRAVARIANT;
+ int OVERLOADFLAGS = DEFERRED | OVERRIDE | FINAL;
public static class Helper {
diff --git a/sources/scalac/symtab/Symbol.java b/sources/scalac/symtab/Symbol.java
index b8edc68c3b..6867bfb576 100644
--- a/sources/scalac/symtab/Symbol.java
+++ b/sources/scalac/symtab/Symbol.java
@@ -226,6 +226,7 @@ public abstract class Symbol implements Modifiers, Kinds {
}
public final boolean isAbstractClass() {
+ preInitialize();
return (flags & ABSTRACTCLASS) != 0 &&
this != Global.instance.definitions.ARRAY_CLASS;
}
@@ -243,6 +244,7 @@ public abstract class Symbol implements Modifiers, Kinds {
/** Does this symbol denote something loaded from a Java class? */
public final boolean isJava() {
+ preInitialize();
return (flags & JAVA) != 0;
}
@@ -276,11 +278,14 @@ public abstract class Symbol implements Modifiers, Kinds {
/** Does this symbol denote a case class?
*/
public final boolean isCaseClass() {
+ preInitialize();
return kind == CLASS && (flags & CASE) != 0;
}
/** Does this symbol denote a uniform (i.e. parameterless) class? */
public final boolean isTrait() {
+ //preInitialize(); todo: enable, problem is that then we cannot print
+ // during unpickle
return kind == CLASS && (flags & TRAIT) != 0;
}
@@ -292,6 +297,7 @@ public abstract class Symbol implements Modifiers, Kinds {
/** Does this symbol denote an interface? */
public final boolean isInterface() {
+ preInitialize();
return (flags & INTERFACE) != 0;
}
@@ -302,11 +308,13 @@ public abstract class Symbol implements Modifiers, Kinds {
/** Does this symbol denote a protected symbol? */
public final boolean isProtected() {
+ preInitialize();
return (flags & PROTECTED) != 0;
}
/** Does this symbol denote a private symbol? */
public final boolean isPrivate() {
+ preInitialize();
return (flags & PRIVATE) != 0;
}
@@ -402,8 +410,9 @@ public abstract class Symbol implements Modifiers, Kinds {
/** Get the fully qualified name of this Symbol
* (this is always a normal name, never a type name)
*/
+ /** Get the fully qualified name of this Symbol */
public Name fullName() {
- return name.toTermName();
+ return name.toTermName();
}
/** Get the mangled name of this Symbol
@@ -541,6 +550,15 @@ public abstract class Symbol implements Modifiers, Kinds {
return this;
}
+ /** Make sure symbol is entered
+ */
+ public final void preInitialize() {
+ //todo: clean up
+ if (infos.info instanceof ClassParser ||
+ infos.info instanceof SourceCompleter)
+ infos.info.complete(this);
+ }
+
/** Get info; This is:
* for a term symbol, its type
* for a type variable, its bound
@@ -825,11 +843,11 @@ public abstract class Symbol implements Modifiers, Kinds {
assert this.name == that.name : Debug.show(this) + " <> " + Debug.show(that);
assert this.owner == that.owner : Debug.show(this) + " != " + Debug.show(that);
assert (this.flags & that.flags & JAVA) != 0 ||
- (this.flags & (SOURCEFLAGS | JAVA) & ~ACCESSFLAGS) ==
- (that.flags & (SOURCEFLAGS | JAVA) & ~ACCESSFLAGS) : Integer.toHexString(this.flags) + "@" + Debug.show(this) + " <> " + Integer.toHexString(that.flags) + "@" + Debug.show(that);
+ (this.flags & OVERLOADFLAGS) == (that.flags & OVERLOADFLAGS)
+ : Integer.toHexString(this.flags) + "@" + Debug.show(this) + " <> " + Integer.toHexString(that.flags) + "@" + Debug.show(that);
TermSymbol overloaded = new TermSymbol(
pos, name, owner,
- ((this.flags | that.flags) & (SOURCEFLAGS | JAVA) & ~ACCESSFLAGS) |
+ ((this.flags | that.flags) & (JAVA | OVERLOADFLAGS)) |
(this.flags & that.flags & ACCESSFLAGS));
overloaded.setInfo(new LazyOverloadedType(this, that));
return overloaded;
@@ -1095,6 +1113,10 @@ public class TypeSymbol extends Symbol {
return type();
}
+ public Symbol[] typeParams() {
+ return type().unalias().typeParams();
+ }
+
public Type[] closure() {
if (kind == ALIAS) return info().symbol().closure();
int id = currentPhaseId();
@@ -1219,6 +1241,10 @@ public class AbsTypeSymbol extends TypeSymbol {
return other;
}
+ public Symbol[] typeParams() {
+ return Symbol.EMPTY_ARRAY;
+ }
+
public Type loBound() {
initialize();
return lobound == null ? Global.instance.definitions.ALL_TYPE : lobound;
diff --git a/sources/scalac/symtab/Type.java b/sources/scalac/symtab/Type.java
index 453e95a323..262d07ccd6 100644
--- a/sources/scalac/symtab/Type.java
+++ b/sources/scalac/symtab/Type.java
@@ -420,8 +420,11 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags {
return tparams;
case MethodType(Symbol[] vparams, _):
return Symbol.EMPTY_ARRAY;
+ case TypeRef(_, Symbol sym, Type[] args):
+ if (args.length == 0) return sym.typeParams();
+ else return Symbol.EMPTY_ARRAY;
default:
- throw Debug.abort("illegal case", this);
+ return Symbol.EMPTY_ARRAY;
}
}
@@ -1148,39 +1151,39 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags {
/** Substitute symbols `to' for occurrences of symbols `from' in this type.
*/
public Type subst(Symbol[] from, Symbol[] to) {
- assert from.length == to.length
- : this + ": " + from.length + " != " + to.length;
- if (from.length != 0 && from != to)
+ if (to.length != 0 && from != to) {//!!!
+ assert from.length == to.length
+ : this + ": " + from.length + " != " + to.length;
return new SubstSymMap(from, to).apply(this);
- else return this;
+ } else return this;
}
/** Substitute symbols `to' for occurrences of symbols `from' in these types.
*/
public static Type[] subst(Type[] these, Symbol[] from, Symbol[] to) {
- assert from.length == to.length;
- if (these.length != 0 && from.length != 0 && from != to)
+ if (these.length != 0 && to.length != 0 && from != to) {
+ assert from.length == to.length;
return new SubstSymMap(from, to).map(these);
- else return these;
+ } else return these;
}
/** Substitute types `to' for occurrences of symbols `from' in this type.
*/
public Type subst(Symbol[] from, Type[] to) {
- assert from.length == to.length
- : this + ": " + Debug.show(from) + " <> " + ArrayApply.toString(to);
- if (from.length != 0)
+ if (to.length != 0) {
+ assert from.length == to.length
+ : this + ": " + Debug.show(from) + " <> " + ArrayApply.toString(to);
return new SubstTypeMap(from, to).apply(this);
- else return this;
+ } else return this;
}
/** Substitute types `to' for occurrences of symbols `from' in these types.
*/
public static Type[] subst(Type[] these, Symbol[] from, Type[] to) {
- assert from.length == to.length;
- if (these.length != 0 && from.length != 0)
+ if (these.length != 0 && to.length != 0) {
+ assert from.length == to.length;
return new SubstTypeMap(from, to).map(these);
- else return these;
+ } else return these;
}
/** A map for substitutions of thistypes.
@@ -2453,9 +2456,10 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags {
^ (pre.hashCode() * 41)
^ (sym.hashCode() * (41*41));
case CompoundType(Type[] parts, Scope members):
- return COMPOUNDtpe
- ^ (hashCode(parts) * 41)
- ^ (members.hashCode() * (41 * 41));
+ return symbol().hashCode();
+ //return COMPOUNDtpe
+ // ^ (hashCode(parts) * 41)
+ // ^ (members.hashCode() * (41 * 41));
case MethodType(Symbol[] vparams, Type result):
int h = METHODtpe;
for (int i = 0; i < vparams.length; i++)
@@ -2532,7 +2536,8 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags {
case CompoundType(Type[] parts, Scope members):
switch (that) {
case CompoundType(Type[] parts1, Scope members1):
- return parts.equals(parts1) && members.equals(members1);
+ return this.symbol() == that.symbol();
+ //return parts.equals(parts1) && members.equals(members1);
default: return false;
}
case MethodType(Symbol[] vparams, Type result):
diff --git a/sources/scalac/symtab/classfile/ClassParser.java b/sources/scalac/symtab/classfile/ClassParser.java
index 43c0eaff01..19eb931f3b 100644
--- a/sources/scalac/symtab/classfile/ClassParser.java
+++ b/sources/scalac/symtab/classfile/ClassParser.java
@@ -19,7 +19,7 @@ public class ClassParser extends Type.LazyType {
/** the global compilation environment
*/
protected Global global;
- private boolean completed = false;
+ protected boolean completed = false;
public ClassParser(Global global) {
this.global = global;
@@ -28,44 +28,29 @@ public class ClassParser extends Type.LazyType {
/** complete class symbol c by loading the class
*/
public void complete(Symbol c) {
- if (completed) {
- c.setInfo(Type.NoType);
- } else {
- //System.out.println("loading " + c);//DEBUG
- try {
- long msec = System.currentTimeMillis();
- String filename = externalizeFileName(c.fullName()) + ".class";
- AbstractFile f = global.classPath.openFile(filename);
- if (f == null)
- global.error("could not read class " + c);
- else {
- new ClassfileParser(global, new AbstractFileReader(f), c).parse();
- 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)
+ //System.out.println("loading " + c);//DEBUG
+ try {
+ long msec = System.currentTimeMillis();
+ String filename = SourceRepresentation.externalizeFileName(
+ c.fullName()) + ".class";
+ AbstractFile f = global.classPath.openFile(filename);
+ if (f == null)
+ global.error("could not read class " + c);
+ else {
+ new ClassfileParser(global, new AbstractFileReader(f), c).parse();
+ 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();
- }
- } catch (IOException e) {
- e.printStackTrace();
- global.error("i/o error while loading " + c);
- c.setInfo(Type.ErrorType);
}
+ } catch (IOException e) {
+ e.printStackTrace();
+ global.error("i/o error while loading " + c);
+ c.setInfo(Type.ErrorType);
}
}
- /** return external representation of file name s,
- * converting '.' to File.separatorChar
- */
- public String externalizeFileName(Name n) {
- if ((n == null) || (n.length() == 0))
- return ".";
- byte[] ascii = n.toAscii();
- String s = SourceRepresentation.ascii2string(
- ascii, 0, ascii.length);
- return s.replace('.', File.separatorChar);
- }
-
public Type.LazyType staticsParser(Symbol clazz) {
return new StaticsParser(clazz);
}
@@ -100,7 +85,8 @@ public class ClassParser extends Type.LazyType {
public void complete(Symbol c) {
try {
long msec = System.currentTimeMillis();
- String filename = externalizeFileName(alias.fullName()) + ".class";
+ String filename = SourceRepresentation.externalizeFileName(
+ alias.fullName()) + ".class";
AbstractFile f = global.classPath.openFile(filename);
if (f == null)
global.error("could not read class " + c);
diff --git a/sources/scalac/symtab/classfile/PackageParser.java b/sources/scalac/symtab/classfile/PackageParser.java
index 9f14045723..80191c79ba 100644
--- a/sources/scalac/symtab/classfile/PackageParser.java
+++ b/sources/scalac/symtab/classfile/PackageParser.java
@@ -22,10 +22,14 @@ public class PackageParser extends Type.LazyType {
/** the class parser
*/
public ClassParser classCompletion;
+ public SymblParser symblCompletion; // provisional
public PackageParser(Global global) {
this.global = global;
this.classCompletion = new ClassParser(global);
+ this.symblCompletion = new SymblParser(global); // provisional
+ if (global.reporter.verbose)
+ System.out.println("classpath = " + global.classPath);//debug
}
/** complete package type symbol p by loading all package members
@@ -38,7 +42,7 @@ public class PackageParser extends Type.LazyType {
if (name.length() == 0) {
// includeMembers(AbstractFile.open(null, "."), p, members, false);
} else {
- dirname = externalizeFileName(name);
+ dirname = SourceRepresentation.externalizeFileName(name);
assert !dirname.startsWith("com") : p;//debug
if (!dirname.endsWith("/"))
dirname += "/";
@@ -95,11 +99,30 @@ public class PackageParser extends Type.LazyType {
if (locals.lookup(n) == Symbol.NONE) {
TermSymbol module = TermSymbol.newJavaPackageModule(n, p, this);
locals.enter(module);
+ locals.enter(module.moduleClass());
}
- } else if (fname.endsWith(".scala")) {
+ } else if (inclClasses && global.separate && fname.endsWith(".symbl")) {
+ //todo: compare dates between symbl and scala.
Name n = Name.fromString(fname.substring(0, fname.length() - 6))
.toTypeName();
- //if (locals.lookup(n) == Symbol.NONE) {
+ Symbol sym = locals.lookup(n);
+ if (sym == Symbol.NONE ||
+ sym.rawInfoAt(Symbol.FIRST_ID) instanceof ClassParser &&
+ !(sym.rawInfoAt(Symbol.FIRST_ID) instanceof SymblParser)) {
+ ClassSymbol clazz = new ClassSymbol(n, p, symblCompletion);
+ clazz.constructor().setInfo(symblCompletion);
+ clazz.module().setInfo(symblCompletion);
+ locals.enter(clazz);
+ locals.enter(clazz.constructor());
+ locals.enter(clazz.module());
+ }
+ } else if (inclClasses && fname.endsWith(".scala")) {
+ Name n = Name.fromString(fname.substring(0, fname.length() - 6))
+ .toTypeName();
+ Symbol sym = locals.lookup(n);
+ if (sym == Symbol.NONE ||
+ sym.rawInfoAt(Symbol.FIRST_ID) instanceof ClassParser &&
+ !(sym.rawInfoAt(Symbol.FIRST_ID) instanceof SymblParser)) {
SourceCompleter completer = new SourceCompleter(global,
dir.getPath() + File.separatorChar + fname);
ClassSymbol clazz = new ClassSymbol(n, p, completer);
@@ -109,23 +132,10 @@ public class PackageParser extends Type.LazyType {
locals.enter(clazz);
locals.enter(clazz.constructor());
locals.enter(clazz.module());
- //}
+ }
}
}
} catch (IOException e) {
}
}
-
- /** return external representation of file name s,
- * converting '.' to File.separatorChar
- */
-
- public String externalizeFileName(Name n) {
- if ((n == null) || (n.length() == 0))
- return ".";
- byte[] ascii = n.toAscii();
- String s = SourceRepresentation.ascii2string(
- ascii, 0, ascii.length);
- return s.replace('.', File.separatorChar);
- }
}
diff --git a/sources/scalac/symtab/classfile/Pickle.java b/sources/scalac/symtab/classfile/Pickle.java
index bbd0ff7526..83d9851405 100644
--- a/sources/scalac/symtab/classfile/Pickle.java
+++ b/sources/scalac/symtab/classfile/Pickle.java
@@ -9,6 +9,7 @@
package scalac.symtab.classfile;
import java.util.HashMap;
+import java.io.*;
import scalac.Global;
import scalac.ApplicationError;
import scalac.util.*;
@@ -21,32 +22,85 @@ public class Pickle implements Kinds, Modifiers, EntryTags {
final static boolean debug = false;
/***************************************************
- * Symbol table attribute format: see UnPickle.java
+ * Symbol table attribute format: see EntryTags.java
*/
public byte[] bytes;
private int bp;
- private Symbol root;
+ private Name rootname;
+ private Symbol rootowner;
private HashMap index;
private Object[] entries;
private int ep;
- private Symbol root1;
- private Symbol root2;
/** Write symbol table info for root.
* root must be either a module or a class.
*/
- Pickle(Symbol root) {
- this.root = root;
- this.root1 = root.moduleClass();
- this.root2 = root1.constructor();
+ public Pickle() {
index = new HashMap();
entries = new Object[256];
ep = 0;
- putSymbol(root);
+ }
+
+ /** Pickle all symbols descending from `root'.
+ */
+ public void add(Symbol root) {
+ if (index.get(root) == null) {
+ this.rootname = root.name.toTermName();
+ this.rootowner = root.owner();
+ putSymbol(root);
+ }
+ }
+
+ /** Finalize pickler with given fullname.
+ */
+ public void finalize(Name fullname) {
bytes = new byte[4096];
bp = 0;
writeAttr();
+ this.index = null;
+ this.entries = null;
+ writeFile(fullname);
+ }
+
+ /** Create output file with given extension for given class.
+ */
+ public File outputFile(Name fullname, String extension) {
+ if (Global.instance.outpath != null) {
+ return new File(
+ Global.instance.outpath,
+ SourceRepresentation.externalizeFileName(fullname) + extension);
+ } else {
+ String s = fullname.toString();
+ int i = s.length();
+ while (i > 0 && s.charAt(i - 1) != '.') i--;
+ return new File(s.substring(i) + extension);
+ }
+ }
+
+ private void createPath(File f) {
+ try {
+ f.createNewFile();
+ } catch (IOException ex) {
+ f.getParentFile().mkdirs();
+ try {
+ f.createNewFile();
+ } catch (IOException ex1) {
+ }
+ }
+ }
+
+ private void writeFile(Name fullname) {
+ File outfile = outputFile(fullname, ".symbl");
+ try {
+ createPath(outfile);
+ FileOutputStream out = new FileOutputStream(outfile);
+ out.write(bytes, 0, bp);
+ out.close();
+ Global.instance.operation("wrote " + outfile);
+ } catch (IOException ex) {
+ System.err.println("error writing " + outfile);
+ }
}
/* **************************************************
@@ -57,7 +111,8 @@ public class Pickle implements Kinds, Modifiers, EntryTags {
*/
private boolean isLocal(Symbol sym) {
return
- sym == root || sym == root1 || sym == root2 ||
+ sym.name.toTermName() == rootname &&
+ sym.owner() == rootowner ||
(sym.kind != NONE && isLocal(sym.owner()));
}
@@ -88,37 +143,45 @@ public class Pickle implements Kinds, Modifiers, EntryTags {
* another symbol.
*/
private void putSymbol(Symbol sym) {
- if (putEntry(sym)) {
- if (isLocal(sym)) {
- putEntry(sym.name);
- putSymbol(sym.owner());
- putType(sym.info());
- switch (sym.kind) {
- case TYPE:
- putType(sym.loBound());
- break;
- case ALIAS:
- break;
- case CLASS:
- putType(sym.typeOfThis());
- putSymbol(sym.constructor());
- for (Scope.SymbolIterator it = sym.members().iterator();
- it.hasNext();)
- putSymbol(it.next());
- break;
- case VAL:
- if (sym.isPrimaryConstructor())
- putSymbol(sym.primaryConstructorClass());
- else if (sym.isModule())
- putSymbol(sym.moduleClass());
- break;
- default:
- throw new ApplicationError();
- }
- } else if (sym.kind != NONE) {
- putEntry(sym.name);
- if (sym.owner() != Global.instance.definitions.ROOT_CLASS)
+ switch (sym.info()) {
+ case OverloadedType(Symbol[] alts, _):
+ for (int i = 0; i < alts.length; i++)
+ putSymbol(alts[i]);
+ break;
+ default:
+ if (putEntry(sym)) {
+ //System.out.println("put sym " + sym);//DEBUG
+ if (isLocal(sym)) {
+ putEntry(sym.name);
putSymbol(sym.owner());
+ putType(sym.info());
+ switch (sym.kind) {
+ case TYPE:
+ putType(sym.loBound());
+ break;
+ case ALIAS:
+ break;
+ case CLASS:
+ putType(sym.typeOfThis());
+ putSymbol(sym.constructor());
+ for (Scope.SymbolIterator it = sym.members().iterator();
+ it.hasNext();)
+ putSymbol(it.next());
+ break;
+ case VAL:
+ if (sym.isPrimaryConstructor())
+ putSymbol(sym.primaryConstructorClass());
+ else if (sym.isModule())
+ putSymbol(sym.moduleClass());
+ break;
+ default:
+ throw new ApplicationError();
+ }
+ } else if (sym.kind != NONE) {
+ putEntry(sym.name);
+ if (sym.owner() != Global.instance.definitions.ROOT_CLASS)
+ putSymbol(sym.owner());
+ }
}
}
}
@@ -148,13 +211,13 @@ public class Pickle implements Kinds, Modifiers, EntryTags {
putTypes(args);
break;
case CompoundType(Type[] parents, Scope members):
+ putSymbol(tp.symbol());
putTypes(parents);
- putSymbols(members.elements());
break;
case MethodType(Symbol[] vparams, Type result):
putType(result);
for (int i = 0; i < vparams.length; i++) {
- Type ptype= vparams[i].type();
+ Type ptype = vparams[i].type();
putType(ptype);
int pflags = vparams[i].flags;
if ((pflags & (COVARIANT | CONTRAVARIANT | REPEATED | DEF)) != 0)
@@ -166,8 +229,7 @@ public class Pickle implements Kinds, Modifiers, EntryTags {
putSymbols(tparams);
break;
case OverloadedType(Symbol[] alts, Type[] alttypes):
- putSymbols(alts);
- putTypes(alttypes);
+ assert false : tp;
break;
default:
throw new ApplicationError();
@@ -259,7 +321,22 @@ public class Pickle implements Kinds, Modifiers, EntryTags {
*/
private void writeSymbol(Symbol sym) {
if (isLocal(sym)) {
- writeByte(sym.kind);
+ switch (sym.kind) {
+ case TYPE:
+ writeByte(TYPEsym);
+ break;
+ case ALIAS:
+ writeByte(ALIASsym);
+ break;
+ case CLASS:
+ writeByte(CLASSsym);
+ break;
+ case VAL:
+ writeByte(VALsym);
+ break;
+ default:
+ throw new ApplicationError();
+ }
writeByte(0); // space for length
writeRef(sym.name);
writeRef(sym.owner());
@@ -281,14 +358,13 @@ public class Pickle implements Kinds, Modifiers, EntryTags {
else if (sym.isModule())
writeRef(sym.moduleClass());
break;
- default:
- throw new ApplicationError();
}
} else if (sym.kind == NONE) {
- writeByte(NONE);
+ writeByte(NONEsym);
writeByte(0); // space for length
} else {
- writeByte(EXTsym);
+ writeByte(((sym.flags & (MODUL | PACKAGE)) == MODUL)
+ ? EXTMODCLASSsym : EXTsym);
writeByte(0); // space for length
writeRef(sym.name);
if (sym.owner() != Global.instance.definitions.ROOT_CLASS)
@@ -329,8 +405,8 @@ public class Pickle implements Kinds, Modifiers, EntryTags {
case CompoundType(Type[] parents, Scope members):
writeByte(COMPOUNDtpe);
writeByte(0); // space for length
+ writeRef(tp.symbol());
writeRefs(parents);
- writeRefs(members.elements());
break;
case MethodType(Symbol[] vparams, Type result):
@@ -388,9 +464,9 @@ public class Pickle implements Kinds, Modifiers, EntryTags {
for (int i = 0; i < ep; i++) {
if (debug) System.out.print(i + "," + bp + ": ");
writeEntry(entries[i]);
+ if (debug) System.out.print("(" + entries[i] + ")");
if (debug) System.out.println();
}
- resizeTo(bp);
}
private static int encodeFlags(int flags) {
diff --git a/sources/scalac/symtab/classfile/SymblParser.java b/sources/scalac/symtab/classfile/SymblParser.java
new file mode 100644
index 0000000000..1c2ef25618
--- /dev/null
+++ b/sources/scalac/symtab/classfile/SymblParser.java
@@ -0,0 +1,52 @@
+/* ____ ____ ____ ____ ______ *\
+** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala **
+** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL **
+** /_____/\____/\___/\____/____/ **
+** **
+** $Id$
+\* */
+
+package scalac.symtab.classfile;
+
+import scalac.*;
+import scalac.symtab.*;
+import scalac.util.*;
+import java.io.*;
+
+
+public class SymblParser extends ClassParser {
+
+ /** the global compilation environment
+ */
+
+ public SymblParser(Global global) {
+ super(global);
+ }
+ /** complete class symbol c by loading the class
+ */
+ public void complete(Symbol c) {
+ //System.out.println("loading " + c);//DEBUG
+ try {
+ long msec = System.currentTimeMillis();
+ String filename = SourceRepresentation.externalizeFileName(
+ c.fullName()) + ".symbl";
+ AbstractFile f = global.classPath.openFile(filename);
+ if (f == null)
+ global.error("could not read class " + c);
+ else {
+ byte[] data = f.read();
+ 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();
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ global.error("i/o error while loading " + c);
+ c.setInfo(Type.ErrorType);
+ }
+ }
+}
+
diff --git a/sources/scalac/symtab/classfile/UnPickle.java b/sources/scalac/symtab/classfile/UnPickle.java
index 7c46a2d6e4..a0cc7eda31 100644
--- a/sources/scalac/symtab/classfile/UnPickle.java
+++ b/sources/scalac/symtab/classfile/UnPickle.java
@@ -19,34 +19,9 @@ import Type.*;
public class UnPickle implements Kinds, Modifiers, EntryTags {
/***************************************************
- * Symbol table attribute format:
- * Symtab = nentries_Nat {Entry}
- * Entry = TERMNAME len_Nat NameInfo
- * | CONSTRNAME len_Nat NameInfo
- * | TYPENAME len_Nat NameInfo
- * | NONEsym len_Nat
- * | TYPEsym len_Nat SymbolInfo lobound_Ref
- * | ALIASsym len_Nat SymbolInfo
- * | CLASSsym len_Nat SymbolInfo thistype_Ref constrsym_Ref
- * | MODULEsym len_Nat SymbolInfo classsym_Ref
- * | VALsym len_Nat SymbolInfo [classsym_Ref]
- * | EXTsym len_Nat name_Ref [owner_Ref]
- * | NOtpe len_Nat
- * | THIStpe len_Nat sym_Ref
- * | SINGLEtpe len_Nat type_Ref sym_Ref
- * | TYPEREFtpe len_Nat type_Ref sym_Ref {targ_Ref}
- * | COMPOUNDtpe len_Nat sym_Ref {tpe_Ref} {sym_Ref}
- * | METHODtpe len_Nat tpe_Ref {tpe_Ref}
- * | POLYTtpe len_Nat tpe_Ref {sym_Ref}
- * | OVERLOADEDtpe len_Nat {sym_Ref} {tpe_Ref}
- * | FLAGGEDtype 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
- *
- * len is remaining length after `len'.
+ * Symbol table attribute format: see EntryTags.java
*/
- static final boolean debug = false;
+ static final boolean debug = true;
Symbol classroot;
Symbol moduleroot;
@@ -56,12 +31,25 @@ public class UnPickle implements Kinds, Modifiers, EntryTags {
int[] index;
Object[] entries;
int paramFlags;
+ Global global;
UnPickle(Symbol root, byte[] data, Name sourceName) {
+ global = Global.instance;
assert root.rawInfoAt(Symbol.FIRST_ID) instanceof LazyType;
- //System.out.println("unpickle " + root);//DEBUG
- this.classroot = root;
- this.moduleroot = classroot.module();
+ if (root.isConstructor()) {
+ this.classroot = root.primaryConstructorClass();
+ this.moduleroot = classroot.module();
+ } else if (root.isType()) {
+ this.classroot = root;
+ this.moduleroot = classroot.module();
+ } else {
+ this.moduleroot = root;
+ this.classroot = root.owner().lookup(root.name.toTypeName());
+ }
+ if (global.debug)
+ global.log(
+ "unpickle " + root + " " + classroot + " " + moduleroot + " " +
+ moduleroot.moduleClass() + moduleroot.moduleClass().constructor());
this.bytes = data;
this.bp = 0;
this.sourceName = sourceName;
@@ -72,21 +60,28 @@ public class UnPickle implements Kinds, Modifiers, EntryTags {
bp = readNat() + bp;
}
entries = new Object[index.length];
- if (debug) {
+ 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];
- System.out.print(readByte() + " ");
+ int tag = readByte();
+ System.out.print(tag + " ");
int len = readNat();
System.out.print(len + " ");
- for (int j = 0; j < len; j++)
- System.out.print(readByte() + " ");
+ if (tag == TERMname || tag == TYPEname || tag == CONSTRname)
+ System.out.print(
+ SourceRepresentation.ascii2string(bytes, bp, len));
+ else
+ for (int j = 0; j < len; j++)
+ System.out.print(readByte() + " ");
System.out.println();
}
}
for (int i = 0; i < index.length; i++) {
if (isSymbolEntry(i)) getSymbol(i);
}
+ if (global.debug) global.log("unpickled " + root);//debug
if (root.rawInfoAt(Symbol.FIRST_ID) instanceof LazyType)
throw new BadSignature(this, "it does not define " + root);
}
@@ -99,14 +94,11 @@ public class UnPickle implements Kinds, Modifiers, EntryTags {
else return Type.PolyType(tparams, restpe1);
case MethodType(Symbol[] params, Type restpe):
Symbol[] params1 = params;
- for (int i = 0; i < params.length; i++) {
- if (params[i].owner() != owner) {
- if (params1 == params && params[i].owner() != Symbol.NONE) {
- params1 = new Symbol[params.length];
- System.arraycopy(params, 0, params1, 0, i);
- }
- params1[i].setOwner(owner);
- }
+ if (params.length > 0 &&
+ 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);
}
Type restpe1 = setOwner(restpe, owner);
if (params1 == params && restpe1 == restpe) return tp;
@@ -162,6 +154,30 @@ public class UnPickle implements Kinds, Modifiers, EntryTags {
return getName(readNat());
}
+ String decode(Name name) {
+ if (name.isTypeName()) return "type " + NameTransformer.decode(name);
+ else if (name.isConstrName()) return "constructor " + NameTransformer.decode(name);
+ else return "value " + NameTransformer.decode(name);
+ }
+
+ Symbol extRef(Symbol owner, Name name, boolean modclass) {
+ if (name.length() == 0 && owner == Symbol.NONE) {
+ return Global.instance.definitions.ROOT_CLASS;
+ } else if (modclass) {
+ assert name.isTypeName() : name;
+ Symbol module = extRef(owner, name.toTermName(), false);
+ switch (module.type()) {
+ case OverloadedType(Symbol[] alts, _):
+ for (int i = 0; i < alts.length; i++)
+ if (alts[i].isModule()) module = alts[i];
+ }
+ assert module.isModule();
+ return module.moduleClass();
+ } else {
+ return owner.info().lookup(name);
+ }
+ }
+
Symbol getSymbol(int n) {
if (entries[n] == null) {
int savedBp = bp;
@@ -175,6 +191,7 @@ public class UnPickle implements Kinds, Modifiers, EntryTags {
entries[n] = sym = Symbol.NONE;
break;
case EXTsym:
+ case EXTMODCLASSsym:
Name name = readNameRef();
if (bp == end) {
owner = Global.instance.definitions.ROOT_CLASS;
@@ -182,20 +199,20 @@ public class UnPickle implements Kinds, Modifiers, EntryTags {
assert bp < end;
owner = readSymbolRef();
}
- if (name.length() == 0 && owner == Symbol.NONE) {
- entries[n] = sym = Global.instance.definitions.ROOT_CLASS;
- } else {
- entries[n] = sym = owner.info().lookupNonPrivate(name);
- }
+ entries[n] = sym = extRef(owner, name, tag == EXTMODCLASSsym);
if (sym.kind == NONE) {
+ if (global.debug)
+ global.log(owner.info().members().toString());//debug
throw new BadSignature(this,
- "reference " + name + " of " + owner +
+ "reference " + decode(name) + " of " + owner +
" refers to nonexisting symbol.");
}
break;
default:
assert isSymbolEntry(n) : n;
Name name = readNameRef();
+ if (global.debug)
+ global.log("reading " + name + " at " + n);//debug
owner = readSymbolRef();
if (entries[n] == null) {
int flags = readNat();
@@ -217,54 +234,84 @@ public class UnPickle implements Kinds, Modifiers, EntryTags {
case CLASSsym:
entries[n] = sym = new ClassSymbol(
Position.NOPOS, name, owner, flags);
- if (name == classroot.name && owner == classroot.owner()) {
- sym.copyTo(classroot);
- entries[n] = sym = classroot;
+ Symbol clr = ((flags & MODUL) == 0) ? classroot
+ : moduleroot.moduleClass();
+ if (name == clr.name && owner == clr.owner()) {
+ if (global.debug) global.log("overwriting " + clr);
+ sym.copyTo(clr);
+ entries[n] = sym = clr;
}
sym.setInfo(getType(inforef));
sym.setTypeOfThis(readTypeRef());
Symbol constructor = readSymbolRef(); //will install itself!
break;
- case MODULEsym:
- entries[n] = sym = TermSymbol.newModule(
- Position.NOPOS, name, owner, flags, (ClassSymbol) readSymbolRef());
- if (name == moduleroot.name && owner == moduleroot.owner()) {
- sym.copyTo(moduleroot);
- entries[n] = sym = moduleroot;
- }
- sym.setInfo(getType(inforef));
- break;
-
case VALsym:
+ Symbol cf = Symbol.NONE;
if (bp < end) {
- assert name.isConstrName();
- Symbol clazz = readSymbolRef();
- entries[n] = sym = clazz.constructor();
- TermSymbol.newConstructor(clazz, flags).copyTo(sym);
+ ClassSymbol clazz = (ClassSymbol) readSymbolRef();
+ if (name.isConstrName()) {
+ entries[n] = sym = clazz.constructor();
+ if (global.debug)
+ global.log("overwriting " + sym);//debug
+ TermSymbol.newConstructor(clazz, flags).copyTo(sym);
+ if (clazz.isCaseClass()) {
+ cf = new TermSymbol(
+ Position.NOPOS, name.toTermName(), owner, flags | CASE);
+ if (name.toTypeName() == classroot.name && owner == moduleroot.owner()) {
+ if (global.debug)
+ global.log("overwriting " + moduleroot);//debug
+ cf.copyTo(moduleroot);
+ cf = moduleroot;
+ } else {
+ owner.info().members().enterOrOverload(cf);
+ }
+ }
+ } else {
+ assert (flags & MODUL) != 0 : name;
+ entries[n] = sym = TermSymbol.newModule(
+ Position.NOPOS, name, owner, flags, clazz);
+ if (name == moduleroot.name && owner == moduleroot.owner()) {
+ if (global.debug)
+ global.log("overwriting " + moduleroot);//debug
+ sym.copyTo(moduleroot);
+ entries[n] = sym = moduleroot;
+ }
+ }
} else {
entries[n] = sym = new TermSymbol(
Position.NOPOS, name, owner, flags);
}
- sym.setInfo(setOwner(getType(inforef), sym));
+ Type tp = getType(inforef);
+ sym.setInfo(setOwner(tp, sym));
+ if (cf.kind != NONE) cf.setInfo(setOwner(tp, cf));
break;
default:
throw new BadSignature(this);
}
- if (owner.kind == CLASS &&
- !(sym == classroot ||
- sym.kind == CLASS && (sym.flags & MODUL) != 0 ||
- (sym.isPrimaryConstructor() &&
- (sym.primaryConstructorClass().flags & MODUL) != 0)))
- owner.members().enter(sym);
+ if (owner.kind == CLASS && !noEnter(sym)) {
+ if (global.debug)
+ global.log("entering " + sym + ":" + sym.type() + " in " + owner);//debug
+ owner.info().members().enterOrOverload(sym);
+ }
}
}
bp = savedBp;
}
return (Symbol) entries[n];
}
+ //where
+ private boolean noEnter(Symbol sym) {
+ return
+ sym == classroot ||
+ sym == moduleroot ||
+ sym.isModuleClass() ||
+ sym.isPrimaryConstructor() && noEnter(sym.primaryConstructorClass());
+ }
+
+
Symbol readSymbolRef() {
return getSymbol(readNat());
@@ -279,6 +326,7 @@ public class UnPickle implements Kinds, Modifiers, EntryTags {
return new Symbol[nread];
} else {
assert bp < end;
+ int bp0 = bp;
int ref = readNat();
if (isSymbolEntry(ref)) {
Symbol s = getSymbol(ref);
@@ -286,6 +334,7 @@ public class UnPickle implements Kinds, Modifiers, EntryTags {
ss[nread] = s;
return ss;
} else {
+ bp = bp0;
return new Symbol[nread];
}
}
@@ -303,7 +352,9 @@ public class UnPickle implements Kinds, Modifiers, EntryTags {
tpe = Type.NoType;
break;
case THIStpe:
- tpe = Type.ThisType(readSymbolRef());
+ Symbol sym = readSymbolRef();
+ tpe = (sym.kind == NONE) ? Type.localThisType
+ : Type.ThisType(sym);
break;
case SINGLEtpe:
tpe = Type.singleType(readTypeRef(), readSymbolRef());
@@ -315,8 +366,7 @@ public class UnPickle implements Kinds, Modifiers, EntryTags {
case COMPOUNDtpe:
Symbol clazz = readSymbolRef();
Type[] parents = readTypeRefs(end);
- Scope members = new Scope(readSymbolRefs(end));
- tpe = Type.compoundType(parents, members, clazz);
+ tpe = Type.compoundType(parents, new Scope(), clazz);
break;
case METHODtpe:
Type restype = readTypeRef();
@@ -339,15 +389,21 @@ public class UnPickle implements Kinds, Modifiers, EntryTags {
tpe = Type.PolyType(readSymbolRefs(end), restype);
break;
case OVERLOADEDtpe:
+ int bp0 = bp;
Symbol[] alts = readSymbolRefs(end);
+ int bp1 = bp;
Type[] alttypes = readTypeRefs(end);
+ assert alts.length == alttypes.length
+ : alts.length + "!=" + alttypes.length +
+ " at " + bp0 + "/" + bp1 + "/" + bp;
for (int i = 0; i < alts.length; i++)
alttypes[i] = setOwner(alttypes[i], alts[i]);
tpe = Type.OverloadedType(alts, alttypes);
break;
case FLAGGEDtpe:
- paramFlags = getFlags(readNat());
- return readTypeRef();
+ readNat(); // skip flags
+ tpe = readTypeRef();
+ break;
default:
throw new BadSignature(this);
}
@@ -369,7 +425,8 @@ public class UnPickle implements Kinds, Modifiers, EntryTags {
if (bp == end) {
return new Type[nread];
} else {
- assert bp < end;
+ assert bp < end : bp + ">" + end;
+ int bp0 = bp;
int ref = readNat();
if (isTypeEntry(ref)) {
Type t = getType(ref);
@@ -377,6 +434,7 @@ public class UnPickle implements Kinds, Modifiers, EntryTags {
ts[nread] = t;
return ts;
} else {
+ bp = bp0;
return new Type[nread];
}
}
diff --git a/sources/scalac/transformer/LambdaLift.java b/sources/scalac/transformer/LambdaLift.java
index 2b8a05135d..c18c466f9a 100644
--- a/sources/scalac/transformer/LambdaLift.java
+++ b/sources/scalac/transformer/LambdaLift.java
@@ -380,8 +380,8 @@ public class LambdaLift extends OwnerTransformer
Tree rhs1 = transform(rhs, sym);
if ((sym.flags & CAPTURED) != 0) {
assert sym.isLocal();
- Type unboxedType = sym.typeAt(descr.nextPhase);
- Type boxedType = descr.refType(unboxedType);
+ Type boxedType = sym.typeAt(descr.nextPhase);
+ Type unboxedType = boxedType.typeArgs()[0];
tpe1 = gen.mkType(tpe.pos, boxedType);
rhs1 = gen.New(
rhs.pos,
diff --git a/sources/scalac/typechecker/Analyzer.java b/sources/scalac/typechecker/Analyzer.java
index 8c427c3c84..bcb7dcb7b7 100644
--- a/sources/scalac/typechecker/Analyzer.java
+++ b/sources/scalac/typechecker/Analyzer.java
@@ -21,9 +21,9 @@ import scalac.util.*;
import scalac.ast.*;
import scalac.ast.printer.*;
import scalac.symtab.*;
-import scalac.symtab.classfile.UnPickle;
+import scalac.symtab.classfile.*;
import Tree.*;
-import java.util.HashMap;
+import java.util.*;
/** The main attribution phase.
*/
@@ -111,16 +111,47 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
this.context = (Context)descr.contexts.remove(unit);
assert this.context != null : "could not find context for " + unit;
unit.body = transformStatSeq(unit.body, Symbol.NONE);
- /** todo: check what this is for
- if (global.target == global.TARGET_JAVA && unit.errors == 0) {
- unit.symdata = new SymData(unit);
+ if (global.target != global.TARGET_INT && global.reporter.errors() == 0) {
+ genSymData(unit.symdata, unit.body);
+ finalizeSymData(unit.symdata);
}
- */
this.unit = null;
this.context = null;
global.operation("checked " + unit);
}
+ public void genSymData(HashMap/*<Name, Pickle>*/ symdata, Tree[] stats) {
+ for (int i = 0; i < stats.length; i++) {
+ switch (stats[i]) {
+ case ClassDef(_, _, _, _, _, _):
+ case ModuleDef(_, _, _, _):
+ case ValDef(_, _, _, _):
+ Symbol sym = stats[i].symbol();
+ Name fullname = sym.kind == VAL
+ ? Name.fromString(sym.owner().fullName() + "." + sym.name)
+ : sym.fullName();
+ Pickle pickle = (Pickle) unit.symdata.get(fullname);
+ if (pickle == null) {
+ pickle = new Pickle();
+ unit.symdata.put(fullname, pickle);
+ }
+ pickle.add(sym);
+ break;
+ case PackageDef(Tree packaged, Tree.Template templ):
+ genSymData(symdata, templ.body);
+ }
+ }
+ }
+
+ public void finalizeSymData(HashMap/*<Name, Pickle>*/ symdata) {
+ for (Iterator it = symdata.entrySet().iterator(); it.hasNext();) {
+ Map.Entry entry = (Map.Entry) it.next();
+ Name fullname = (Name) entry.getKey();
+ Pickle pickle = (Pickle) entry.getValue();
+ pickle.finalize(fullname);
+ }
+ }
+
/** Mode constants
*/
static final int NOmode = 0x000;
@@ -612,14 +643,6 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
Symbol constr = tree.symbol().constructor();
Type constrtype = constr.type().instanceType();
constrtype = constrtype.cloneType(constr, sym);
- /* todo: remove
- switch (tree) {
- case ClassDef(_, _, _, ValDef[][] vparams, _, _):
- if (vparams.length == 0) {
- constrtype = removeMethod(constrtype);
- }
- }
- */
sym.setInfo(constrtype);
}
/* todo: remove
@@ -924,6 +947,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
tparamSyms,
vparamSyms,
Type.TypeRef(sym.owner().thisType(), sym, Symbol.type(tparamSyms)));
+ //System.out.println("set info " + sym.constructor() + " to " + constrtype + " was " + sym.constructor().rawInfo());//DEBUG
sym.constructor().setInfo(constrtype);
// necessary so that we can access tparams
sym.constructor().flags |= INITIALIZED;
@@ -1001,6 +1025,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
owntype = rhs.type;
popContext();
}
+
//checkNonCyclic(tree.pos, owntype);
break;
@@ -1014,7 +1039,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
tp.lookup(selectors[i]) == Symbol.NONE &&
tp.lookup(selectors[i].toTypeName()) == Symbol.NONE &&
tp.lookup(selectors[i].toConstrName()) == Symbol.NONE)
- error(tree.pos, NameTransformer.decode(selectors[i]) + " is not a member of " + expr);
+ error(tree.pos, NameTransformer.decode(selectors[i]) + " is not a member of " + expr + " of type " + expr.type);
}
break;
@@ -1041,6 +1066,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
* into symbol table.
*/
void defineTemplate(Tree.Template templ, Symbol clazz) {
+ //System.out.println("defining " + clazz);//debug
// attribute parent constructors
Tree[] constrs = transformConstrInvocations(templ.pos, templ.parents);
Type[] parents = Tree.typeOf(constrs);
@@ -1144,6 +1170,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
if ((mode & PATTERNmode) != 0) {
if (tree.isType()) {
Symbol clazz = tree.type.unalias().symbol();
+
if (clazz.isCaseClass()) {
// set type to instantiated case class constructor
tree.type = clazz.constructor().type();
@@ -1241,7 +1268,6 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
// find applicable definition and assign to `sym'
Symbol sym = Symbol.NONE;
Type pre;
- Type symtype;
int stopPos = Integer.MIN_VALUE;
Context nextcontext = context;
@@ -1328,7 +1354,8 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
tree = make.Select(tree.pos, qual, name);
checkAccessible(tree.pos, sym, qual);
}
- symtype = pre.memberType(sym);
+ Type symtype = (sym.isType() ? sym.typeConstructor() : sym.type())
+ .asSeenFrom(pre, sym.owner());
if (symtype == Type.NoType)
return error(tree.pos, "not found: " + decode(name));
if ((pt != null && pt.isStable() || (mode & QUALmode) != 0) && sym.isStable()) {
@@ -1359,7 +1386,8 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
sym.flags |= ACCESSED;
if (!TreeInfo.isSelf(qual, context.enclClass.owner))
sym.flags |= SELECTOR;
- Type symtype = qual.type.memberType(sym);
+ Type symtype = (sym.isType() ? sym.typeConstructor() : sym.type())
+ .asSeenFrom(qual.type, sym.owner());
if (symtype == Type.NoType)
return error(tree.pos, "not found: " + decode(name));
//System.out.println(sym.name + ":" + symtype);//DEBUG
@@ -1634,9 +1662,9 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
this.mode = savedMode;
if ((mode & TYPEmode) != 0) {
- // todo: generalize to type constructors?
Symbol sym = tree1.symbol();
- if ((mode & FUNmode) == 0 && sym != null && sym.typeParams().length != 0)
+ if ((mode & FUNmode) == 0 &&
+ sym != null && sym.typeParams().length != 0)
return error(tree.pos, sym + " takes type parameters.");
// else if (tree1.isType())
// return gen.mkType(tree1.pos, tree1.type);
@@ -2223,11 +2251,13 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
Tree tpe1 = transform(tpe, TYPEmode | FUNmode);
Tree[] args1 = transform(args, TYPEmode);
Type[] argtypes = Tree.typeOf(args);
+ Symbol[] tparams = tpe1.type.symbol().typeParams();
+ /*
//todo: this needs to be refined. (same code in RefCheck.transform)
- Symbol[] tparams =
(Type.isSameAs(tpe1.type.typeArgs(), Symbol.type(tpe1.type.unalias().symbol().typeParams())))
- ? tpe1.type.unalias().symbol().typeParams()
+ ?
: Symbol.EMPTY_ARRAY;
+ */
Type owntype = Type.ErrorType;
if (tpe1.type != Type.ErrorType) {
if (tparams.length == args.length)
diff --git a/sources/scalac/typechecker/Infer.java b/sources/scalac/typechecker/Infer.java
index e79fc21990..6690855ec6 100644
--- a/sources/scalac/typechecker/Infer.java
+++ b/sources/scalac/typechecker/Infer.java
@@ -261,6 +261,10 @@ public class Infer implements Modifiers, Kinds {
return cut(variance(tparam, pre));
case CompoundType(Type[] parts, Scope members):
return variance(tparam, parts) & variance(tparam, members.elements());
+ case MethodType(Symbol[] params, Type restype):
+ return flip(variance(tparam, params)) & variance(tparam, restype);
+ case PolyType(Symbol[] tparams, Type restype):
+ return flip(variance(tparam, tparams)) & variance(tparam, restype);
default:
throw new ApplicationError(tp.toString());
}
diff --git a/sources/scalac/typechecker/RefCheck.java b/sources/scalac/typechecker/RefCheck.java
index bf5ca8d62f..9cd8575c6b 100644
--- a/sources/scalac/typechecker/RefCheck.java
+++ b/sources/scalac/typechecker/RefCheck.java
@@ -883,11 +883,14 @@ public class RefCheck extends Transformer implements Modifiers, Kinds {
return super.transform(tree);
case AppliedType(Tree tpe, Tree[] args):
+ Symbol[] tparams = tpe.type.symbol().typeParams();
+ /*
//todo: this needs to be refined. (same code in Analyzer.transform)
Symbol[] tparams =
(Type.isSameAs(
tpe.type.typeArgs(), Symbol.type(tpe.type.unalias().symbol().typeParams())))
? tpe.type.unalias().symbol().typeParams() : Symbol.EMPTY_ARRAY;
+ */
checkBounds(tree.pos, tparams, Tree.typeOf(args));
return elimTypeNode(super.transform(tree));
diff --git a/sources/scalac/util/SourceRepresentation.java b/sources/scalac/util/SourceRepresentation.java
index 7c6ee44107..e5cb210090 100644
--- a/sources/scalac/util/SourceRepresentation.java
+++ b/sources/scalac/util/SourceRepresentation.java
@@ -8,6 +8,8 @@
package scalac.util;
+import java.io.File;
+
public final class SourceRepresentation {
public static int digit2int(byte ch, int base) {
@@ -202,4 +204,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/test/files/pos/matthias4.scala b/test/files/pos/matthias4.scala
index 32200cccd1..bcda93746b 100644
--- a/test/files/pos/matthias4.scala
+++ b/test/files/pos/matthias4.scala
@@ -29,7 +29,7 @@ trait _a extends Object with _b {
def setX(x: B.X): Unit;
}
}
-abstract class a() extends Object with _a with _b {
+abstract class a123() extends Object with _a with _b {
val a: this.type = this;
val A: A = new A();
class A() extends AObject {
@@ -67,7 +67,7 @@ trait _m {
abstract class m() extends Object with _m with _b {
val m: this.type = this;
val M: M = new M();
- class M() extends MObject with a() with Linker() {
+ class M() extends MObject with a123() with Linker() {
def test() = {
val x: B.X = B.getX();
A.setX(x);
diff --git a/test/files/run/Course-2002-07.scala b/test/files/run/Course-2002-07.scala
index 2a45805138..01a0e183b8 100644
--- a/test/files/run/Course-2002-07.scala
+++ b/test/files/run/Course-2002-07.scala
@@ -504,7 +504,7 @@ object MB {
private def vars: List[String] = match {
case Var(n) => List(n)
case Mul(l,r) => l.vars ::: r.vars
- case Pow(l,n) => { val vs = l.vars; List.range(0,n).flatMap(i => vs) }
+ case Pow(l,n) => { val vs = l.vars; Predef.List.range(0,n).flatMap(i => vs) }
case _ => List()
}
diff --git a/test/pos/matthias4.scala b/test/pos/matthias4.scala
index 32200cccd1..bcda93746b 100644
--- a/test/pos/matthias4.scala
+++ b/test/pos/matthias4.scala
@@ -29,7 +29,7 @@ trait _a extends Object with _b {
def setX(x: B.X): Unit;
}
}
-abstract class a() extends Object with _a with _b {
+abstract class a123() extends Object with _a with _b {
val a: this.type = this;
val A: A = new A();
class A() extends AObject {
@@ -67,7 +67,7 @@ trait _m {
abstract class m() extends Object with _m with _b {
val m: this.type = this;
val M: M = new M();
- class M() extends MObject with a() with Linker() {
+ class M() extends MObject with a123() with Linker() {
def test() = {
val x: B.X = B.getX();
A.setX(x);