diff options
Diffstat (limited to 'sources')
-rw-r--r-- | sources/scalac/CompilerCommand.java | 8 | ||||
-rw-r--r-- | sources/scalac/Global.java | 3 | ||||
-rw-r--r-- | sources/scalac/symtab/Symbol.java | 21 | ||||
-rw-r--r-- | sources/scalac/symtab/Type.java | 2 | ||||
-rw-r--r-- | sources/scalac/symtab/classfile/AttributeParser.java | 19 | ||||
-rw-r--r-- | sources/scalac/symtab/classfile/ClassParser.java | 3 | ||||
-rw-r--r-- | sources/scalac/symtab/classfile/ClassfileParser.java | 9 | ||||
-rw-r--r-- | sources/scalac/symtab/classfile/PackageParser.java | 41 | ||||
-rw-r--r-- | sources/scalac/symtab/classfile/Pickle.java | 40 | ||||
-rw-r--r-- | sources/scalac/symtab/classfile/UnPickle.java | 3 | ||||
-rw-r--r-- | sources/scalac/typechecker/Analyzer.java | 16 | ||||
-rw-r--r-- | sources/scalac/typechecker/Infer.java | 2 | ||||
-rw-r--r-- | sources/scalac/util/AbstractFile.java | 32 | ||||
-rw-r--r-- | sources/scalac/util/AbstractFileReader.java | 5 |
14 files changed, 111 insertions, 93 deletions
diff --git a/sources/scalac/CompilerCommand.java b/sources/scalac/CompilerCommand.java index 5b87d72b46..3eb8a1d117 100644 --- a/sources/scalac/CompilerCommand.java +++ b/sources/scalac/CompilerCommand.java @@ -40,7 +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 ChoiceOptionParser separate; //public final OptimizeOptionParser optimize; public final StringOptionParser classpath; public final StringOptionParser sourcepath; @@ -109,9 +109,9 @@ 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.separate = new ChoiceOptionParser(this, + "separate", "read symbol files for separate compilation: (yes, no)", + "separate", new String[]{"yes", "no"}, "default"), //this.optimize = new OptimizeOptionParser(this, // "optimize", "optimize bytecode (-optimize:help for option list)", diff --git a/sources/scalac/Global.java b/sources/scalac/Global.java index 4860eb9402..44636ff982 100644 --- a/sources/scalac/Global.java +++ b/sources/scalac/Global.java @@ -164,7 +164,6 @@ 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; @@ -174,6 +173,8 @@ public class Global { this.classPath = args.classpath(); this.outpath = args.outpath(); this.target = interpret ? TARGET_INT : args.target.value.intern(); + this.separate = args.separate.value.equals("yes") || + args.separate.value.equals("default") && !this.target.equals(TARGET_INT); this.uniqueID = new UniqueID(); String printFile = args.printfile.value; try { diff --git a/sources/scalac/symtab/Symbol.java b/sources/scalac/symtab/Symbol.java index 280d3f73e6..55bb65b6ac 100644 --- a/sources/scalac/symtab/Symbol.java +++ b/sources/scalac/symtab/Symbol.java @@ -148,15 +148,13 @@ public abstract class Symbol implements Modifiers, Kinds { || info instanceof Type.PolyType && ((Type.PolyType)info).result instanceof Type.MethodType : "illegal type for " + this + ": " + info; - //if ((flags & (INITIALIZED | LOCKED)) != (INITIALIZED | LOCKED)) { - if (infos == TypeIntervalList.EMPTY) { - infos = new TypeIntervalList(TypeIntervalList.EMPTY); - } - infos.limit = limit; - infos.info = info; - if (info instanceof Type.LazyType) flags &= ~INITIALIZED; - else flags |= INITIALIZED; - //} + if (infos == TypeIntervalList.EMPTY) { + infos = new TypeIntervalList(TypeIntervalList.EMPTY); + } + infos.limit = limit; + infos.info = info; + if (info instanceof Type.LazyType) flags &= ~INITIALIZED; + else flags |= INITIALIZED; return this; } @@ -205,6 +203,7 @@ public abstract class Symbol implements Modifiers, Kinds { /** Does this symbol denote a value? */ public final boolean isValue() { + preInitialize(); return kind == VAL && !(isModule() && isJava()) && !isPackage(); } @@ -615,7 +614,8 @@ public abstract class Symbol implements Modifiers, Kinds { public final void preInitialize() { //todo: clean up if (infos.info instanceof ClassParser || - infos.info instanceof SourceCompleter) + infos.info instanceof SourceCompleter || + infos.info instanceof ClassParser.StaticsParser) infos.info.complete(this); } @@ -627,6 +627,7 @@ public abstract class Symbol implements Modifiers, Kinds { * its baseclasses and members. */ public Type info() { + //if (isModule()) moduleClass().initialize(); int id = currentPhaseId(); if ((flags & INITIALIZED) == 0) { Type info = rawInfoAt(FIRST_ID); diff --git a/sources/scalac/symtab/Type.java b/sources/scalac/symtab/Type.java index 7b27647e22..10578d02de 100644 --- a/sources/scalac/symtab/Type.java +++ b/sources/scalac/symtab/Type.java @@ -53,7 +53,7 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { */ public case TypeRef(Type pre, Symbol sym, Type[] args) { assert pre.isLegalPrefix() || pre == ErrorType : pre + "#" + sym; - assert sym.kind == ERROR || sym.isType() : pre + "#" + sym; + assert sym.kind == ERROR || sym.isType() : pre + " # " + sym; } /** parts_1 with ... with parts_n { members } diff --git a/sources/scalac/symtab/classfile/AttributeParser.java b/sources/scalac/symtab/classfile/AttributeParser.java index 4df2529b2d..a4cfc6fec6 100644 --- a/sources/scalac/symtab/classfile/AttributeParser.java +++ b/sources/scalac/symtab/classfile/AttributeParser.java @@ -81,18 +81,8 @@ public class AttributeParser implements ClassfileConstants { switch (attr) { // class attributes case SCALA_ATTR: - in.skip(attrLen); - /* not yet - Name sourcefile = (Name)pool.readPool(in.nextChar()); - new UnPickle( - (JavaClassSymbol) sym, in.nextBytes(attrLen - 2), sourcefile); - */ - return; - - case SOURCEFILE_ATTR: - // ((ClassDef)def).sourcefile = (Name)reader.readPool(in.nextChar()); - in.skip(attrLen); - return; + new UnPickle(sym, in.nextBytes(attrLen), Name.fromString(in.path)); + return; case INNERCLASSES_ATTR: /* int n = in.nextChar(); @@ -154,8 +144,11 @@ public class AttributeParser implements ClassfileConstants { new MetaParser(meta, tvars, sym, type).parse(), Symbol.FIRST_ID); return; + + default: + in.skip(attrLen); + return; } - throw new RuntimeException("unknown classfile attribute"); } Scope tvars = new Scope(); diff --git a/sources/scalac/symtab/classfile/ClassParser.java b/sources/scalac/symtab/classfile/ClassParser.java index 19eb931f3b..0dc29c87bb 100644 --- a/sources/scalac/symtab/classfile/ClassParser.java +++ b/sources/scalac/symtab/classfile/ClassParser.java @@ -28,6 +28,7 @@ public class ClassParser extends Type.LazyType { /** complete class symbol c by loading the class */ public void complete(Symbol c) { + c.owner().initialize(); //System.out.println("loading " + c);//DEBUG try { long msec = System.currentTimeMillis(); @@ -59,7 +60,7 @@ public class ClassParser extends Type.LazyType { return new AliasParser(alias); } - class StaticsParser extends Type.LazyType { + public class StaticsParser extends Type.LazyType { Symbol clazz; StaticsParser(Symbol clazz) { diff --git a/sources/scalac/symtab/classfile/ClassfileParser.java b/sources/scalac/symtab/classfile/ClassfileParser.java index 098be96b06..da5300cb42 100644 --- a/sources/scalac/symtab/classfile/ClassfileParser.java +++ b/sources/scalac/symtab/classfile/ClassfileParser.java @@ -97,11 +97,12 @@ public class ClassfileParser implements ClassfileConstants { c.setInfo(classType, Symbol.FIRST_ID); // set type of statics Symbol staticsClass = c.module().moduleClass(); - Type staticsInfo = Type.compoundType(Type.EMPTY_ARRAY, statics, staticsClass); - staticsClass.setInfo(staticsInfo, Symbol.FIRST_ID); - c.module().setInfo(Type.TypeRef(staticsClass.owner().thisType(), + if (staticsClass.isModuleClass()) { + Type staticsInfo = Type.compoundType(Type.EMPTY_ARRAY, statics, staticsClass); + staticsClass.setInfo(staticsInfo, Symbol.FIRST_ID); + c.module().setInfo(Type.TypeRef(staticsClass.owner().thisType(), staticsClass, Type.EMPTY_ARRAY)); - + } basetpes[0] = supertpe; for (int i = 1; i < basetpes.length; i++) basetpes[i] = readClassType(in.nextChar()); diff --git a/sources/scalac/symtab/classfile/PackageParser.java b/sources/scalac/symtab/classfile/PackageParser.java index 9fdbe797ed..1b29c7a0ef 100644 --- a/sources/scalac/symtab/classfile/PackageParser.java +++ b/sources/scalac/symtab/classfile/PackageParser.java @@ -8,10 +8,12 @@ package scalac.symtab.classfile; +import ch.epfl.lamp.util.*; import scalac.*; import scalac.symtab.*; import scalac.util.*; import java.io.*; +import java.util.HashMap; public class PackageParser extends Type.LazyType { @@ -39,18 +41,19 @@ public class PackageParser extends Type.LazyType { Scope members = new Scope(); String dirname = null; Name name = p.fullName(); + HashMap/*<Symbol, AbstractFile>*/ symFile = new HashMap(); if (name.length() == 0) { // includeMembers(AbstractFile.open(null, "."), p, members, false); } else { dirname = SourceRepresentation.externalizeFileName(name); - assert !dirname.startsWith("com") : p;//debug if (!dirname.endsWith("/")) dirname += "/"; } String[] base = global.classPath.components(); for (int i = 0; i < base.length; i++) { includeMembers( - AbstractFile.open(base[i], dirname), p, members, dirname != null); + AbstractFile.open(base[i], dirname), + p, members, dirname != null, symFile); } p.setInfo(Type.compoundType(Type.EMPTY_ARRAY, members, p)); if (dirname == null) @@ -59,11 +62,24 @@ public class PackageParser extends Type.LazyType { (System.currentTimeMillis() - msec) + "ms"); } + private boolean isMostRecent(AbstractFile f, Symbol previous, HashMap symFile) { + if (previous == Symbol.NONE || previous.isPackage()) return true; + if (previous.pos != Position.NOPOS) return false; + AbstractFile pf = (AbstractFile) symFile.get(previous); + if (!global.separate) { + if (f.getName().endsWith(".scala") && + pf.getName().endsWith(".class")) return true; + if (f.getName().endsWith(".class") && + pf.getName().endsWith(".scala")) return false; + } + return f.lastModified() > pf.lastModified(); + } + /** read directory of a classpath directory and include members * in package/module scope */ protected void includeMembers(AbstractFile dir, Symbol p, Scope locals, - boolean inclClasses) { + boolean inclClasses, HashMap symFile) { if (dir == null) return; String[] filenames = null; @@ -72,14 +88,17 @@ public class PackageParser extends Type.LazyType { return; for (int j = 0; j < filenames.length; j++) { String fname = filenames[j]; + AbstractFile f = dir.open(fname); if (inclClasses && fname.endsWith(".class")) { Name n = Name.fromString(fname.substring(0, fname.length() - 6)) .toTypeName(); - if (locals.lookup(n) == Symbol.NONE) { + if (isMostRecent(f, locals.lookup(n), symFile)) { ClassSymbol clazz = new ClassSymbol(n, p, classCompletion); // todo: needed? clazz.allConstructors().setInfo( classCompletion.staticsParser(clazz)); + clazz.module().setInfo( + classCompletion.staticsParser(clazz)); // enter class locals.enter(clazz); // enter module, except for scala.Object class @@ -93,14 +112,18 @@ public class PackageParser extends Type.LazyType { } locals.enter(clazz.module()); } + symFile.put(clazz, f); } } else if (fname.endsWith("/") && !fname.equals("META-INF/")) { Name n = Name.fromString(fname.substring(0, fname.length() - 1)); if (locals.lookup(n) == Symbol.NONE) { TermSymbol module = TermSymbol.newJavaPackageModule(n, p, this); locals.enter(module); + //todo: moduleClass needs to be entered? locals.enter(module.moduleClass()); - } + } + +/* } else if (inclClasses && fname.endsWith(".symbl")) { //todo: compare dates between symbl and scala. Name n = Name.fromString(fname.substring(0, fname.length() - 6)) @@ -117,14 +140,11 @@ public class PackageParser extends Type.LazyType { locals.enter(clazz); 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.isPackage() || - sym.rawInfoAt(Symbol.FIRST_ID) instanceof ClassParser && - !(sym.rawInfoAt(Symbol.FIRST_ID) instanceof SymblParser)) { + if (isMostRecent(f, locals.lookup(n), symFile)) { SourceCompleter completer = new SourceCompleter(global); ClassSymbol clazz = new ClassSymbol(n, p, completer); //todo: needed? @@ -133,6 +153,7 @@ public class PackageParser extends Type.LazyType { // enter class locals.enter(clazz); locals.enter(clazz.module()); + symFile.put(clazz, f); } } } diff --git a/sources/scalac/symtab/classfile/Pickle.java b/sources/scalac/symtab/classfile/Pickle.java index fe41289f8f..bae101668d 100644 --- a/sources/scalac/symtab/classfile/Pickle.java +++ b/sources/scalac/symtab/classfile/Pickle.java @@ -72,46 +72,6 @@ public class Pickle implements Kinds, Modifiers, EntryTags { return bp; } - /** 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) { - } - } - } - - public 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); - } - } - /* ************************************************** * Phase 1: Build entry table ************************************************* */ diff --git a/sources/scalac/symtab/classfile/UnPickle.java b/sources/scalac/symtab/classfile/UnPickle.java index de755fd7fd..07c30a60c4 100644 --- a/sources/scalac/symtab/classfile/UnPickle.java +++ b/sources/scalac/symtab/classfile/UnPickle.java @@ -35,7 +35,6 @@ public class UnPickle implements Kinds, Modifiers, EntryTags { Global global; UnPickle(Symbol root, byte[] data, Name sourceName) { - assert !root.isInitialized(); global = Global.instance; if (root.isConstructor()) { this.classroot = root.primaryConstructorClass(); @@ -70,6 +69,8 @@ public class UnPickle implements Kinds, Modifiers, EntryTags { if (global.debug) global.log("unpickled " + root + ":" + root.rawInfo());//debug if (!root.isInitialized()) throw new BadSignature(this, "it does not define " + root); + if (moduleroot.isModule() && !moduleroot.moduleClass().isInitialized()) + moduleroot.setInfo(Type.NoType); } Type setOwner(Type tp, Symbol owner) { diff --git a/sources/scalac/typechecker/Analyzer.java b/sources/scalac/typechecker/Analyzer.java index 9a9803691f..3c3812c573 100644 --- a/sources/scalac/typechecker/Analyzer.java +++ b/sources/scalac/typechecker/Analyzer.java @@ -129,7 +129,6 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { pickle.add(sym.owner().info().lookup(sym.name.toTermName())); pickle.add(sym.owner().info().lookup(sym.name.toTypeName())); pickle.pickle(); - pickle.writeFile(fullname); global.symdata.put(fullname, pickle); } break; @@ -270,12 +269,6 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { * - symbols with `override' modifier override some other symbol. */ void validate(Symbol sym) { - checkNoConflict(sym, DEFERRED, PRIVATE); - checkNoConflict(sym, FINAL, SEALED); - checkNoConflict(sym, FINAL, PRIVATE); - checkNoConflict(sym, PRIVATE, PROTECTED); - checkNoConflict(sym, PRIVATE, OVERRIDE); - checkNoConflict(sym, DEFERRED, FINAL); if ((sym.flags & ABSTRACTCLASS) != 0 && sym.kind != CLASS) { error(sym.pos, "`abstract' modifier can be used only for classes; " + "\nit should be omitted for abstract members"); @@ -317,6 +310,12 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { sym.flags &= ~OVERRIDE; } } + checkNoConflict(sym, DEFERRED, PRIVATE); + checkNoConflict(sym, FINAL, SEALED); + checkNoConflict(sym, FINAL, PRIVATE); + checkNoConflict(sym, PRIVATE, PROTECTED); + checkNoConflict(sym, PRIVATE, OVERRIDE); + checkNoConflict(sym, DEFERRED, FINAL); } /** Check that @@ -712,8 +711,9 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { tree.pos, name.toTermName(), owner, mods & ACCESSFLAGS | CASE, context.scope); enterInScope(cf); - if (!cf.isInitialized()) + if (!cf.isInitialized() || cf.info().symbol().isModuleClass()) { cf.setInfo(new LazyConstrMethodType(tree)); + } } } return enterSym(tree, clazz); diff --git a/sources/scalac/typechecker/Infer.java b/sources/scalac/typechecker/Infer.java index 6690855ec6..b3a6babae5 100644 --- a/sources/scalac/typechecker/Infer.java +++ b/sources/scalac/typechecker/Infer.java @@ -926,11 +926,13 @@ public class Infer implements Modifiers, Kinds { if (i == alts.length) throw new Type.Error("missing arguments for " + alts[0]); } + /* // then catch the case of a single alternative. if (alts.length == 1) { tree.setSymbol(alts[0]).setType(alttypes[0]); return; } + */ // finally, do the normal case. int best = -1; for (int i = 0; i < alttypes.length; i++) { diff --git a/sources/scalac/util/AbstractFile.java b/sources/scalac/util/AbstractFile.java index 2487e07ca3..7069df868b 100644 --- a/sources/scalac/util/AbstractFile.java +++ b/sources/scalac/util/AbstractFile.java @@ -39,6 +39,10 @@ public abstract class AbstractFile { */ public abstract boolean isDirectory(); + /** date file was last modified + */ + public abstract long lastModified(); + /** read content of the file into a byte[] buffer */ public abstract byte[] read() throws IOException; @@ -129,6 +133,10 @@ class PlainFile extends AbstractFile { return f.isDirectory(); } + public long lastModified() { + return f.lastModified(); + } + public byte[] read() throws IOException { FileInputStream in = new FileInputStream(f); int rest = (int)f.length(); @@ -196,6 +204,10 @@ class ZippedFile extends AbstractFile { return zipEntry.isDirectory(); } + public long lastModified() { + return zipEntry.getTime(); + } + public byte[] read() throws IOException { InputStream in = dir.zipFile.getInputStream(zipEntry); int rest = (int)zipEntry.getSize(); @@ -254,6 +266,10 @@ class ZipDir extends AbstractFile { return (zipFile != null); } + public long lastModified() { + return -1; + } + public byte[] read() throws IOException { throw new IOException("cannot read directory"); } @@ -322,6 +338,10 @@ final class JarArchive extends AbstractFile { return jarFile != null; } + public long lastModified() { + return -1; + } + public byte[] read() throws IOException { throw new IOException("cannot read archive"); } @@ -443,6 +463,10 @@ final class JarArchive extends AbstractFile { return true; } + public long lastModified() { + return -1; + } + public String[] list() throws IOException { throw new IOException("not a directory"); } @@ -510,6 +534,10 @@ final class JarArchive extends AbstractFile { return false; } + public long lastModified() { + return -1; + } + public String[] list() throws IOException { throw new IOException("not a directory"); } @@ -537,6 +565,10 @@ final class JarArchive extends AbstractFile { return true; } + public long lastModified() { + return jarFile.getJarEntry(name).getTime(); + } + public byte[] read() throws IOException { JarEntry jarEntry = jarFile.getJarEntry(name); if (jarEntry == null) diff --git a/sources/scalac/util/AbstractFileReader.java b/sources/scalac/util/AbstractFileReader.java index 0d18292838..2f7d0e1e21 100644 --- a/sources/scalac/util/AbstractFileReader.java +++ b/sources/scalac/util/AbstractFileReader.java @@ -21,11 +21,16 @@ public class AbstractFileReader { */ public int bp; + /** the file path name + */ + public final String path; + /** constructor */ public AbstractFileReader(AbstractFile f) throws IOException { buf = f.read(); bp = 0; + path = f.getPath(); } /** return byte at offset 'pos' |