summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sources/scala/List.scala11
-rw-r--r--sources/scala/concurrent/jolib.scala4
-rwxr-xr-xsources/scala/reflect/Code.scala3
-rwxr-xr-xsources/scala/tools/nsc/symtab/Definitions.scala2
-rwxr-xr-xsources/scala/tools/nsc/symtab/Types.scala9
-rwxr-xr-xsources/scala/tools/nsc/transform/UnCurry.scala86
-rw-r--r--sources/scala/tools/nsc/typechecker/Analyzer.scala3
-rwxr-xr-xsources/scala/tools/nsc/typechecker/RefChecks.scala57
-rwxr-xr-xsources/scala/tools/nsc/typechecker/Typers.scala99
9 files changed, 117 insertions, 157 deletions
diff --git a/sources/scala/List.scala b/sources/scala/List.scala
index 66442b42b2..7bd2c5f45e 100644
--- a/sources/scala/List.scala
+++ b/sources/scala/List.scala
@@ -357,9 +357,14 @@ sealed trait List[+a] extends Seq[a] { // todo make sealed once we figure out ho
*
* @return the number of elements in the list.
*/
- def length: Int = this match {
- case Nil => 0
- case _ :: xs => xs.length + 1
+ def length: Int = {
+ var xs = this;
+ var len = 0;
+ while (!xs.isEmpty) {
+ len = len + 1;
+ xs = xs.tail
+ }
+ len
}
/** Creates a list with all indices in the list. This is
diff --git a/sources/scala/concurrent/jolib.scala b/sources/scala/concurrent/jolib.scala
index e7d19b5bd5..08611be513 100644
--- a/sources/scala/concurrent/jolib.scala
+++ b/sources/scala/concurrent/jolib.scala
@@ -28,8 +28,8 @@ object jolib {
def canMatch(p: Pattern) =
p forall { s => !s.queue.isEmpty };
- def values(p: Pattern) =
- p map { s => s.queue.dequeue };
+ def values(p: Pattern): List[Any] =
+ p map { s => s.queue.dequeue: Any };
def rules(rs: Pair[Pattern, Rule]*) =
ruls = rs.asInstanceOf[List[Pair[Pattern, Rule]]];
diff --git a/sources/scala/reflect/Code.scala b/sources/scala/reflect/Code.scala
index 6122dec396..203ff946c5 100755
--- a/sources/scala/reflect/Code.scala
+++ b/sources/scala/reflect/Code.scala
@@ -11,8 +11,9 @@ package scala.reflect;
abstract class Code;
case class Ident(sym: Symbol) extends Code;
+case class Select(qual: Code, sym: Symbol) extends Code;
+case class Literal(value: Any) extends Code;
case class Apply(fun: Code, args: List[Code]) extends Code;
case class TypeApply(fun: Code, args: List[Type]) extends Code;
-case class Select(qual: Code, sym: Symbol) extends Code;
case class Function(params: List[Symbol], body: Code) extends Code;
diff --git a/sources/scala/tools/nsc/symtab/Definitions.scala b/sources/scala/tools/nsc/symtab/Definitions.scala
index beeed30397..5397c7d5fc 100755
--- a/sources/scala/tools/nsc/symtab/Definitions.scala
+++ b/sources/scala/tools/nsc/symtab/Definitions.scala
@@ -55,6 +55,7 @@ import Flags._;
def ScalaObjectClass_tag = getMember(ScalaObjectClass, nme.tag );
var AttributeClass: Symbol = _;
var RefClass: Symbol = _;
+ var TypedCodeClass: Symbol = _;
var PartialFunctionClass: Symbol = _;
var IterableClass: Symbol = _;
def Iterable_next = getMember(IterableClass, "next");
@@ -317,6 +318,7 @@ import Flags._;
ScalaObjectClass = getClass("scala.ScalaObject");
AttributeClass = getClass("scala.Attribute");
RefClass = getClass("scala.Ref");
+ TypedCodeClass = getClass("scala.reflect.TypedCode");
PartialFunctionClass = getClass("scala.PartialFunction");
IterableClass = getClass("scala.Iterable");
IteratorClass = getClass("scala.Iterator");
diff --git a/sources/scala/tools/nsc/symtab/Types.scala b/sources/scala/tools/nsc/symtab/Types.scala
index 5bf8dd7c0f..3b1c8322c7 100755
--- a/sources/scala/tools/nsc/symtab/Types.scala
+++ b/sources/scala/tools/nsc/symtab/Types.scala
@@ -761,7 +761,14 @@ import Flags._;
override def typeParams: List[Symbol] =
if (args.isEmpty) symbol.unsafeTypeParams else List();
- override def decls: Scope = sym.info.decls;
+ override def decls: Scope = {
+ sym.info match {
+ case TypeRef(_, sym1, _) =>
+ assert(sym1 != symbol, this);
+ case _ =>
+ }
+ sym.info.decls
+ }
override def baseType(clazz: Symbol): Type =
if (sym == clazz) this
diff --git a/sources/scala/tools/nsc/transform/UnCurry.scala b/sources/scala/tools/nsc/transform/UnCurry.scala
index 47e3fe43c4..e62bb20739 100755
--- a/sources/scala/tools/nsc/transform/UnCurry.scala
+++ b/sources/scala/tools/nsc/transform/UnCurry.scala
@@ -5,6 +5,8 @@
// $Id$
package scala.tools.nsc.transform;
+import symtab.Flags._;
+
/*<export>*/
/** - uncurry all symbol and tree types (@see UnCurryPhase)
* - for every curried parameter list: (ps_1) ... (ps_n) ==> (ps_1, ..., ps_n)
@@ -90,6 +92,75 @@ abstract class UnCurry extends InfoTransform {
uncurry(tp)
}
+ /* Transform a function node (x_1,...,x_n) => body of type FunctionN[T_1, .., T_N, R] to
+ *
+ * class $anon() extends Object() with FunctionN[T_1, .., T_N, R] with ScalaObject {
+ * def apply(x_1: T_1, ..., x_N: T_n): R = body
+ * }
+ * new $anon()
+ *
+ * transform a function node (x => body) of type PartialFunction[T, R] where
+ * body = x match { case P_i if G_i => E_i }_i=1..n
+ * to:
+ *
+ * class $anon() extends Object() with PartialFunction[T, R] with ScalaObject {
+ * def apply(x: T): R = body;
+ * def isDefinedAt(x: T): boolean = x match {
+ * case P_1 if G_1 => true
+ * ...
+ * case P_n if G_n => true
+ * case _ => false
+ * }
+ * }
+ * new $anon()
+ *
+ * However, if one of the patterns P_i if G_i is a default pattern, generate instead
+ *
+ * def isDefinedAt(x: T): boolean = true
+ */
+ def transformFunction(fun: Function): Tree = {
+ val anonClass = fun.symbol.owner.newAnonymousFunctionClass(fun.pos) setFlag (FINAL | SYNTHETIC);
+ val formals = fun.tpe.typeArgs.init;
+ val restpe = fun.tpe.typeArgs.last;
+ anonClass setInfo ClassInfoType(
+ List(ObjectClass.tpe, fun.tpe, ScalaObjectClass.tpe), new Scope(), anonClass);
+ val applyMethod = anonClass.newMethod(fun.pos, nme.apply)
+ setFlag FINAL setInfo MethodType(formals, restpe);
+ anonClass.info.decls enter applyMethod;
+ for (val vparam <- fun.vparams) vparam.symbol.owner = applyMethod;
+ new ChangeOwnerTraverser(fun.symbol, applyMethod).traverse(fun.body);
+ var members = List(
+ DefDef(FINAL, nme.apply, List(), List(fun.vparams), TypeTree(restpe), fun.body)
+ setSymbol applyMethod);
+ if (fun.tpe.symbol == PartialFunctionClass) {
+ val isDefinedAtMethod = anonClass.newMethod(fun.pos, nme.isDefinedAt)
+ setFlag FINAL setInfo MethodType(formals, BooleanClass.tpe);
+ anonClass.info.decls enter isDefinedAtMethod;
+ def idbody(idparam: Symbol) = fun.body match {
+ case Match(_, cases) =>
+ val substParam = new TreeSymSubstituter(List(fun.vparams.head.symbol), List(idparam));
+ def transformCase(cdef: CaseDef): CaseDef =
+ resetAttrs(CaseDef(cdef.pat.duplicate, cdef.guard.duplicate, Literal(true)));
+ if (cases exists treeInfo.isDefaultCase) Literal(true)
+ else
+ Match(
+ Ident(idparam),
+ (cases map transformCase) :::
+ List(CaseDef(Ident(nme.WILDCARD), EmptyTree, Literal(false))))
+ }
+ members = DefDef(isDefinedAtMethod, vparamss => idbody(vparamss.head.head)) :: members;
+ }
+ typer.atOwner(currentOwner).typed {
+ atPos(fun.pos) {
+ Block(
+ List(ClassDef(anonClass, List(List()), List(List()), members)),
+ Typed(
+ New(TypeTree(anonClass.tpe), List(List())),
+ TypeTree(fun.tpe)))
+ }
+ }
+ }
+
def transformArgs(pos: int, args: List[Tree], formals: List[Type]) = {
if (formals.isEmpty) {
assert(args.isEmpty); List()
@@ -118,7 +189,7 @@ abstract class UnCurry extends InfoTransform {
val fun = typer.atOwner(currentOwner).typed(
Function(List(), arg) setPos arg.pos).asInstanceOf[Function];
new ChangeOwnerTraverser(currentOwner, fun.symbol).traverse(arg);
- refchecks.newTransformer(unit).transformFunction(fun)
+ transformFunction(fun)
})
}
}
@@ -132,6 +203,8 @@ abstract class UnCurry extends InfoTransform {
val pat1 = transform(pat);
inPattern = false;
copy.CaseDef(tree, pat1, transform(guard), transform(body))
+ case fun @ Function(_, _) =>
+ mainTransform(transformFunction(fun))
case _ =>
assert(!tree.isInstanceOf[Function]);
val tree1 = super.transform(tree);
@@ -188,4 +261,15 @@ abstract class UnCurry extends InfoTransform {
}
}
}
+
+ private val resetAttrs = new Traverser {
+ override def traverse(tree: Tree): unit = tree match {
+ case EmptyTree | TypeTree() =>
+ ;
+ case _ =>
+ if (tree.hasSymbol) tree.symbol = NoSymbol;
+ tree.tpe = null;
+ super.traverse(tree)
+ }
+ }
}
diff --git a/sources/scala/tools/nsc/typechecker/Analyzer.scala b/sources/scala/tools/nsc/typechecker/Analyzer.scala
index 5789f5fe86..e895524915 100644
--- a/sources/scala/tools/nsc/typechecker/Analyzer.scala
+++ b/sources/scala/tools/nsc/typechecker/Analyzer.scala
@@ -15,7 +15,8 @@ package scala.tools.nsc.typechecker;
with Infer
with Variances
with EtaExpansion
- with SyntheticMethods {
+ with SyntheticMethods
+ with Codification {
val global: Global;
import global._;
diff --git a/sources/scala/tools/nsc/typechecker/RefChecks.scala b/sources/scala/tools/nsc/typechecker/RefChecks.scala
index 638a7f4543..4cd609d909 100755
--- a/sources/scala/tools/nsc/typechecker/RefChecks.scala
+++ b/sources/scala/tools/nsc/typechecker/RefChecks.scala
@@ -81,17 +81,6 @@ abstract class RefChecks extends InfoTransform {
mvarRef))
}
- val resetAttrs = new Traverser {
- override def traverse(tree: Tree): unit = tree match {
- case EmptyTree | TypeTree() =>
- ;
- case _ =>
- if (tree.hasSymbol) tree.symbol = NoSymbol;
- tree.tpe = null;
- super.traverse(tree)
- }
- }
-
class RefCheckTransformer(unit: CompilationUnit) extends Transformer {
var localTyper: analyzer.Typer = typer;
@@ -485,49 +474,6 @@ abstract class RefChecks extends InfoTransform {
List(transform(tree))
}
- def transformFunction(fun: Function): Tree = {
- val anonClass = fun.symbol.owner.newAnonymousFunctionClass(fun.pos) setFlag (FINAL | SYNTHETIC);
- val formals = fun.tpe.typeArgs.init;
- val restpe = fun.tpe.typeArgs.last;
- anonClass setInfo ClassInfoType(
- List(ObjectClass.tpe, fun.tpe, ScalaObjectClass.tpe), new Scope(), anonClass);
- val applyMethod = anonClass.newMethod(fun.pos, nme.apply)
- setFlag FINAL setInfo MethodType(formals, restpe);
- anonClass.info.decls enter applyMethod;
- for (val vparam <- fun.vparams) vparam.symbol.owner = applyMethod;
- new ChangeOwnerTraverser(fun.symbol, applyMethod).traverse(fun.body);
- var members = List(
- DefDef(FINAL, nme.apply, List(), List(fun.vparams), TypeTree(restpe), fun.body)
- setSymbol applyMethod);
- if (fun.tpe.symbol == PartialFunctionClass) {
- val isDefinedAtMethod = anonClass.newMethod(fun.pos, nme.isDefinedAt)
- setFlag FINAL setInfo MethodType(formals, BooleanClass.tpe);
- anonClass.info.decls enter isDefinedAtMethod;
- def idbody(idparam: Symbol) = fun.body match {
- case Match(_, cases) =>
- val substParam = new TreeSymSubstituter(List(fun.vparams.head.symbol), List(idparam));
- def transformCase(cdef: CaseDef): CaseDef =
- resetAttrs(CaseDef(cdef.pat.duplicate, cdef.guard.duplicate, Literal(true)));
- if (cases exists treeInfo.isDefaultCase) Literal(true)
- else
- Match(
- Ident(idparam),
- (cases map transformCase) :::
- List(CaseDef(Ident(nme.WILDCARD), EmptyTree, Literal(false))))
- }
- members = DefDef(isDefinedAtMethod, vparamss => idbody(vparamss.head.head)) :: members;
- }
- localTyper.typed {
- atPos(fun.pos) {
- Block(
- List(ClassDef(anonClass, List(List()), List(List()), members)),
- Typed(
- New(TypeTree(anonClass.tpe), List(List())),
- TypeTree(fun.tpe)))
- }
- }
- }
-
override def transform(tree: Tree): Tree = try {
/* Convert a reference of a case factory to a new of the class it produces. */
@@ -578,9 +524,6 @@ abstract class RefChecks extends InfoTransform {
}
} traverse tree.tpe
- case fun @ Function(_, _) =>
- result = transform(transformFunction(fun));
-
case TypeApply(fn, args) =>
checkBounds(fn.tpe.typeParams, args map (.tpe));
if (sym.isSourceMethod && sym.hasFlag(CASE)) result = toConstructor;
diff --git a/sources/scala/tools/nsc/typechecker/Typers.scala b/sources/scala/tools/nsc/typechecker/Typers.scala
index 835e617b98..83ec152b06 100755
--- a/sources/scala/tools/nsc/typechecker/Typers.scala
+++ b/sources/scala/tools/nsc/typechecker/Typers.scala
@@ -710,35 +710,8 @@ import collection.mutable.HashMap;
newTyper(context.makeNewScope(tree, context.owner)).typedCase(cdef, pattp, pt))
}
- /* Transform a function node (x_1,...,x_n) => body of type FunctionN[T_1, .., T_N, R] to
- *
- * class $anon() extends Object() with FunctionN[T_1, .., T_N, R] with ScalaObject {
- * def apply(x_1: T_1, ..., x_N: T_n): R = body
- * }
- * new $anon()
- *
- * transform a function node (x => body) of type PartialFunction[T, R] where
- * body = x match { case P_i if G_i => E_i }_i=1..n
- * to:
- *
- * class $anon() extends Object() with PartialFunction[T, R] with ScalaObject {
- * def apply(x: T): R = body;
- * def isDefinedAt(x: T): boolean = x match {
- * case P_1 if G_1 => true
- * ...
- * case P_n if G_n => true
- * case _ => false
- * }
- * }
- * new $anon()
- *
- * However, if one of the patterns P_i if G_i is a default pattern, generate instead
- *
- * def isDefinedAt(x: T): boolean = true
- */
-/*
def typedFunction(fun: Function, mode: int, pt: Type): Tree = {
- val Triple(clazz, argpts, respt) =
+ def decompose(tp: Type): Triple[Symbol, List[Type], Type] =
if (isFunctionType(pt)
||
pt.symbol == PartialFunctionClass &&
@@ -746,67 +719,10 @@ import collection.mutable.HashMap;
Triple(pt.symbol, pt.typeArgs.init, pt.typeArgs.last)
else
Triple(FunctionClass(fun.vparams.length), fun.vparams map (x => NoType), WildcardType);
- val vparamSyms = List.map2(fun.vparams, argpts) { (vparam, argpt) =>
- if (vparam.tpt.isEmpty)
- vparam.tpt.tpe =
- if (argpt == NoType) { error(vparam.pos, "missing parameter type"); ErrorType }
- else argpt;
- namer.enterSym(vparam);
- vparam.symbol
- }
- val vparams = List.mapConserve(fun.vparams)(typedValDef);
- val body = typed(fun.body, respt);
- val formals = vparamSyms map (.tpe);
- val restpe = body.tpe.deconst;
- val funtpe = typeRef(clazz.tpe.prefix, clazz, formals ::: List(restpe));
- assert(context.owner != RootClass);//debug
- val anonClass = context.owner.newAnonymousFunctionClass(fun.pos) setFlag (FINAL | SYNTHETIC);
- anonClass setInfo ClassInfoType(
- List(ObjectClass.tpe, funtpe, ScalaObjectClass.tpe), new Scope(), anonClass);
- val applyMethod = anonClass.newMethod(fun.pos, nme.apply)
- setFlag FINAL setInfo MethodType(formals, restpe);
- anonClass.info.decls enter applyMethod;
- for (val vparam <- vparamSyms) vparam.owner = applyMethod;
- new ChangeOwnerTraverser(context.owner, applyMethod).traverse(body);
- var members = List(
- DefDef(FINAL, nme.apply, List(), List(vparams), TypeTree(restpe), body)
- setSymbol applyMethod);
- if (pt.symbol == PartialFunctionClass) {
- val isDefinedAtMethod = anonClass.newMethod(fun.pos, nme.isDefinedAt)
- setFlag FINAL setInfo MethodType(formals, BooleanClass.tpe);
- anonClass.info.decls enter isDefinedAtMethod;
- def idbody(idparam: Symbol) = body match {
- case Match(_, cases) =>
- val substParam = new TreeSymSubstituter(List(vparams.head.symbol), List(idparam));
- def transformCase(cdef: CaseDef): CaseDef =
- resetAttrs(CaseDef(cdef.pat.duplicate, cdef.guard.duplicate, Literal(true)));
- if (cases exists treeInfo.isDefaultCase) Literal(true)
- else
- Match(
- Ident(idparam),
- (cases map transformCase) :::
- List(CaseDef(Ident(nme.WILDCARD), EmptyTree, Literal(false))))
- }
- members = DefDef(isDefinedAtMethod, vparamss => idbody(vparamss.head.head)) :: members;
- }
- typed(
- atPos(fun.pos)(
- Block(
- List(ClassDef(anonClass, List(List()), List(List()), members)),
- Typed(
- New(TypeTree(anonClass.tpe), List(List())),
- TypeTree(funtpe)))))
- }
-*/
- def typedFunction(fun: Function, mode: int, pt: Type): Tree = {
+
val Triple(clazz, argpts, respt) =
- if (isFunctionType(pt)
- ||
- pt.symbol == PartialFunctionClass &&
- fun.vparams.length == 1 && fun.body.isInstanceOf[Match])
- Triple(pt.symbol, pt.typeArgs.init, pt.typeArgs.last)
- else
- Triple(FunctionClass(fun.vparams.length), fun.vparams map (x => NoType), WildcardType);
+ decompose(if (pt.symbol == TypedCodeClass) pt.typeArgs.head else pt);
+
val vparamSyms = List.map2(fun.vparams, argpts) { (vparam, argpt) =>
if (vparam.tpt.isEmpty)
vparam.tpt.tpe =
@@ -820,8 +736,10 @@ import collection.mutable.HashMap;
val formals = vparamSyms map (.tpe);
val restpe = body.tpe.deconst;
val funtpe = typeRef(clazz.tpe.prefix, clazz, formals ::: List(restpe));
- copy.Function(fun, vparams, checkNoEscaping.locals(context.scope, restpe, body))
- setType funtpe
+ val fun1 = copy.Function(fun, vparams, checkNoEscaping.locals(context.scope, restpe, body))
+ setType funtpe;
+ if (pt.symbol == TypedCodeClass) typed(atPos(fun.pos)(codify(fun1)))
+ else fun1
}
def typedRefinement(stats: List[Tree]): List[Tree] = {
@@ -1477,7 +1395,6 @@ import collection.mutable.HashMap;
val startTime = if (util.Statistics.enabled) System.currentTimeMillis() else 0l;
def isBetter(sym1: Symbol, tpe1: Type, sym2: Symbol, tpe2: Type): boolean = {
- System.out.println("is better " + sym1 + ":" + tpe1 + " than " + sym2 + ":" + tpe2);
sym2.isError ||
(sym1.owner != sym2.owner) && (sym1.owner isSubClass sym2.owner) && (tpe1 matches tpe2);
}