diff options
author | Martin Odersky <odersky@gmail.com> | 2004-04-08 13:25:45 +0000 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2004-04-08 13:25:45 +0000 |
commit | 98a03600e089ca46db9fe74cd3a0295a44148fff (patch) | |
tree | c09ab0d0833c0f0c76617045b01ebdf5abbfdac8 | |
parent | 645f87a5a839685fde5ee9fbeb55d242a32445d4 (diff) | |
download | scala-98a03600e089ca46db9fe74cd3a0295a44148fff.tar.gz scala-98a03600e089ca46db9fe74cd3a0295a44148fff.tar.bz2 scala-98a03600e089ca46db9fe74cd3a0295a44148fff.zip |
*** empty log message ***
-rw-r--r-- | config/list/library.lst | 2 | ||||
-rw-r--r-- | sources/scala/List.scala | 21 | ||||
-rw-r--r-- | sources/scala/Ord.scala | 10 | ||||
-rw-r--r-- | sources/scala/Predef.scala | 148 | ||||
-rw-r--r-- | sources/scala/tools/scalac/ast/parser/Parser.scala | 2 | ||||
-rw-r--r-- | sources/scala/tools/scalac/ast/parser/Tokens.scala | 2 | ||||
-rw-r--r-- | sources/scala/tools/scalac/ast/printer/TextTreePrinter.scala | 2 | ||||
-rw-r--r-- | sources/scala/tools/scalac/typechecker/Analyzer.scala | 12 | ||||
-rw-r--r-- | sources/scala/tools/scalac/typechecker/DeSugarize.scala | 6 | ||||
-rw-r--r-- | sources/scala/tools/scalac/typechecker/Infer.scala | 83 | ||||
-rw-r--r-- | sources/scalac/symtab/Modifiers.java | 2 | ||||
-rw-r--r-- | sources/scalac/symtab/Symbol.java | 3 | ||||
-rw-r--r-- | sources/scalac/typechecker/RefCheck.java | 61 |
13 files changed, 243 insertions, 111 deletions
diff --git a/config/list/library.lst b/config/list/library.lst index aecb911127..45c9cf60d4 100644 --- a/config/list/library.lst +++ b/config/list/library.lst @@ -39,6 +39,8 @@ Nil.scala None.scala Option.scala Ord.scala +#Ordered.scala +#PartiallyOrdered.scala PartialFunction.scala Predef.scala Ref.java diff --git a/sources/scala/List.scala b/sources/scala/List.scala index 8483983e80..94341862c8 100644 --- a/sources/scala/List.scala +++ b/sources/scala/List.scala @@ -157,8 +157,27 @@ object List { } sb.toString() } -} + /** Lists with ordered elements are ordered + * not yet since not compilable with bootstrap + def view[a <% Ordered[a]](x: List[a]): Ordered[List[a]] = new Ordered[List[a]] { + def compareTo [b >: List[a] <% Ordered[b]](y: b): int = y match { + case y1: List[a] => compareLists(x, y1); + case _ => -(y compareTo x) + } + private def compareLists(xs: List[a], ys: List[a]): int = { + if (xs.isEmpty && ys.isEmpty) 0 + else if (xs.isEmpty) -1 + else if (ys.isEmpty) 1 + else { + val s = xs.head compareTo ys.head; + if (s != 0) s + else compareLists(xs.tail, ys.tail) + } + } + } + */ +} /** A trait representing an ordered collection of elements of type * <code>a</code>. This class comes with two implementing case diff --git a/sources/scala/Ord.scala b/sources/scala/Ord.scala index ff352ac584..911d58d29f 100644 --- a/sources/scala/Ord.scala +++ b/sources/scala/Ord.scala @@ -26,3 +26,13 @@ trait Ord[+T <: Ord[T]] { def > [S >: T <: Ord[S]](that: S): Boolean = that < this; def >=[S >: T <: Ord[S]](that: S): Boolean = that <= this; } + +/* +trait Ord[+a] { + def compareTo [b >: a <% Ord[b]](that: b): int; + def < [b >: a <% Ord[b]](that: b): boolean = (this compareTo that) < 0; + def > [b >: a <% Ord[b]](that: b): boolean = (this compareTo that) > 0; + def <= [b >: a <% Ord[b]](that: b): boolean = (this compareTo that) <= 0; + def >= [b >: a <% Ord[b]](that: b): boolean = (this compareTo that) >= 0; +} +*/ diff --git a/sources/scala/Predef.scala b/sources/scala/Predef.scala index 6bc8e8c82a..21c9ba1820 100644 --- a/sources/scala/Predef.scala +++ b/sources/scala/Predef.scala @@ -16,56 +16,118 @@ package scala; */ object Predef { - type byte = scala.Byte; - type short = scala.Short; - type char = scala.Char; - type int = scala.Int; - type long = scala.Long; - type float = scala.Float; - type double = scala.Double; - type boolean = scala.Boolean; - type unit = scala.Unit; - - type String = java.lang.String; - type NullPointerException = java.lang.NullPointerException; - type Throwable = java.lang.Throwable; - - /** Create an array with given elements. - * - * @param xs the elements to put in the array - * @return the array containing elements xs. - */ - def Array[A](xs: A*): Array[A] = { - val array: Array[A] = new Array[A](xs.length); - var i = 0; - for (val x <- xs.elements) { array(i) = x; i = i + 1; } - array; - } +// aliases ------------------------------------------------------- - def error(message: String): All = throw new Error(message); + type byte = scala.Byte; + type short = scala.Short; + type char = scala.Char; + type int = scala.Int; + type long = scala.Long; + type float = scala.Float; + type double = scala.Double; + type boolean = scala.Boolean; + type unit = scala.Unit; - def exit: Unit = java.lang.System.exit(0); + type String = java.lang.String; + type NullPointerException = java.lang.NullPointerException; + type Throwable = java.lang.Throwable; - def assert(assertion: Boolean): Unit = { - if (!assertion) - throw new Error("assertion failed"); - } - def assert(assertion: Boolean, message: Any): Unit = { - if (!assertion) - throw new Error("assertion failed: " + message); - } + type Pair[+p, +q] = Tuple2[p, q]; + def Pair[a, b](x: a, y: b) = Tuple2(x, y); - type Pair[+p, +q] = Tuple2[p, q]; - def Pair[a, b](x: a, y: b) = Tuple2(x, y); + type Triple[+a, +b, +c] = Tuple3[a, b, c]; + def Triple[a, b, c](x: a, y: b, z: c) = Tuple3(x, y, z); - type Triple[+a, +b, +c] = Tuple3[a, b, c]; - def Triple[a, b, c](x: a, y: b, z: c) = Tuple3(x, y, z); - - def id[a](x: a): a = x; - def fst[a](x: a, y: Any): a = x; - def scd[a](x: Any, y: a): a = y; + def id[a](x: a): a = x; + def fst[a](x: a, y: Any): a = x; + def scd[a](x: Any, y: a): a = y; type Function[-a,+b] = Function1[a,b]; +// arrays ----------------------------------------------------------- + + /** Create an array with given elements. + * + * @param xs the elements to put in the array + * @return the array containing elements xs. + */ + def Array[A](xs: A*): Array[A] = { + val array: Array[A] = new Array[A](xs.length); + var i = 0; + for (val x <- xs.elements) { array(i) = x; i = i + 1; } + array; + } + +// errors and asserts ------------------------------------------------- + + def error(message: String): All = throw new Error(message); + + def exit: Unit = java.lang.System.exit(0); + + def assert(assertion: Boolean): Unit = { + if (!assertion) + throw new Error("assertion failed"); + } + def assert(assertion: Boolean, message: Any): Unit = { + if (!assertion) + throw new Error("assertion failed: " + message); + } + +// views ------------------------------------------------------------- +/* not yet compilable with bootstrap + + def view(x: int): Ordered[int] = new Ordered[int] { + def compareTo [b >: int <% Ordered[b]](y: b): int = y match { + case y1: int => + if (x < y1) -1 + else if (x > y1) 1 + else 0 + case _ => -(y compareTo x) + } + } + def view(x: long): Ordered[long] = new Ordered[long] { + def compareTo [b >: long <% Ordered[b]](y: b): int = y match { + case y1: long => + if (x < y1) -1 + else if (x > y1) 1 + else 0 + case _ => -(y compareTo x) + } + } + def view(x: float): Ordered[float] = new Ordered[float] { + def compareTo [b >: float <% Ordered[b]](y: b): int = y match { + case y1: float => + if (x < y1) -1 + else if (x > y1) 1 + else 0 + case _ => -(y compareTo x) + } + } + def view(x: double): Ordered[double] = new Ordered[double] { + def compareTo [b >: double <% Ordered[b]](y: b): int = y match { + case y1: double => + if (x < y1) -1 + else if (x > y1) 1 + else 0 + case _ => -(y compareTo x) + } + } + def view(x: boolean): Ordered[boolean] = new Ordered[boolean] { + def compareTo [b >: boolean <% Ordered[b]](y: b): int = y match { + case y1: boolean => + if (x == y1) 0 + else if (x) 1 + else -1 + case _ => -(y compareTo x) + } + } + def view(x: String): Ordered[String] = new Ordered[String] { + def compareTo [b >: String <% Ordered[b]](y: b): int = y match { + case y1: String => x compareTo y1; + case _ => -(y compareTo x) + } + } + +*/ } diff --git a/sources/scala/tools/scalac/ast/parser/Parser.scala b/sources/scala/tools/scalac/ast/parser/Parser.scala index c33e62a76e..05665e4a5e 100644 --- a/sources/scala/tools/scalac/ast/parser/Parser.scala +++ b/sources/scala/tools/scalac/ast/parser/Parser.scala @@ -1516,7 +1516,7 @@ class Parser(unit: Unit) { typeBounds(s.pos, mods, ident()) } - /** TypeBounds ::= [`>:' Type] [`<:' Type | `<+' Type] + /** TypeBounds ::= [`>:' Type] [`<:' Type | `<%' Type] */ def typeBounds(pos: int, _mods: int, name: Name): Tree = { var mods = _mods; diff --git a/sources/scala/tools/scalac/ast/parser/Tokens.scala b/sources/scala/tools/scalac/ast/parser/Tokens.scala index fad884f6be..ca20940c35 100644 --- a/sources/scala/tools/scalac/ast/parser/Tokens.scala +++ b/sources/scala/tools/scalac/ast/parser/Tokens.scala @@ -205,7 +205,7 @@ object Tokens { enterKeyword("<-", LARROW); enterKeyword("<:", SUBTYPE); enterKeyword(">:", SUPERTYPE); - enterKeyword("<+", VIEWBOUND); + enterKeyword("<%", VIEWBOUND); enterKeyword("#", HASH); enterKeyword("@", AT); diff --git a/sources/scala/tools/scalac/ast/printer/TextTreePrinter.scala b/sources/scala/tools/scalac/ast/printer/TextTreePrinter.scala index 14da5e6613..a17f54774c 100644 --- a/sources/scala/tools/scalac/ast/printer/TextTreePrinter.scala +++ b/sources/scala/tools/scalac/ast/printer/TextTreePrinter.scala @@ -166,7 +166,7 @@ class TextTreePrinter(writer: PrintWriter) with TreePrinter { protected final val TXT_EQUAL = Simple("="); protected final val TXT_SUPERTYPE = Simple(">:"); protected final val TXT_SUBTYPE = Simple("<:"); - protected final val TXT_VIEWBOUND = Simple("<+"); + protected final val TXT_VIEWBOUND = Simple("<%"); protected final val TXT_HASH = Simple("#"); protected final val TXT_RIGHT_ARROW = Simple("=>"); protected final val TXT_LEFT_PAREN = Simple("("); diff --git a/sources/scala/tools/scalac/typechecker/Analyzer.scala b/sources/scala/tools/scalac/typechecker/Analyzer.scala index 18cae3fe6d..37b3ae2379 100644 --- a/sources/scala/tools/scalac/typechecker/Analyzer.scala +++ b/sources/scala/tools/scalac/typechecker/Analyzer.scala @@ -1052,8 +1052,14 @@ class Analyzer(global: scalac_Global, descr: AnalyzerPhase) extends Transformer( tree, sym.primaryConstructor(), new Scope(context.scope)); val tparamSyms = enterParams(tparams); var vparamSyms = enterParams(vparams); - if (vparamSyms.length == 0) + if (vparamSyms.length == 0) { vparamSyms = NewArray.SymbolArray{Symbol.EMPTY_ARRAY}; + } else if (infer.isViewBounded(tparamSyms) && vparamSyms.length == 1) { + val vparamSyms1 = new Array[Array[Symbol]](2); + vparamSyms1(0) = vparamSyms(0); + vparamSyms1(1) = Symbol.EMPTY_ARRAY; + vparamSyms = vparamSyms1 + } if ((mods & CASE) != 0 && vparams.length > 0) templ.body = desugarize.addCaseElements( templ.body, vparams(vparams.length - 1)); @@ -2660,7 +2666,9 @@ class Analyzer(global: scalac_Global, descr: AnalyzerPhase) extends Transformer( fn1 = infer.methodInstance(fn1, tparams, restp, argtypes, pt); //System.out.println(fn1 + ":" + fn1.getType());//DEBUG } catch { - case ex: Type$Error => reportTypeError(tree.pos, ex); + case ex: Type$Error => + //ex.printStackTrace();//DEBUG + reportTypeError(tree.pos, ex); } fn1.getType() match { case Type$MethodType(params, restp1) => diff --git a/sources/scala/tools/scalac/typechecker/DeSugarize.scala b/sources/scala/tools/scalac/typechecker/DeSugarize.scala index 59ec8946d6..ae21fac622 100644 --- a/sources/scala/tools/scalac/typechecker/DeSugarize.scala +++ b/sources/scala/tools/scalac/typechecker/DeSugarize.scala @@ -301,11 +301,15 @@ class DeSugarize(make: TreeFactory, copy: TreeCopier, gen: TreeGen, infer: scala addViewParams(tparams, vparams), tpe, templ); case Tree$DefDef(mods, name, tparams, vparams, tpe, rhs) => + //System.out.println("DEF " + make.DefDef(tree.pos, mods, name, tparams, addViewParams(tparams, vparams), tpe, rhs));//DEBUG make.DefDef(tree.pos, mods, name, tparams, addViewParams(tparams, vparams), tpe, rhs) + case Tree$DocDef(comment, definition) => + make.DocDef(tree.pos, comment, Definition(definition)) + case _ => - return tree + tree } def addViewParams(tparams: Array[Tree$AbsTypeDef], vparams: Array[Array[Tree$ValDef]]): Array[Array[Tree$ValDef]] = { diff --git a/sources/scala/tools/scalac/typechecker/Infer.scala b/sources/scala/tools/scalac/typechecker/Infer.scala index 8dada48e1b..59f2a042ac 100644 --- a/sources/scala/tools/scalac/typechecker/Infer.scala +++ b/sources/scala/tools/scalac/typechecker/Infer.scala @@ -334,7 +334,7 @@ class Infer(global: scalac_Global, gen: TreeGen, make: TreeFactory) extends scal } } - private def viewObj(meth: Tree, msym: Symbol) = msym.getType() match { + private def viewObj(meth: Tree) = meth.getType() match { case Type$MethodType(params: Array[Symbol], _) => assert(params.length == 1); val paramsym = params(0).cloneSymbol(getContext.owner); @@ -360,10 +360,12 @@ class Infer(global: scalac_Global, gen: TreeGen, make: TreeFactory) extends scal case Type$PolyType(vtparams, vrestype) => assert(vtparams.length != 0); vmeth = exprInstance(vmeth, vtparams, vrestype, vtype); - assert(vmeth.getType().isSubType(vtype)); case _ => } - viewObj(vmeth, v.sym) + val vobj = viewObj(vmeth); + if (!vobj.getType().isSubType(vtype)) + assert(false, "view argument " + vobj + ":" + vobj.getType() + " is not a subtype of view param type " + vtype); + vobj } else { error(pos, "type instantiation with [" + @@ -407,18 +409,19 @@ class Infer(global: scalac_Global, gen: TreeGen, make: TreeFactory) extends scal } def completeTypeApply(tree: Tree): Tree = { + //System.out.println("complete type apply: " + tree + ":" + tree.getType());//DEBUG tree match { - case Tree$TypeApply(fn, targs) => - fn.getType() match { - case Type$PolyType(tparams, restp) if tparams.length == targs.length => - if (isViewBounded(tparams)) { - val result = passViewArgs(tree, tparams, restp, Tree.typeOf(targs)); - //System.out.println("completed type apply: " + result + ":" + result.getType());//DEBUG - result - } else tree - case _ => tree - } - case _ => tree + case Tree$TypeApply(fn, targs) => + fn.getType() match { + case Type$PolyType(tparams, restp) if tparams.length == targs.length => + if (isViewBounded(tparams)) { + val result = passViewArgs(tree, tparams, restp, Tree.typeOf(targs)); + //System.out.println("completed type apply: " + result + ":" + result.getType());//DEBUG + result + } else tree + case _ => tree + } + case _ => tree } } @@ -905,6 +908,19 @@ class Infer(global: scalac_Global, gen: TreeGen, make: TreeFactory) extends scal tvars } + private def methTypeArgsSkipViews( + tparams: Array[Symbol], params: Array[Symbol], + argtypes: Array[Type], restpe: Type, + pt: Type, + needToSucceed: boolean, regularValue: boolean): Array[Type] = restpe match { + case Type$MethodType(params1, restpe1) if isViewBounded(tparams) => + methTypeArgs( + tparams, params1, argtypes, restpe1, pt, needToSucceed, regularValue); + case _ => + methTypeArgs( + tparams, params, argtypes, restpe, pt, needToSucceed, regularValue); + } + /** Create and attribute type application node. Pass arguments for that * `tparams' prefix which is owned by the tree's symbol. If there are remaining * type parameters, substitute corresponding type arguments for them in the @@ -957,9 +973,10 @@ class Infer(global: scalac_Global, gen: TreeGen, make: TreeFactory) extends scal case _ => if (tparams.length != 0) { - var targs: Array[Type] = exprTypeArgs(tparams, restype, pt1); + val skippedRestype = skipViewParams(tparams, restype); + var targs: Array[Type] = exprTypeArgs(tparams, skippedRestype, pt1); if (targs == null) - targs = exprTypeArgs(tparams, restype, pt2); + targs = exprTypeArgs(tparams, skippedRestype, pt2); if (targs == null) throw new Type$Error( typeErrorMsg( @@ -984,7 +1001,8 @@ class Infer(global: scalac_Global, gen: TreeGen, make: TreeFactory) extends scal System.arraycopy(tparams1, 0, tparams2, tparams.length, tparams1.length); exprInstance(tree, tparams2, restype1, pt) case _ => - val targs: Array[Type] = exprTypeArgs(tparams, restype, pt); + val targs: Array[Type] = + exprTypeArgs(tparams, skipViewParams(tparams, restype), pt); if (targs == null) throw new Type$Error( "polymorphic expression of type " + tree.getType() + @@ -1010,14 +1028,8 @@ class Infer(global: scalac_Global, gen: TreeGen, make: TreeFactory) extends scal case Type$MethodType(params, restpe) => var targs: Array[Type] = _; try { - restpe match { - case Type$MethodType(params1, restpe1) if isViewBounded(tparams) => - targs = methTypeArgs( - tparams, params1, argtypes, restpe1, pt, true, false); - case _ => - targs = methTypeArgs( - tparams, params, argtypes, restpe, pt, true, false); - } + targs = methTypeArgsSkipViews( + tparams, params, argtypes, restpe, pt, true, false); } catch { case ex: NoInstance => throw new Type$Error( @@ -1054,17 +1066,18 @@ class Infer(global: scalac_Global, gen: TreeGen, make: TreeFactory) extends scal case _ => val tvars: Array[Type] = freshVars(tparams); - val restype1: Type = restype.subst(tparams, tvars); + val restype0: Type = skipViewParams(tparams, restype); + val restype1: Type = restype0.subst(tparams, tvars); val ctpe1: Type = restype1.resultType(); if (ctpe1.isSubType(pt)) { try { { var i = 0; while (i < tvars.length) { - solve(tparams, true, variance(tparams, restype.resultType()), + solve(tparams, true, variance(tparams, restype0.resultType()), tvars, i); i = i + 1 }} checkBounds(tparams, tvars, "inferred "); - tree.setType(restype.subst(tparams, tvars)); + tree.setType(restype0.subst(tparams, tvars)); //System.out.println("inferred constructor type: " + tree.getType());//DEBUG } catch { case ex: NoInstance => @@ -1092,7 +1105,9 @@ class Infer(global: scalac_Global, gen: TreeGen, make: TreeFactory) extends scal isApplicable(ftpe, argtypes, pt, Names.EMPTY, true); def isApplicable(ftpe: Type, argtypes: Array[Type], pt: Type, - fieldName: Name, regularValue: boolean): boolean = ftpe match { + fieldName: Name, regularValue: boolean): boolean = { + //if (!regularValue) System.out.println("is app " + ftpe + " to " + ArrayApply.toString(argtypes.asInstanceOf[Array[Object]]));//DEBUG + ftpe match { case Type$MethodType(params, restpe) => // sequences ? List( a* ) val formals: Array[Type] = formalTypes(params, argtypes.length); @@ -1102,16 +1117,17 @@ class Infer(global: scalac_Global, gen: TreeGen, make: TreeFactory) extends scal (fieldName == Names.EMPTY || restpe.lookup(fieldName).kind != NONE) case Type$PolyType(tparams, Type$MethodType(params, restpe)) => try { - val targs: Array[Type] = methTypeArgs( + val targs: Array[Type] = methTypeArgsSkipViews( tparams, params, argtypes, restpe, pt, false, regularValue); if (targs != null) { val uninstantiated: Array[Symbol] = normalizeArgs(targs, tparams, restpe); + val restpe1 = skipViewParams(tparams, restpe); isWithinBounds(tparams, targs) && exprTypeArgs(uninstantiated, - restpe.subst(tparams, targs), pt, + restpe1.subst(tparams, targs), pt, regularValue) != null && (fieldName == Names.EMPTY || - restpe.subst(tparams, targs).lookup(fieldName).kind != NONE) + restpe1.subst(tparams, targs).lookup(fieldName).kind != NONE) } else { false } @@ -1124,7 +1140,7 @@ class Infer(global: scalac_Global, gen: TreeGen, make: TreeFactory) extends scal ftpe1 != ftpe && isApplicable(ftpe1, argtypes, pt, fieldName, false); } else false - } + }} def applyType(tp: Type) = if (tp.isObjectType()) { @@ -1274,6 +1290,7 @@ class Infer(global: scalac_Global, gen: TreeGen, make: TreeFactory) extends scal def bestView(tp: Type, pt: Type, name: Name): View = { var best: View = null; var viewMeths = getViews(tp); + //System.out.println("best view for " + tp + "/" + pt + " in " + viewMeths);//DEBUG val argtypes = NewArray.Type(tp); while (!viewMeths.isEmpty) { if (isApplicable(viewMeths.head.symtype, argtypes, pt, name, false) && diff --git a/sources/scalac/symtab/Modifiers.java b/sources/scalac/symtab/Modifiers.java index afe215ea3d..dd6a6167ed 100644 --- a/sources/scalac/symtab/Modifiers.java +++ b/sources/scalac/symtab/Modifiers.java @@ -31,7 +31,7 @@ public interface Modifiers { int JAVA = 0x00001000; // symbol was defined by a Java class int MODUL = 0x00002000; // symbol is module or class implementing a module int MUTABLE = 0x00004000; // symbol is a mutable variable. - int VIEWBOUND = 0x00004000; // type symbol has a <+ bound. + int VIEWBOUND = 0x00004000; // type symbol has a <% bound. int PARAM = 0x00008000; // symbol is a (type) parameter to a method int INITIALIZED = 0x00010000; // symbol's definition is complete diff --git a/sources/scalac/symtab/Symbol.java b/sources/scalac/symtab/Symbol.java index ccd9f2632a..bbfd7c0301 100644 --- a/sources/scalac/symtab/Symbol.java +++ b/sources/scalac/symtab/Symbol.java @@ -1791,7 +1791,8 @@ final class AbsTypeSymbol extends TypeSymbol { public Type vuBound() { initialize(); - return vubound == null ? Global.instance.definitions.ANY_TYPE() : vubound; + return !isViewBounded() || vubound == null + ? Global.instance.definitions.ANY_TYPE() : vubound; } public Symbol setLoBound(Type lobound) { diff --git a/sources/scalac/typechecker/RefCheck.java b/sources/scalac/typechecker/RefCheck.java index 2bb96cbe69..f7649a9792 100644 --- a/sources/scalac/typechecker/RefCheck.java +++ b/sources/scalac/typechecker/RefCheck.java @@ -820,45 +820,54 @@ public class RefCheck extends Transformer implements Modifiers, Kinds { * the case classe's primary constructor `constr'. */ private Tree toConstructor(Tree tree, Symbol constr) { - switch (tree) { - case Apply(Tree fn, Tree[] args): - return copy.Apply(tree, toConstructor1(fn, constr), args); - default: - return gen.Apply( - tree.pos, toConstructor1(tree, constr), Tree.EMPTY_ARRAY); - } + int missing = constr.getType().paramSectionCount() - applyNesting(tree); + assert missing >= 0 && missing <= 1; + Tree tree1 = toConstructor1(tree, constr, missing > 0); + if (missing > 0) return gen.Apply(tree1, Tree.EMPTY_ARRAY); + else return tree1; } //where - private Tree toConstructor1(Tree tree, Symbol constr) { + private int applyNesting(Tree tree) { + switch (tree) { + case Apply(Tree fn, Tree[] args): + return applyNesting(fn) + 1; + default: + return 0; + } + } + + private Tree toConstructor1(Tree tree, Symbol constr, boolean addEmpty) { + Tree tree1 = toConstructor2(tree, constr, addEmpty); + if (addEmpty) + return tree1.duplicate() + .setType(addEmptyParams(tree1.getType())); + else + return tree1; + } + + private Tree toConstructor2(Tree tree, Symbol constr, boolean addEmpty) { switch (tree) { + case Apply(Tree fn, Tree[] args): + return copy.Apply( + tree, toConstructor1(fn, constr, addEmpty), args); case TypeApply(Tree fn, Tree[] args): - return toMethodType( - copy.TypeApply(tree, toConstructor1(fn, constr), args)); + return copy.TypeApply( + tree, toConstructor1(fn, constr, addEmpty), args); case Ident(_): - return toMethodType( - copy.Ident(tree, constr)); + return copy.Ident(tree, constr); case Select(Tree qual, _): - return toMethodType( - copy.Select(tree, constr, qual)); + return copy.Select(tree, constr, qual); default: throw new ApplicationError(); } } - private Tree toMethodType(Tree tree) { - Type tp = toMethodType(tree.type); - if (tp == tree.type) return tree; - else return tree.duplicate().setType(tp); - } - - private Type toMethodType(Type tp) { + private Type addEmptyParams(Type tp) { switch (tp) { - case MethodType(_, _): - return tp; + case MethodType(Symbol[] vparams, Type restp): + return Type.MethodType(vparams, addEmptyParams(restp)); case PolyType(Symbol[] tparams, Type restp): - Type restp1 = toMethodType(restp); - if (restp == restp) return tp; - else return Type.PolyType(tparams, restp1); + return Type.PolyType(tparams, addEmptyParams(restp)); default: return Type.MethodType(Symbol.EMPTY_ARRAY, tp); } |