diff options
author | Martin Odersky <odersky@gmail.com> | 2007-12-19 10:38:50 +0000 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2007-12-19 10:38:50 +0000 |
commit | 2ed9387915c9b813907c811ff889a056333d2ded (patch) | |
tree | dc577ecb63a6b6955bc75edddbac45a9b49f2685 /src/compiler | |
parent | e5d6f338deead8beb992d215ff57ea78c8c5b6f5 (diff) | |
download | scala-2ed9387915c9b813907c811ff889a056333d2ded.tar.gz scala-2ed9387915c9b813907c811ff889a056333d2ded.tar.bz2 scala-2ed9387915c9b813907c811ff889a056333d2ded.zip |
dual mode (generics or not) version of compiler...
dual mode (generics or not) version of compiler and libraries
Diffstat (limited to 'src/compiler')
6 files changed, 51 insertions, 29 deletions
diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala index 9a746bf1f3..35810e560d 100644 --- a/src/compiler/scala/tools/nsc/Global.scala +++ b/src/compiler/scala/tools/nsc/Global.scala @@ -169,7 +169,7 @@ class Global(var settings: Settings, var reporter: Reporter) extends SymbolTable } try { val clazz = Class.forName(settings.sourceReader.value) - val ccon = clazz.getConstructor(Array[Class](classOf[java.nio.charset.CharsetDecoder])) + val ccon = clazz.getConstructor(Array[Class[T] forSome { type T }](classOf[java.nio.charset.CharsetDecoder])) ccon.newInstance(Array[AnyRef] (charset.newDecoder())).asInstanceOf[SourceReader]; //new SourceReader(charset.newDecoder()) } catch { diff --git a/src/compiler/scala/tools/nsc/plugins/Plugin.scala b/src/compiler/scala/tools/nsc/plugins/Plugin.scala index 4f5e0a54bd..aa0a80e0aa 100644 --- a/src/compiler/scala/tools/nsc/plugins/Plugin.scala +++ b/src/compiler/scala/tools/nsc/plugins/Plugin.scala @@ -100,7 +100,7 @@ object Plugin { * if the jar file has no plugin in it or if the plugin * is badly formed. */ - def loadFrom(jarfile: File, loader: ClassLoader): Option[Class] = { + def loadFrom(jarfile: File, loader: ClassLoader): Option[Class[_]] = { val pluginInfo = loadDescription(jarfile).get try { @@ -120,7 +120,7 @@ object Plugin { */ def loadAllFrom(jars: List[File], dirs: List[File], - ignoring: List[String]): List[Class] = + ignoring: List[String]): List[Class[_]] = { val alljars = new ListBuffer[File] @@ -143,7 +143,7 @@ object Plugin { /** Instantiate a plugin class, given the class and * the compiler it is to be used in. */ - def instantiate(clazz: Class, global: Global): Plugin = { + def instantiate(clazz: Class[_], global: Global): Plugin = { val constructor = clazz.getConstructor(Array(classOf[Global])) constructor.newInstance(Array(global)).asInstanceOf[Plugin] } diff --git a/src/compiler/scala/tools/nsc/symtab/Types.scala b/src/compiler/scala/tools/nsc/symtab/Types.scala index c1c2448e31..d33c0dc652 100644 --- a/src/compiler/scala/tools/nsc/symtab/Types.scala +++ b/src/compiler/scala/tools/nsc/symtab/Types.scala @@ -1659,6 +1659,7 @@ A type's typeSymbol should never be inspected directly. { override protected def rewrap(newtp: Type) = existentialAbstraction(quantified, newtp) + override def isTrivial = false override def isStable: Boolean = false override def bounds = TypeBounds(maybeRewrap(underlying.bounds.lo), maybeRewrap(underlying.bounds.hi)) override def parents = underlying.parents map maybeRewrap @@ -2037,7 +2038,7 @@ A type's typeSymbol should never be inspected directly. /** A creator for type parameterizations * If tparams is empty, simply returns result type */ - def parameterizedType(tparams: List[Symbol], tpe: Type): Type = + def polyType(tparams: List[Symbol], tpe: Type): Type = if (tparams.isEmpty) tpe else PolyType(tparams, tpe match { @@ -2462,10 +2463,17 @@ A type's typeSymbol should never be inspected directly. private val emptySymMap = scala.collection.immutable.Map[Symbol, Symbol]() private val emptySymCount = scala.collection.immutable.Map[Symbol, Int]() - private def makeExistential(suffix: String, owner: Symbol, lo: Type, hi: Type) = + /** Make an existential variable. + * @param suffix A suffix to be appended to the freshly generated name + * It's ususally "", except for type variables abstracting + * over values, where it is ".type". + * @param owner The owner of the variable + * @param bounds The variable's bounds + */ + def makeExistential(suffix: String, owner: Symbol, bounds: TypeBounds): Symbol = recycle( owner.newAbstractType(owner.pos, newTypeName(freshTypeName()+suffix)).setFlag(EXISTENTIAL) - ).setInfo(TypeBounds(lo, hi)) + ).setInfo(bounds) /** A map to compute the asSeenFrom method */ class AsSeenFromMap(pre: Type, clazz: Symbol) extends TypeMap { @@ -2507,7 +2515,8 @@ A type's typeSymbol should never be inspected directly. def stabilize(pre: Type, clazz: Symbol): Type = { capturedPre get clazz match { case None => - val qvar = makeExistential(".type", clazz, AllClass.tpe, intersectionType(List(pre, SingletonClass.tpe))) + val qvar = makeExistential(".type", clazz, + mkTypeBounds(AllClass.tpe, intersectionType(List(pre, SingletonClass.tpe)))) capturedPre += (clazz -> qvar) capturedParams = qvar :: capturedParams qvar @@ -2586,7 +2595,7 @@ A type's typeSymbol should never be inspected directly. "something is wrong (wrong class file?): "+basesym+ " with type parameters "+ basesym.typeParams.map(_.name).mkString("[",",","]")+ - " gets applied to arguments "+baseargs.mkString("(",",",")")+", phase = "+phase) + " gets applied to arguments "+baseargs.mkString("[",",","]")+", phase = "+phase) instParam(basesym.typeParams, baseargs); case ExistentialType(tparams, qtpe) => capturedParams = capturedParams union tparams @@ -3180,7 +3189,14 @@ A type's typeSymbol should never be inspected directly. !(List.map3(args1, args2, sym1.typeParams) { (arg1, arg2, tparam) => //if (tparam.variance == 0 && !(arg1 =:= arg2)) Console.println("inconsistent: "+arg1+"!="+arg2)//DEBUG - tparam.variance != 0 || arg1 =:= arg2 + if (tparam.variance == 0) arg1 =:= arg2 + else if (arg1.isInstanceOf[TypeVar]) + // if left-hand argument is a typevar, make it compatible with variance + // this is for more precise pattern matching + // todo: work this in the spec of this method + // also: think what happens if there are embedded typevars? + if (tparam.variance < 0) arg1 <:< arg2 else arg2 <:< arg1 + else true } contains false) case (et: ExistentialType, _) => et.withTypeVars(isConsistent(_, tp2)) @@ -4090,7 +4106,7 @@ A type's typeSymbol should never be inspected directly. if (l <:< g) l else { val owner = commonOwner(as) - val qvar = makeExistential("", commonOwner(as), g, l) + val qvar = makeExistential("", commonOwner(as), mkTypeBounds(g, l)) capturedParams += qvar qvar.tpe } diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala index 06209194b7..13c666e122 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala @@ -470,11 +470,10 @@ abstract class ClassfileParser { case VOID_TAG => definitions.UnitClass.tpe case BOOL_TAG => definitions.BooleanClass.tpe case 'L' => { - val classSym = classNameToSymbol(subName(c => ((c == ';') || (c == '<')))) + val classSym = classNameToSymbol(subName(c => c == ';' || c == '<')) assert(!classSym.hasFlag(OVERLOADED), classSym.alternatives) val existentials = new ListBuffer[Symbol]() val tpe: Type = if (sig(index) == '<') { - assert(sym != null) accept('<') val xs = new ListBuffer[Type]() while (sig(index) != '>') { @@ -489,13 +488,11 @@ abstract class ClassfileParser { case '*' => mkTypeBounds(definitions.AllClass.tpe, definitions.AnyClass.tpe) } - val name = fresh.newName("T_" + sym.name) - val newtparam = sym.newTypeParameter(NoPosition, name) + val newtparam = makeExistential("", sym, bounds) existentials += newtparam - newtparam.setInfo(bounds) xs += newtparam.tpe - - case _ => xs += sig2type(tparams) + case _ => + xs += sig2type(tparams) } } accept('>') @@ -571,7 +568,7 @@ abstract class ClassfileParser { } ClassInfoType(parents.toList, instanceDefs, sym) } - parameterizedType(newTParams.toList, tpe) + polyType(newTParams.toList, tpe) } // polySigToType @@ -592,8 +589,8 @@ abstract class ClassfileParser { val sig = pool.getExternalName(in.nextChar) val newType = sigToType(sym, sig) sym.setInfo(newType) - if (settings.debug.value) - global.inform("" + sym + "; signatire = " + sig + " type = " + newType) +// if (settings.debug.value) + println("" + sym + "; signature = " + sig + " type = " + newType) hasMeta = true } else in.skip(attrLen) @@ -731,7 +728,8 @@ abstract class ClassfileParser { pool.getClassSymbol(outerIndex) == sym) { val innerAlias = getOwner(jflags) .newAliasType(NoPosition, pool.getName(nameIndex).toTypeName) - .setInfo(pool.getClassSymbol(innerIndex).tpe) + .setFlag(JAVA) + .setInfo(new LazyAliasType(pool.getClassSymbol(innerIndex))) getScope(jflags).enter(innerAlias) if ((jflags & JAVA_ACC_STATIC) != 0) { @@ -746,6 +744,14 @@ abstract class ClassfileParser { for (i <- 0 until attrCount) parseAttribute() } + class LazyAliasType(alias: Symbol) extends LazyType { + override def complete(sym: Symbol) { + alias.initialize + val tparams1 = cloneSymbols(alias.typeParams) + sym.setInfo(polyType(tparams1, alias.tpe.substSym(alias.typeParams, tparams1))) + } + } + def skipAttributes() { val attrCount = in.nextChar for (i <- 0 until attrCount) { diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala index b285113ee6..1ae4eced0e 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala @@ -522,7 +522,7 @@ trait Namers { self: Analyzer => } private def classSig(tparams: List[TypeDef], impl: Template): Type = - parameterizedType(typer.reenterTypeParams(tparams), templateSig(impl)) + polyType(typer.reenterTypeParams(tparams), templateSig(impl)) private def methodSig(tparams: List[TypeDef], vparamss: List[List[ValDef]], tpt: Tree, rhs: Tree): Type = { @@ -613,7 +613,7 @@ trait Namers { self: Analyzer => } def thisMethodType(restpe: Type) = - parameterizedType( + polyType( tparamSyms, if (vparamSymss.isEmpty) PolyType(List(), restpe) else checkDependencies((vparamSymss :\ restpe) (makeMethodType))) @@ -739,7 +739,7 @@ trait Namers { self: Analyzer => if (tpsym.owner.isRefinementClass && // only needed in refinements !tpsym.allOverriddenSymbols.forall{verifyOverriding(_)}) ErrorType - else parameterizedType(tparamSyms, tp) + else polyType(tparamSyms, tp) } def typeSig(tree: Tree): Type = { diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 2e3290c8d1..a42a7fbb6d 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -1890,7 +1890,7 @@ trait Typers { self: Analyzer => protected def existentialBound(sym: Symbol): Type = if (sym.isClass) - parameterizedType(sym.typeParams, mkTypeBounds(AllClass.tpe, sym.classBound)) + polyType(sym.typeParams, mkTypeBounds(AllClass.tpe, sym.classBound)) else if (sym.isAbstractType) sym.info else if (sym.isTerm) @@ -2340,7 +2340,7 @@ trait Typers { self: Analyzer => // of the type arguments as we don't know which alternative to choose... here we do val args1 = map2Conserve(args, tparams) { //@M! the polytype denotes the expected kind - (arg, tparam) => typedHigherKindedType(arg, parameterizedType(tparam.typeParams, AnyClass.tpe)) + (arg, tparam) => typedHigherKindedType(arg, polyType(tparam.typeParams, AnyClass.tpe)) } typedTypeApply(fun, args1) case SingleType(_, _) => @@ -2829,7 +2829,7 @@ trait Typers { self: Analyzer => // if symbol hasn't been fully loaded, can't check kind-arity else map2Conserve(args, tparams) { (arg, tparam) => - typedHigherKindedType(arg, parameterizedType(tparam.typeParams, AnyClass.tpe)) + typedHigherKindedType(arg, polyType(tparam.typeParams, AnyClass.tpe)) //@M! the polytype denotes the expected kind } val argtypes = args1 map (_.tpe) @@ -3020,7 +3020,7 @@ trait Typers { self: Analyzer => // @M maybe the well-kindedness check should be done when checking the type arguments conform to the type parameters' bounds? val args1 = if(args.length == tparams.length) map2Conserve(args, tparams) { //@M! the polytype denotes the expected kind - (arg, tparam) => typedHigherKindedType(arg, parameterizedType(tparam.typeParams, AnyClass.tpe)) + (arg, tparam) => typedHigherKindedType(arg, polyType(tparam.typeParams, AnyClass.tpe)) } else { //@M this branch is correctly hit for an overloaded polymorphic type. It also has to handle erroneous cases. // Until the right alternative for an overloaded method is known, be very liberal, |