diff options
Diffstat (limited to 'sources')
-rw-r--r-- | sources/scala/List.scala | 28 | ||||
-rw-r--r-- | sources/scala/Nil.scala | 2 | ||||
-rw-r--r-- | sources/scala/None.scala | 2 | ||||
-rw-r--r-- | sources/scala/Option.scala | 4 | ||||
-rw-r--r-- | sources/scalac/Global.java | 28 | ||||
-rw-r--r-- | sources/scalac/symtab/Symbol.java | 37 | ||||
-rw-r--r-- | sources/scalac/transformer/UnCurry.java | 3 | ||||
-rw-r--r-- | sources/scalac/typechecker/Analyzer.java | 131 |
8 files changed, 156 insertions, 79 deletions
diff --git a/sources/scala/List.scala b/sources/scala/List.scala index d80a13e273..b94d6060db 100644 --- a/sources/scala/List.scala +++ b/sources/scala/List.scala @@ -53,7 +53,7 @@ trait List[a] extends Seq[a] { * @return the number of elements in the list. */ def length: Int = this match { - case Nil() => 0 + case Nil => 0 case _ :: xs => xs.length + 1 } @@ -71,7 +71,7 @@ trait List[a] extends Seq[a] { */ def init: List[a] = if (isEmpty) error("Nil.init") - else if (tail.isEmpty) Nil() + else if (tail.isEmpty) Nil else head :: tail.init; /** Returns the last element of this list. @@ -89,7 +89,7 @@ trait List[a] extends Seq[a] { * @throws java.lang.RuntimeException if the list is too short. */ def take(n: Int): List[a] = - if (n == 0) Nil() + if (n == 0) Nil else head :: tail.take(n-1); /** Returns the list without its <code>n</code> first elements. @@ -108,7 +108,7 @@ trait List[a] extends Seq[a] { * the predicate <code>p</code>. */ def takeWhile(p: a => Boolean): List[a] = - if (isEmpty || !p(head)) Nil() + if (isEmpty || !p(head)) Nil else head :: tail.takeWhile(p); /** Returns the longest suffix of this list whose first element does not satisfy @@ -137,7 +137,7 @@ trait List[a] extends Seq[a] { * @return <code>[f(a0), ..., f(an)]</code> if this list is <code>[a0, ..., an]</code>. */ def map[b](f: a => b): List[b] = - if (isEmpty) Nil() + if (isEmpty) Nil else f(head) :: tail.map(f); /** Apply the given function <code>f</code> to each element of this list (while respecting @@ -183,23 +183,23 @@ trait List[a] extends Seq[a] { * is <code>[a0, a1, ..., an]</code>. */ def foldl_:[b](z: b)(f: (b, a) => b): b = match { - case Nil() => z + case Nil => z case x :: xs => (xs.foldl_:[b](f(z, x)))(f) } def foldr[b](z: b)(f: (a, b) => b): b = match { - case Nil() => z + case Nil => z case x :: xs => f(x, (xs foldr z)(f)) } def foldl1(f: (a, a) => a): a = this match { - case Nil() => error("foldl1 of empty list") + case Nil => error("foldl1 of empty list") case x :: xs => (x foldl_: xs)(f) } def foldr1(f: (a, a) => a): a = match { - case Nil() => error("foldr1 of empty list") - case x :: Nil() => x + case Nil => error("foldr1 of empty list") + case x :: Nil => x case x :: xs => f(x, xs foldr1 f) } @@ -210,7 +210,7 @@ trait List[a] extends Seq[a] { * <code>[a0, ..., an]</code>. */ def flatMap[b](f: a => List[b]): List[b] = - if (isEmpty) Nil() + if (isEmpty) Nil else f(head) ::: tail.flatMap(f); /** Reverses the elements of this list. @@ -220,7 +220,7 @@ trait List[a] extends Seq[a] { * @return the elements of this list in reverse order. */ def reverse: List[a] = { - ((Nil(): List[a]) foldl_: this)((xs: List[a], x: a) => x :: xs) + ((Nil: List[a]) foldl_: this)((xs: List[a], x: a) => x :: xs) } /** Prints on standard output a raw textual representation of this list. @@ -229,7 +229,7 @@ trait List[a] extends Seq[a] { * <code>[1, 2, 3] print</code> will display <code>1 :: 2 :: 3 :: []</code>. */ def print: Unit = - if (isEmpty) java.lang.System.out.println("Nil()") + if (isEmpty) java.lang.System.out.println("Nil") else { java.lang.System.out.print(head as java.lang.Object); java.lang.System.out.print(" :: "); @@ -284,7 +284,7 @@ trait List[a] extends Seq[a] { * @throws java.lang.RuntimeException if lists have different lengths. */ def zip[b](that: List[b]): List[Tuple2[a,b]] = - if (this.isEmpty || that.isEmpty) Nil() + if (this.isEmpty || that.isEmpty) Nil else Tuple2(this.head, that.head) :: this.tail.zip(that.tail); /** Tests if the given value <code>elem</code> is a member of diff --git a/sources/scala/Nil.scala b/sources/scala/Nil.scala index d6d67433f8..82460f5de3 100644 --- a/sources/scala/Nil.scala +++ b/sources/scala/Nil.scala @@ -3,7 +3,7 @@ package scala { /* An empty list. Scala provides <code>[]</code> as syntactic sugar * for <code>Nil</code>. */ - final case class Nil[c]() extends List[c] { + final case class Nil[c] extends List[c] { def isEmpty = true; def head: c = error("head of empty list"); def tail: List[c] = error("tail of empty list"); diff --git a/sources/scala/None.scala b/sources/scala/None.scala index 7563dae231..fe034a3f34 100644 --- a/sources/scala/None.scala +++ b/sources/scala/None.scala @@ -1,5 +1,5 @@ package scala { - final case class None[b]() extends Option[b] { + final case class None[b] extends Option[b] { def isNone = true; def get: b = error("None does not have an element."); } diff --git a/sources/scala/Option.scala b/sources/scala/Option.scala index 2640ecec7b..3c7abb7034 100644 --- a/sources/scala/Option.scala +++ b/sources/scala/Option.scala @@ -6,12 +6,12 @@ package scala { def get: a; def map[b](f: a => b): Option[b] = this match { - case None() => None() + case None => None case Some(x) => Some(f(x)) } def toList: List[a] = this match { - case None() => Predef.List() + case None => Predef.List() case Some(x) => Predef.List(x) } diff --git a/sources/scalac/Global.java b/sources/scalac/Global.java index 15eb81baf8..c4ecc98a88 100644 --- a/sources/scalac/Global.java +++ b/sources/scalac/Global.java @@ -17,10 +17,7 @@ import scalac.symtab.Definitions; import scalac.ast.printer.*; import scalac.backend.Primitives; // !!! <<< Interpreter stuff -import scalac.symtab.Kinds; -import scalac.symtab.Type; -import scalac.symtab.Symbol; -import scalac.symtab.Scope; +import scalac.symtab.*; // !!! >>> Interpreter stuff @@ -87,6 +84,10 @@ public class Global { public OutputStream printStream; public final TreePrinter debugPrinter; + /** The set of currenttly compiled top-level symbols + */ + public HashSet/*Symbol*/ compiledNow = new HashSet(); + /** the current phase */ public PhaseDescriptor currentPhase; @@ -280,8 +281,13 @@ public class Global { if (currentPhase == PHASE.PARSER) fix1(); if (currentPhase == PHASE.ANALYZER) fix2(); } - if (reporter.errors() != 0) imports.clear(); - + if (reporter.errors() != 0) { + imports.clear(); + for (Iterator it = compiledNow.iterator(); it.hasNext();) { + uninitialize((Symbol)it.next()); + } + } + compiledNow.clear(); printer.end(); } // !!! <<< Interpreter stuff @@ -623,4 +629,14 @@ public class Global { reporter.inform("[" + message + " in " + (System.currentTimeMillis() - start) + "ms]"); } + + private void uninitialize(Symbol sym) { + if (sym instanceof ClassSymbol) { + ClassSymbol clazz = (ClassSymbol)sym; + if (clazz.sourcefile != null) { + clazz.reset( + new SourceCompleter(this, clazz.sourcefile)); + } + } + } } diff --git a/sources/scalac/symtab/Symbol.java b/sources/scalac/symtab/Symbol.java index 92eca67cce..35ceb28e36 100644 --- a/sources/scalac/symtab/Symbol.java +++ b/sources/scalac/symtab/Symbol.java @@ -884,6 +884,13 @@ public abstract class Symbol implements Modifiers, Kinds { } } } + + public void reset(Type completer) { + this.flags &= (FINAL | MODUL); + this.pos = 0; + this.infos = TypeIntervalList.EMPTY; + this.setInfo(completer); + } } /** A class for term symbols @@ -924,7 +931,7 @@ public class TermSymbol extends Symbol { */ public static TermSymbol newCompanionModule(Symbol clazz, int flags, Type.LazyType parser) { TermSymbol sym = newModule(Position.NOPOS, clazz.name.toTermName(), clazz.owner(), - FINAL | flags); + flags); sym.clazz.setInfo(parser); return sym; } @@ -946,8 +953,7 @@ public class TermSymbol extends Symbol { } /** Get the fully qualified name of this Symbol */ public Name fullName() { - if (isModule()) return moduleClass().fullName(); - else if (isPrimaryConstructor()) return primaryConstructorClass().fullName(); + if (clazz != null) return clazz.fullName(); else return super.fullName(); } @@ -1106,6 +1112,12 @@ public class TypeSymbol extends Symbol { adjustType(parents[i]); } } + + public void reset(Type completer) { + super.reset(completer); + closures = ClosureIntervalList.EMPTY; + tycon = null; + } } /** A class for class symbols. It has JavaClassSymbol as a subclass. @@ -1134,7 +1146,14 @@ public class ClassSymbol extends TypeSymbol { /** A cache for this.thisType() */ - private Type thistp = Type.ThisType(this); + final private Type thistp = Type.ThisType(this); + + /** The sourcefile name form where the class symbol was or + * needs to be loaded. only defined for Scala source library classes; + * not for classes that exist in class files, or classes compiled + * from the command line. + */ + public String sourcefile = null; /** Principal Constructor */ @@ -1158,6 +1177,7 @@ public class ClassSymbol extends TypeSymbol { this.module = TermSymbol.newCompanionModule(this, 0, parser); this.mangled = name; this.setInfo(parser); + this.sourcefile = parser.filename; } /** Constructor for classes to load as class files. @@ -1178,6 +1198,7 @@ public class ClassSymbol extends TypeSymbol { other.constructor.setInfo(constructor.info()); other.mangled = mangled; other.module = module; + other.sourcefile = sourcefile; if (thisSym != this) other.setTypeOfThis(typeOfThis()); return other; } @@ -1279,6 +1300,14 @@ public class ClassSymbol extends TypeSymbol { assert sym != null : this; return sym; } + + public void reset(Type completer) { + super.reset(completer); + constructor().reset(completer); + module().reset(completer); + template = null; + thisSym = this; + } } /** A class for error symbols. diff --git a/sources/scalac/transformer/UnCurry.java b/sources/scalac/transformer/UnCurry.java index dac20cba6d..4995a82286 100644 --- a/sources/scalac/transformer/UnCurry.java +++ b/sources/scalac/transformer/UnCurry.java @@ -172,7 +172,8 @@ public class UnCurry extends OwnerTransformer case PolyType(_, Type restp): return transformArgs(pos, args, restp); default: - throw new ApplicationError(methtype); + if (args.length == 0) return args; // could be arguments of nullary case pattern + else throw new ApplicationError(methtype); } } diff --git a/sources/scalac/typechecker/Analyzer.java b/sources/scalac/typechecker/Analyzer.java index 8c57883545..512cd047a6 100644 --- a/sources/scalac/typechecker/Analyzer.java +++ b/sources/scalac/typechecker/Analyzer.java @@ -19,7 +19,6 @@ import scalac.ast.printer.*; import scalac.symtab.*; import Tree.*; import java.util.HashMap; -import java.util.HashSet; public class Analyzer extends Transformer implements Modifiers, Kinds { @@ -42,10 +41,8 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { private Context context; private Type pt; private int mode; - private HashSet compiledNow = new HashSet(); public void apply() { - compiledNow.clear(); for (int i = 0; i < global.units.length; i++) { enterUnit(global.units[i]); } @@ -813,7 +810,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { } result = other; } else if (sym.owner().isPackage()) { - if (compiledNow.contains(other)) { + if (global.compiledNow.contains(other)) { error(sym.pos, sym + " is compiled twice"); } context.scope.unlink(e); @@ -837,7 +834,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { } else { context.scope.enter(sym); } - if (result.owner().isPackage()) compiledNow.add(result); + if (result.owner().isPackage()) global.compiledNow.add(result); return result; } @@ -1590,9 +1587,9 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { tree = error(tree.pos, ex.msg); } return adapt(tree, mode, pt); - } else if ((mode & EXPRmode) != 0) { - // will be instantiated later - return tree; +// } else if ((mode & EXPRmode) != 0) { +// // will be instantiated later +// return tree; } break; @@ -1606,12 +1603,11 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { return error(tree.pos, "missing arguments for class constructor"); } } - if ((mode & FUNmode) != 0) { - if ((mode & PATTERNmode) != 0) { - // set type to instantiated case class constructor - if (tree.type == Type.ErrorType) return tree; + 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(); switch (tree.type) { case PolyType(Symbol[] tparams, Type restp): @@ -1619,10 +1615,14 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { infer.constructorInstance(tree, tparams, restp, pt); } catch (Type.Error ex) { if (pt != Type.ErrorType) error(tree.pos, ex.msg); - tree.setType(Type.ErrorType); + return tree.setType(Type.ErrorType); } + if (!(tree.type instanceof Type.MethodType)) + tree = make.Apply(tree.pos, tree, Tree.EMPTY_ARRAY) + .setType(tree.type); } } else if (clazz.isSubClass(definitions.SEQ_CLASS)) { + // set type to instantiated sequence class constructor Type seqtp = dropVarArgs(pt.baseType(clazz)); if (seqtp != Type.NoType) { tree.type = seqConstructorType(seqtp, pt); @@ -1630,55 +1630,86 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { error(tree.pos, "expected pattern type " + pt + " does not conform to sequence " + clazz); } - } else { + } else if (tree.type != Type.ErrorType) { error(tree.pos, tree.symbol() + " is neither a case class constructor nor a sequence class constructor"); } - return tree; - } else if ((mode & EXPRmode) != 0 && tree.type.isObjectType()) { - // insert apply method - Symbol applyMeth = tree.type.lookup(Names.apply); - if (applyMeth != Symbol.NONE && isAccessible(applyMeth, tree)) { - applyMeth.flags |= (ACCESSED | SELECTOR); - tree = make.Select(tree.pos, tree, Names.apply) - .setSymbol(applyMeth) - .setType(tree.type.memberType(applyMeth)); - return adapt(tree, mode, pt); - } } - } else if ((mode & (EXPRmode | FUNmode)) == EXPRmode) { - Symbol fsym = TreeInfo.methSymbol(tree); - if (fsym != null && fsym.isMethod() && (fsym.flags & CASE) != 0) { - Symbol constr = fsym.owner().info() - .lookup(fsym.name.toTypeName()).constructor(); - Template templ = make.Template( - tree.pos, - new Tree[]{desugarize.toConstructor(tree, constr)}, - Tree.EMPTY_ARRAY); - //templ.setSymbol(Symbol.NONE).setType(tree.type); - return transform( - make.New(tree.pos, templ).setType(tree.type.instanceType()), mode, pt); - } else if ((mode & QUALmode) == 0) { - // check that packages and static modules are not used as values + if ((mode & FUNmode) != 0) { + return tree; + } else { Symbol sym = tree.symbol(); - if (sym != null && sym.kind != ERROR && !sym.isValue() && tree.isTerm()) { - new TextTreePrinter().print(tree).println().end();//debug - error(tree.pos, tree.symbol() + " is not a value"); + // convert nullary case methods to types + // check that other idents or selects are stable. + switch (tree) { + case Ident(Name name): + if (sym != null && isNullaryMethod(sym) && (sym.flags & CASE) != 0) { + ((Ident)tree).name = name.toTypeName(); + return transform(tree, mode, pt); + } else { + checkStable(tree); + } + break; + case Select(_, Name selector): + if (sym != null && isNullaryMethod(sym) && (sym.flags & CASE) != 0) { + ((Select)tree).selector = selector.toTypeName(); + return transform(tree, mode, pt); + } else { + checkStable(tree); + } } } - } else if ((mode & (PATTERNmode | FUNmode)) == PATTERNmode) { - switch (tree) { - case Ident(_): - case Select(_, _): - if (!tree.type.unalias().symbol().isCaseClass()) - checkStable(tree); + } else if ((mode & EXPRmode) != 0) { + if ((mode & FUNmode) != 0) { + if (tree.type.isObjectType()) { + // insert apply method + Symbol applyMeth = tree.type.lookup(Names.apply); + if (applyMeth != Symbol.NONE && isAccessible(applyMeth, tree)) { + applyMeth.flags |= (ACCESSED | SELECTOR); + tree = make.Select(tree.pos, tree, Names.apply) + .setSymbol(applyMeth) + .setType(tree.type.memberType(applyMeth)); + return adapt(tree, mode, pt); + } + } + } else { + Symbol fsym = TreeInfo.methSymbol(tree); + if (fsym != null && fsym.isMethod() && (fsym.flags & CASE) != 0) { + // convert case methods to new's + Symbol constr = fsym.owner().info() + .lookup(fsym.name.toTypeName()).constructor(); + Template templ = make.Template( + tree.pos, + new Tree[]{desugarize.toConstructor(tree, constr)}, + Tree.EMPTY_ARRAY); + return transform(make.New(tree.pos, templ), mode, pt); + } else if ((mode & QUALmode) == 0) { + // check that packages and static modules are not used as values + Symbol sym = tree.symbol(); + if (sym != null && sym.kind != ERROR && !sym.isValue() && + tree.isTerm()) { + new TextTreePrinter().print(tree).println().end();//debug + error(tree.pos, tree.symbol() + " is not a value"); + } + } } } - // check type against prototype - return tree.setType(checkType(tree.pos, tree.type, pt)); + if (!(tree.type instanceof Type.PolyType)) + tree.type = checkType(tree.pos, tree.type, pt); + + return tree; } //where + boolean isNullaryMethod(Symbol sym) { + switch (sym.type()) { + case PolyType(_, Type restpe): + return !(restpe instanceof Type.MethodType); + default: + return false; + } + } + Type dropVarArgs(Type tp) { switch (tp) { case TypeRef(Type pre, Symbol sym, Type[] targs): |