diff options
author | Martin Odersky <odersky@gmail.com> | 2005-11-09 15:52:02 +0000 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2005-11-09 15:52:02 +0000 |
commit | 8a426ccf5f56f2d21ab6bad7d02ec2b1b2532346 (patch) | |
tree | 25f206e4bb54429bef68d0e680abc405fab6cbba | |
parent | 071be391c1cf77c3e22c33aad8a2e783c59d1574 (diff) | |
download | scala-8a426ccf5f56f2d21ab6bad7d02ec2b1b2532346.tar.gz scala-8a426ccf5f56f2d21ab6bad7d02ec2b1b2532346.tar.bz2 scala-8a426ccf5f56f2d21ab6bad7d02ec2b1b2532346.zip |
*** empty log message ***
-rwxr-xr-x | sources/scala/tools/nsc/symtab/Symbols.scala | 24 | ||||
-rwxr-xr-x | sources/scala/tools/nsc/symtab/Types.scala | 28 | ||||
-rwxr-xr-x | sources/scala/tools/nsc/transform/Erasure.scala | 22 | ||||
-rwxr-xr-x | sources/scala/tools/nsc/typechecker/Namers.scala | 66 | ||||
-rwxr-xr-x | sources/scala/tools/nsc/typechecker/Typers.scala | 5 |
5 files changed, 101 insertions, 44 deletions
diff --git a/sources/scala/tools/nsc/symtab/Symbols.scala b/sources/scala/tools/nsc/symtab/Symbols.scala index 92887ac6b6..396f733ca3 100755 --- a/sources/scala/tools/nsc/symtab/Symbols.scala +++ b/sources/scala/tools/nsc/symtab/Symbols.scala @@ -84,6 +84,12 @@ import Flags._; new TypeSymbol(this, pos, name).setFlag(DEFERRED); final def newTypeParameter(pos: int, name: Name) = newAbstractType(pos, name).setFlag(PARAM); + final def newSkolem(tparam: Symbol) = tparam;// for now +/* + new TypeSkolem(this, tparam.pos, tparam.name, tparam) + .setFlag(tparam.flags) + .setInfo(tparam.rawInfo); +*/ final def newClass(pos: int, name: Name) = new ClassSymbol(this, pos, name); final def newModuleClass(pos: int, name: Name) = @@ -104,9 +110,9 @@ import Flags._; // Tests ---------------------------------------------------------------------- - def isTerm = false; //to be overridden - def isType = false; //to be overridden - def isClass = false; //to be overridden + def isTerm = false; //to be overridden + def isType = false; //to be overridden + def isClass = false; //to be overridden final def isValue = isTerm && !(isModule && hasFlag(PACKAGE | JAVA)); final def isVariable = isTerm && hasFlag(MUTABLE) && !isMethod; @@ -584,6 +590,9 @@ import Flags._; final def setter(base: Symbol): Symbol = base.info.decl(nme.getterToSetter(nme.getterName(name))) filter (.hasFlag(ACCESSOR)); + /** If this symbol is a skolem, its corresponding type parameter, otherwise this */ + def deSkolemize: Symbol = this; + /** Remove private modifier from symbol `sym's definition. If `sym' is a * term symbol rename it by expanding its name to avoid name clashes */ @@ -859,6 +868,15 @@ import Flags._; if (util.Statistics.enabled) typeSymbolCount = typeSymbolCount + 1; } + /** A class for type parameters viewed from inside their scopes */ + class TypeSkolem(initOwner: Symbol, initPos: int, initName: Name, typeParam: Symbol) extends TypeSymbol(initOwner, initPos, initName) { + override def deSkolemize = typeParam; + override def cloneSymbolImpl(owner: Symbol): Symbol = { + throw new Error("should not clone a type skolem"); + } + override def toString(): String = super.toString() + "&"; + } + /** A class for class symbols */ class ClassSymbol(initOwner: Symbol, initPos: int, initName: Name) extends TypeSymbol(initOwner, initPos, initName) { var sourceFile: AbstractFile = null; diff --git a/sources/scala/tools/nsc/symtab/Types.scala b/sources/scala/tools/nsc/symtab/Types.scala index d4df21fd0a..5aa43e088e 100755 --- a/sources/scala/tools/nsc/symtab/Types.scala +++ b/sources/scala/tools/nsc/symtab/Types.scala @@ -1172,7 +1172,7 @@ import Flags._; val symclazz = sym.owner; def throwError = throw new Error("" + tp + " in " + symclazz + - "cannot be instantiated from " + pre.widen); + " cannot be instantiated from " + pre.widen); def instParam(ps: List[Symbol], as: List[Type]): Type = if (ps.isEmpty) throwError else if (sym eq ps.head) as.head @@ -1346,6 +1346,32 @@ import Flags._; } } + /** Convert to corresponding type parameters all skolems which satisfy one of the + * following two conditions: + * 1. The skolem is a parameter of a class or alias type + * 2. The skolem is a method parameter which appears in parameter `tparams' + */ + class DeSkolemizeMap(tparams: List[Symbol]) extends TypeMap { + def apply(tp: Type): Type = tp;//for now + /* + tp match { + case TypeRef(pre, sym, args) => + val tparam = sym.deSkolemize; + mapOver( + if (tparam == sym || tparam.owner.isTerm && !(tparams contains tparam)) tp + else rawTypeRef(pre, tparam, args)) + case PolyType(tparams1, restpe) => + assert(tparams.isEmpty); + new DeSkolemizeMap(tparams1).mapOver(tp) + case ClassInfoType(_, _, _) => + tp + case _ => + mapOver(tp) + } + */ + } + val deSkolemize = new DeSkolemizeMap(List()); + // Helper Methods ------------------------------------------------------------- final def isValid(p: Phase): boolean = diff --git a/sources/scala/tools/nsc/transform/Erasure.scala b/sources/scala/tools/nsc/transform/Erasure.scala index 659b12ff5c..21b2c6b642 100755 --- a/sources/scala/tools/nsc/transform/Erasure.scala +++ b/sources/scala/tools/nsc/transform/Erasure.scala @@ -199,7 +199,7 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer { /** Adapt `tree' to expected type `pt' */ private def adaptToType(tree: Tree, pt: Type): Tree = { - //if (settings.debug.value && pt != WildcardType) log("adapting " + tree + ":" + tree.tpe + " to " + pt);//DEBUG + if (settings.debug.value && pt != WildcardType) log("adapting " + tree + ":" + tree.tpe + " to " + pt);//debug if (tree.tpe <:< pt) tree else if (isUnboxedClass(tree.tpe.symbol) && !isUnboxedClass(pt.symbol)) @@ -239,15 +239,17 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer { atPos(tree.pos) { Typed(Apply(Select(New(TypeTree(BoxedAnyArrayClass.tpe)), name), args), tpt) } - case Apply(TypeApply(sel @ Select(qual, name), List(targ)), List()) => - if ((tree.symbol == Any_asInstanceOf || tree.symbol == Any_asInstanceOfErased) && - isValueClass(targ.tpe.symbol)) { - val qual1 = typedQualifier(qual); - if (isNumericValueClass(qual1.tpe.symbol) && isNumericValueClass(targ.tpe.symbol)) - // convert numeric type casts - atPos(tree.pos)(Apply(Select(qual1, "to" + targ.tpe.symbol.name), List())) - else unbox(qual1, targ.tpe) - } else tree + case Apply(TypeApply(sel @ Select(qual, name), List(targ)), List()) + if ((tree.symbol == Any_asInstanceOf || tree.symbol == Any_asInstanceOfErased)) => + val qual1 = typedQualifier(qual); + val targClass = targ.tpe.symbol; + if (isNumericValueClass(qual1.tpe.symbol) && isNumericValueClass(targClass)) + // convert numeric type casts + atPos(tree.pos)(Apply(Select(qual1, "to" + targClass.name), List())) + else if (isValueClass(targClass) || + (targClass == ArrayClass && (qual1.tpe <:< BoxedArrayClass.tpe))) + unbox(qual1, targ.tpe) + else tree case Select(qual, name) if (name != nme.CONSTRUCTOR) => if (tree.symbol == Any_asInstanceOf || tree.symbol == Any_asInstanceOfErased) adaptMember(atPos(tree.pos)(Select(qual, Object_asInstanceOf))) diff --git a/sources/scala/tools/nsc/typechecker/Namers.scala b/sources/scala/tools/nsc/typechecker/Namers.scala index 3b6f353714..abe7d05a32 100755 --- a/sources/scala/tools/nsc/typechecker/Namers.scala +++ b/sources/scala/tools/nsc/typechecker/Namers.scala @@ -125,6 +125,10 @@ trait Namers: Analyzer { } def finish = finishWith(List()); + def skolemize(tparams: List[AbsTypeDef]): unit = { + for (val tp <- tparams) tp.symbol = context.owner.newSkolem(tp.symbol) + } + if (tree.symbol == NoSymbol) { val owner = context.owner; tree match { @@ -141,7 +145,8 @@ trait Namers: Analyzer { } val mods1: int = if (impl.body forall treeInfo.isInterfaceMember) mods | INTERFACE else mods; tree.symbol = enterClassSymbol(tree.pos, mods1, name); - finishWith(tparams) + finishWith(tparams); + skolemize(tparams); case ModuleDef(mods, name, _) => tree.symbol = enterModuleSymbol(tree.pos, mods | MODULE | FINAL, name); tree.symbol.moduleClass.setInfo(innerNamer.typeCompleter(tree)); @@ -174,10 +179,12 @@ trait Namers: Analyzer { case DefDef(mods, nme.CONSTRUCTOR, tparams, vparams, tp, rhs) => tree.symbol = enterInScope(owner.newConstructor(tree.pos)) .setFlag(mods | owner.getFlag(ConstrFlags)); - finishWith(tparams) + finishWith(tparams); + skolemize(tparams); case DefDef(mods, name, tparams, _, _, _) => tree.symbol = enterInScope(owner.newMethod(tree.pos, name)).setFlag(mods); - finishWith(tparams) + finishWith(tparams); + skolemize(tparams); case AbsTypeDef(mods, name, _, _) => tree.symbol = enterInScope(owner.newAbstractType(tree.pos, name)).setFlag(mods); finish @@ -346,7 +353,7 @@ trait Namers: Analyzer { private def aliasTypeSig(tpsym: Symbol, tparams: List[AbsTypeDef], rhs: Tree): Type = makePolyType(typer.reenterTypeParams(tparams), typer.typedType(rhs).tpe); - private def typeSig(tree: Tree): Type = + private def typeSig(tree: Tree): Type = deSkolemize { try { val sym: Symbol = tree.symbol; tree match { @@ -355,9 +362,9 @@ trait Namers: Analyzer { case ModuleDef(_, _, impl) => val clazz = sym.moduleClass; - clazz.setInfo(new Namer(context.make(tree, clazz)).templateSig(impl)); - //clazz.typeOfThis = singleType(sym.owner.thisType, sym); - clazz.tpe; + clazz.setInfo(new Namer(context.make(tree, clazz)).templateSig(impl)); + //clazz.typeOfThis = singleType(sym.owner.thisType, sym); + clazz.tpe; case DefDef(_, _, tparams, vparamss, tpt, rhs) => if (sym.isConstructor) sym.owner.setFlag(INCONSTRUCTOR); @@ -367,46 +374,47 @@ trait Namers: Analyzer { checkContractive(sym, result) case ValDef(_, _, tpt, rhs) => - if (tpt.isEmpty) - if (rhs.isEmpty) { + if (tpt.isEmpty) + if (rhs.isEmpty) { context.error(tpt.pos, "missing parameter type"); - ErrorType - } else { - tpt.tpe = deconstIfNotFinal(sym, newTyper(context.make(tree, sym)).computeType(rhs)); - tpt.tpe - } - else typer.typedType(tpt).tpe + ErrorType + } else { + tpt.tpe = deconstIfNotFinal(sym, newTyper(context.make(tree, sym)).computeType(rhs)); + tpt.tpe + } + else typer.typedType(tpt).tpe case AliasTypeDef(_, _, tparams, rhs) => - new Namer(context.makeNewScope(tree, sym)).aliasTypeSig(sym, tparams, rhs) + new Namer(context.makeNewScope(tree, sym)).aliasTypeSig(sym, tparams, rhs) case AbsTypeDef(_, _, lo, hi) => - TypeBounds(typer.typedType(lo).tpe, typer.typedType(hi).tpe); + TypeBounds(typer.typedType(lo).tpe, typer.typedType(hi).tpe); - case Import(expr, selectors) => - val expr1 = typer.typedQualifier(expr); + case Import(expr, selectors) => + val expr1 = typer.typedQualifier(expr); val base = expr1.tpe; - typer.checkStable(expr1); - def checkSelectors(selectors: List[Pair[Name, Name]]): unit = selectors match { - case Pair(from, to) :: rest => - if (from != nme.WILDCARD && base != ErrorType && + typer.checkStable(expr1); + def checkSelectors(selectors: List[Pair[Name, Name]]): unit = selectors match { + case Pair(from, to) :: rest => + if (from != nme.WILDCARD && base != ErrorType && base.member(from) == NoSymbol && base.member(from.toTypeName) == NoSymbol) - context.error(tree.pos, from.decode + " is not a member of " + expr); + context.error(tree.pos, from.decode + " is not a member of " + expr); if (from != nme.WILDCARD && (rest.exists (sel => sel._1 == from))) context.error(tree.pos, from.decode + " is renamed twice"); - if (to != null && to != nme.WILDCARD && (rest exists (sel => sel._2 == to))) + if (to != null && to != nme.WILDCARD && (rest exists (sel => sel._2 == to))) context.error(tree.pos, to.decode + " appears twice as a target of a renaming"); - checkSelectors(rest) - case Nil => + checkSelectors(rest) + case Nil => } checkSelectors(selectors); - ImportType(expr1) - } + ImportType(expr1) + } } catch { case ex: TypeError => typer.reportTypeError(tree.pos, ex); ErrorType } + } /** Check that symbol's definition is well-formed. This means: * - no conflicting modifiers diff --git a/sources/scala/tools/nsc/typechecker/Typers.scala b/sources/scala/tools/nsc/typechecker/Typers.scala index 8cddbef7fb..520272920c 100755 --- a/sources/scala/tools/nsc/typechecker/Typers.scala +++ b/sources/scala/tools/nsc/typechecker/Typers.scala @@ -215,7 +215,10 @@ import collection.mutable.HashMap; for (val vparams <- vparamss; val vparam <- vparams) context.scope enter vparam.symbol; def reenterTypeParams(tparams: List[AbsTypeDef]): List[Symbol] = - for (val tparam <- tparams) yield { context.scope enter tparam.symbol; tparam.symbol } + for (val tparam <- tparams) yield { + context.scope enter tparam.symbol; + tparam.symbol.deSkolemize + } def attrInfo(attr: Tree): AttrInfo = attr match { case Apply(Select(New(tpt), nme.CONSTRUCTOR), args) => |