diff options
author | Martin Odersky <odersky@gmail.com> | 2005-10-10 15:44:14 +0000 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2005-10-10 15:44:14 +0000 |
commit | 60b24c0671d01cd3dad2da5914d92105912d969c (patch) | |
tree | 360718e965e734383177c7d5fabfa12ddd415b5e | |
parent | e093d72b2f4eb1bf65beafbd6aff1023e3dd1511 (diff) | |
download | scala-60b24c0671d01cd3dad2da5914d92105912d969c.tar.gz scala-60b24c0671d01cd3dad2da5914d92105912d969c.tar.bz2 scala-60b24c0671d01cd3dad2da5914d92105912d969c.zip |
*** empty log message ***
-rw-r--r-- | sources/scala/List.scala | 11 | ||||
-rw-r--r-- | sources/scala/concurrent/jolib.scala | 4 | ||||
-rwxr-xr-x | sources/scala/reflect/Code.scala | 3 | ||||
-rwxr-xr-x | sources/scala/tools/nsc/symtab/Definitions.scala | 2 | ||||
-rwxr-xr-x | sources/scala/tools/nsc/symtab/Types.scala | 9 | ||||
-rwxr-xr-x | sources/scala/tools/nsc/transform/UnCurry.scala | 86 | ||||
-rw-r--r-- | sources/scala/tools/nsc/typechecker/Analyzer.scala | 3 | ||||
-rwxr-xr-x | sources/scala/tools/nsc/typechecker/RefChecks.scala | 57 | ||||
-rwxr-xr-x | sources/scala/tools/nsc/typechecker/Typers.scala | 99 |
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); } |