diff options
Diffstat (limited to 'sources')
-rw-r--r-- | sources/scala/List.scala | 45 | ||||
-rw-r--r-- | sources/scala/tools/scalac/ast/parser/Parser.scala | 35 | ||||
-rw-r--r-- | sources/scala/tools/scalac/typechecker/Analyzer.scala | 11 | ||||
-rw-r--r-- | sources/scala/tools/scalac/typechecker/DeSugarize.scala | 2 | ||||
-rw-r--r-- | sources/scalac/symtab/ClosureHistory.java | 4 | ||||
-rw-r--r-- | sources/scalac/symtab/Type.java | 28 |
6 files changed, 119 insertions, 6 deletions
diff --git a/sources/scala/List.scala b/sources/scala/List.scala index 00b3bcf446..ec05522eda 100644 --- a/sources/scala/List.scala +++ b/sources/scala/List.scala @@ -180,6 +180,49 @@ object List { sb.toString() } + /** Returns the list resulting from applying the given function <code>f</code> to + * corresponding elements of the argument lists. + * + * @param f function to apply to each pair of elements. + * @return <code>[f(a0,b0), ..., f(an,bn)]</code> if the lists are + * <code>[a0, ..., ak]</code>, <code>[b0, ..., bl]</code> and + * <code>m = min(k,l)</code> + */ + def map2[a,b,c](xs: List[a], ys: List[b], f: (a, b) => c): List[c] = + if (xs.isEmpty || ys.isEmpty) Nil + else f(xs.head, ys.head) :: map2(xs.tail, ys.tail, f); + + /** Tests whether the given predicate <code>p</code> holds + * for all corresponding elements of the argument lists. + * + * @param p function to apply to each pair of elements. + * @return <code>n == 0 || (p(a0,b0) && ... && p(an,bn))]</code> if the lists are + * <code>[a0, ..., ak]</code>, <code>[b0, ..., bl]</code> and + * <code>m = min(k,l)</code> + */ + def forall2[a,b](xs: List[a], ys: List[b], f: (a, b) => boolean): boolean = + if (xs.isEmpty || ys.isEmpty) true + else f(xs.head, ys.head) && forall2(xs.tail, ys.tail, f); + + /** Tests whether the given predicate <code>p</code> holds + * for some corresponding elements of the argument lists. + * + * @param p function to apply to each pair of elements. + * @return <code>n != 0 && (p(a0,b0) || ... || p(an,bn))]</code> if the lists are + * <code>[a0, ..., ak]</code>, <code>[b0, ..., bl]</code> and + * <code>m = min(k,l)</code> + */ + def exists2[a,b](xs: List[a], ys: List[b], f: (a, b) => boolean): boolean = + if (xs.isEmpty || ys.isEmpty) false + else f(xs.head, ys.head) || exists2(xs.tail, ys.tail, f); + + /** Transposes a list of lists. + * pre: All element lists have the same length. + */ + def transpose[a](xss: List[List[a]]): List[List[a]] = + if (xss.head.isEmpty) List() + else (xss map (xs => xs.head)) :: transpose(xss map (xs => xs.tail)); + /** Lists with ordered elements are ordered */ def view[a <% Ordered[a]](x: List[a]): Ordered[List[a]] = new Ordered[List[a]] { @@ -445,7 +488,7 @@ sealed trait List[+a] extends Seq[a] { def map[b](f: a => b): List[b] = match { case Nil => Nil case head :: tail => f(head) :: (tail map f) - }; + } /** Apply a function to all the elements of the list, and return the * reversed list of results. This is equivalent to a call to <code>map</code> diff --git a/sources/scala/tools/scalac/ast/parser/Parser.scala b/sources/scala/tools/scalac/ast/parser/Parser.scala index 3aa0ac6cb2..2ce0ec1c3a 100644 --- a/sources/scala/tools/scalac/ast/parser/Parser.scala +++ b/sources/scala/tools/scalac/ast/parser/Parser.scala @@ -239,6 +239,7 @@ class Parser(unit: CompilationUnit) { NewArray.Tree(left, right)); } + def scalaDot(pos: int, name: Name): Tree = make.Select(pos, make.Ident(pos, Names.scala), name); @@ -433,6 +434,29 @@ class Parser(unit: CompilationUnit) { make.Apply(t.pos, t, Tree.EMPTY_ARRAY) } + /** make closure from tree */ + def makeClosure(pos: int, tree: Tree): Tree = { + val pname = fresh(); + def insertParam(tree: Tree): Tree = tree match { + case Tree$Ident(name) => + make.Select(tree.pos, make.Ident(pos, pname), name) + case Tree$Select(qual, name) => + make.Select(tree.pos, insertParam(qual), name) + case Tree$Apply(fn, args) => + make.Apply(tree.pos, insertParam(fn), args) + case Tree$TypeApply(fn, args) => + make.TypeApply(tree.pos, insertParam(fn), args) + case _ => + syntaxError(pos, "cannot concert to closure", false); + gen.mkZeroLit(s.pos) + } + make.Function( + pos, + NewArray.ValDef( + make.ValDef(pos, Modifiers.PARAM, pname, Tree.Empty, Tree.Empty)), + insertParam(tree)) + } + /////// OPERAND/OPERATOR STACK ///////////////////////////////////////////////// var operands = new Array[Tree](8); @@ -818,6 +842,7 @@ class Parser(unit: CompilationUnit) { * | return [Expr] * | [SimpleExpr `.'] Id `=' Expr * | SimpleExpr ArgumentExprs `=' Expr + * | `.' SimpleExpr * | PostfixExpr [`:' Type1] * Bindings ::= Id [`:' Type1] * | `(' [Binding {`,' Binding}] `)' @@ -890,6 +915,14 @@ class Parser(unit: CompilationUnit) { } else if (s.token == THROW) { val pos = s.skipToken(); make.Throw(pos, expr()) + } else if (s.token == DOT) { + val pos = s.skipToken(); + if (s.token == IDENTIFIER) + makeClosure(pos, simpleExpr()) + else { + syntaxError("identifier expected", true); + gen.mkZeroLit(pos); + } } else { var t = postfixExpr(); if (s.token == EQUALS) { @@ -927,7 +960,7 @@ class Parser(unit: CompilationUnit) { } } - /** PostfixExpr ::= InfixExpr [Id] + /** PostfixExpr ::= [`.'] InfixExpr [Id] * InfixExpr ::= PrefixExpr * | InfixExpr Id InfixExpr */ diff --git a/sources/scala/tools/scalac/typechecker/Analyzer.scala b/sources/scala/tools/scalac/typechecker/Analyzer.scala index 46692e3508..1478b89045 100644 --- a/sources/scala/tools/scalac/typechecker/Analyzer.scala +++ b/sources/scala/tools/scalac/typechecker/Analyzer.scala @@ -1330,6 +1330,8 @@ class Analyzer(global: scalac_Global, descr: AnalyzerPhase) extends Transformer( clazz.getType() else if (selftype.isSubType(clazz.getType())) selftype + else if (selftype.isSingletonType() && selftype.singleDeref().symbol().isSubClass(clazz)) + selftype else selftype match { case Type$CompoundType(parts, members) => @@ -1342,6 +1344,7 @@ class Analyzer(global: scalac_Global, descr: AnalyzerPhase) extends Transformer( Type.compoundTypeWithOwner( clazz.owner().enclClass(), NewArray.Type(selftype, clazz.getType()), Scope.EMPTY); } + if (global.debug) global.log("assigning self type " + selftype1); sym.setInfo(selftype1); this.unit = savedUnit; @@ -1367,7 +1370,9 @@ class Analyzer(global: scalac_Global, descr: AnalyzerPhase) extends Transformer( } case _ => } - if ((pt != null && pt.isStable() || (mode & QUALmode) != 0) && + if ((pt != null && pt.isStable() || + (mode & QUALmode) != 0 || + tree.getType().symbol().isModuleClass()) && (pre != null) && pre.isStable()) { var sym: Symbol = tree.symbol(); tree.getType() match { @@ -1566,7 +1571,7 @@ class Analyzer(global: scalac_Global, descr: AnalyzerPhase) extends Transformer( } var owntype: Type = tree.getType(); - if ((mode & (CONSTRmode | FUNmode)) == (CONSTRmode)) { + if ((mode & (CONSTRmode | FUNmode)) == (CONSTRmode) && pt != Type.AnyType) { owntype = owntype.instanceType(); // this works as for superclass constructor calls the expected // type `pt' is always AnyType (see transformConstrInvocations). @@ -1917,7 +1922,7 @@ class Analyzer(global: scalac_Global, descr: AnalyzerPhase) extends Transformer( transformConstrInvocationArgs(parents); if (!owner.isError()) { validateParentClasses( - parents, owner.info().parents(), owner.typeOfThis()); + parents, owner.info().parents(), owner.thisType()); } val prevContext = pushContext(templ, owner, owner.members()); /* diff --git a/sources/scala/tools/scalac/typechecker/DeSugarize.scala b/sources/scala/tools/scalac/typechecker/DeSugarize.scala index 7e178e3000..99ec52fb2b 100644 --- a/sources/scala/tools/scalac/typechecker/DeSugarize.scala +++ b/sources/scala/tools/scalac/typechecker/DeSugarize.scala @@ -591,7 +591,7 @@ class DeSugarize(make: TreeFactory, copy: TreeCopier, gen: TreeGen, infer: scala * It is assumed that all symbols are term symbols ==> make.Ident(). */ def toIdents(symbols: Array[Symbol]): Array[Tree] = { - val idents = new Array[Tree$Ident](symbols.length); + val idents = new Array[Tree](symbols.length); for (val i <- Iterator.range(0, symbols.length)) { idents(i) = make.Ident(symbols(i).pos, symbols(i).name); } diff --git a/sources/scalac/symtab/ClosureHistory.java b/sources/scalac/symtab/ClosureHistory.java index 514e093f29..0f5073cd89 100644 --- a/sources/scalac/symtab/ClosureHistory.java +++ b/sources/scalac/symtab/ClosureHistory.java @@ -66,6 +66,10 @@ public class ClosureHistory extends History { for (int i = 0; i < parents.length; i++) addParents(table, parents[i]); return; + case SingleType(_, _): + case ThisType(_): + addParents(table, type.singleDeref()); + return; default: throw Debug.abort("illegal case", type); } diff --git a/sources/scalac/symtab/Type.java b/sources/scalac/symtab/Type.java index f0ebe88b1e..8b7510a597 100644 --- a/sources/scalac/symtab/Type.java +++ b/sources/scalac/symtab/Type.java @@ -698,6 +698,15 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { } } + /** Is this type a s thistype or singletype? + */ + public boolean isSingletonType() { + switch (this) { + case ThisType(_): case SingleType(_, _): return true; + default: return false; + } + } + /** Is this type a reference to an object type? * todo: replace by this.isSubType(global.definitions.ANY_TYPE())? */ @@ -2155,6 +2164,12 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { && sym == sym1.moduleClass() && sym.owner().thisType().isSameAs(pre1) || + this.singleDeref().isSingletonType() && + this.singleDeref().isSameAs(that) + || + that.singleDeref().isSingletonType() && + this.isSameAs(that.singleDeref()) + || deAlias(that) != that && this.isSameAs(deAlias(that)); } @@ -2165,6 +2180,12 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { case SingleType(Type pre1, Symbol sym1): return sym == sym1 && pre.isSameAs(pre1) || + this.singleDeref().isSingletonType() && + this.singleDeref().isSameAs(that) + || + that.singleDeref().isSingletonType() && + this.isSameAs(that.singleDeref()) + || (deAlias(this) != this || deAlias(that) != that) && deAlias(this).isSameAs(deAlias(that)); case ThisType(Symbol sym1): @@ -2172,6 +2193,12 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { && sym.moduleClass() == sym1 && pre.isSameAs(sym1.owner().thisType()) || + this.singleDeref().isSingletonType() && + this.singleDeref().isSameAs(that) + || + that.singleDeref().isSingletonType() && + this.isSameAs(that.singleDeref()) + || deAlias(this) != this && deAlias(this).isSameAs(that); default: @@ -2280,6 +2307,7 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { return false; } //where + Type deAlias(Type tp) { switch (tp) { case SingleType(_, _): |