@@ -14,6 +14,14 @@ import PartialFunction._
1414trait Definitions extends reflect.api.StandardDefinitions {
1515 self : SymbolTable =>
1616
17+ /** Since both the value parameter types and the result type may
18+ * require access to the type parameter symbols, we model polymorphic
19+ * creation as a function from those symbols to (formal types, result type).
20+ * The Option is to distinguish between nullary methods and empty-param-list
21+ * methods.
22+ */
23+ private type PolyMethodCreator = List [Symbol ] => (Option [List [Type ]], Type )
24+
1725 private def newClass (owner : Symbol , name : TypeName , parents : List [Type ], flags : Long = 0L ): Symbol = {
1826 val clazz = owner.newClassSymbol(name, NoPosition , flags)
1927 clazz setInfoAndEnter ClassInfoType (parents, newScope, clazz)
@@ -311,17 +319,10 @@ trait Definitions extends reflect.api.StandardDefinitions {
311319 lazy val RemoteInterfaceClass = getRequiredClass(" java.rmi.Remote" )
312320 lazy val RemoteExceptionClass = getRequiredClass(" java.rmi.RemoteException" )
313321
314- lazy val RepeatedParamClass = newCovariantPolyClass(
315- ScalaPackageClass ,
316- tpnme.REPEATED_PARAM_CLASS_NAME ,
317- tparam => seqType(tparam.typeConstructor)
318- )
319-
320- lazy val JavaRepeatedParamClass = newCovariantPolyClass(
321- ScalaPackageClass ,
322- tpnme.JAVA_REPEATED_PARAM_CLASS_NAME ,
323- tparam => arrayType(tparam.typeConstructor)
324- )
322+ lazy val ByNameParamClass = specialPolyClass(tpnme.BYNAME_PARAM_CLASS_NAME , COVARIANT )(_ => AnyClass .typeConstructor)
323+ lazy val EqualsPatternClass = specialPolyClass(tpnme.EQUALS_PATTERN_NAME , 0L )(_ => AnyClass .typeConstructor)
324+ lazy val JavaRepeatedParamClass = specialPolyClass(tpnme.JAVA_REPEATED_PARAM_CLASS_NAME , COVARIANT )(tparam => arrayType(tparam.typeConstructor))
325+ lazy val RepeatedParamClass = specialPolyClass(tpnme.REPEATED_PARAM_CLASS_NAME , COVARIANT )(tparam => seqType(tparam.typeConstructor))
325326
326327 def isByNameParamType (tp : Type ) = tp.typeSymbol == ByNameParamClass
327328 def isScalaRepeatedParamType (tp : Type ) = tp.typeSymbol == RepeatedParamClass
@@ -350,15 +351,6 @@ trait Definitions extends reflect.api.StandardDefinitions {
350351 case _ => false
351352 }
352353
353- lazy val ByNameParamClass = newCovariantPolyClass(
354- ScalaPackageClass ,
355- tpnme.BYNAME_PARAM_CLASS_NAME ,
356- tparam => AnyClass .typeConstructor
357- )
358- lazy val EqualsPatternClass = {
359- val clazz = newClass(ScalaPackageClass , tpnme.EQUALS_PATTERN_NAME , Nil )
360- clazz setInfo polyType(List (newTypeParam(clazz, 0 )), ClassInfoType (anyparam, newScope, clazz))
361- }
362354 lazy val MatchingStrategyClass = getRequiredClass(" scala.MatchingStrategy" )
363355
364356 // collections classes
@@ -429,24 +421,27 @@ trait Definitions extends reflect.api.StandardDefinitions {
429421 * information into the toString method.
430422 */
431423 def manifestToType (m : OptManifest [_]): Type = m match {
432- case x : AnyValManifest [_] =>
433- getClassIfDefined(" scala." + x).tpe
434424 case m : ClassManifest [_] =>
435- val name = m.erasure.getName
436- if (name endsWith nme.MODULE_SUFFIX_STRING )
437- getModuleIfDefined(name stripSuffix nme.MODULE_SUFFIX_STRING ).tpe
438- else {
439- val sym = getClassIfDefined(name)
440- val args = m.typeArguments
441-
442- if (sym eq NoSymbol ) NoType
443- else if (args.isEmpty) sym.tpe
444- else appliedType(sym.typeConstructor, args map manifestToType)
445- }
425+ val sym = manifestToSymbol(m)
426+ val args = m.typeArguments
427+
428+ if ((sym eq NoSymbol ) || args.isEmpty) sym.tpe
429+ else appliedType(sym.typeConstructor, args map manifestToType)
446430 case _ =>
447431 NoType
448432 }
449433
434+ def manifestToSymbol (m : ClassManifest [_]): Symbol = m match {
435+ case x : scala.reflect.AnyValManifest [_] =>
436+ getMember(ScalaPackageClass , newTypeName(" " + x))
437+ case _ =>
438+ val name = m.erasure.getName
439+ if (name endsWith nme.MODULE_SUFFIX_STRING )
440+ getModuleIfDefined(name stripSuffix nme.MODULE_SUFFIX_STRING )
441+ else
442+ getClassIfDefined(name)
443+ }
444+
450445 // The given symbol represents either String.+ or StringAdd.+
451446 def isStringAddition (sym : Symbol ) = sym == String_+ || sym == StringAdd_+
452447 def isArrowAssoc (sym : Symbol ) = ArrowAssocClass .tpe.decls.toList contains sym
@@ -594,6 +589,14 @@ trait Definitions extends reflect.api.StandardDefinitions {
594589 case _ => NoType
595590 }
596591
592+ /** To avoid unchecked warnings on polymorphic classes, translate
593+ * a Foo[T] into a Foo[_] for use in the pattern matcher.
594+ */
595+ def typeCaseType (clazz : Symbol ) = clazz.tpe.normalize match {
596+ case TypeRef (_, sym, args) if args.nonEmpty => newExistentialType(sym.typeParams, clazz.tpe)
597+ case tp => tp
598+ }
599+
597600 def seqType (arg : Type ) = appliedType(SeqClass .typeConstructor, List (arg))
598601 def arrayType (arg : Type ) = appliedType(ArrayClass .typeConstructor, List (arg))
599602 def byNameType (arg : Type ) = appliedType(ByNameParamClass .typeConstructor, List (arg))
@@ -637,8 +640,8 @@ trait Definitions extends reflect.api.StandardDefinitions {
637640 }
638641
639642 // members of class scala.Any
640- lazy val Any_== = newMethod(AnyClass , nme.EQ , anyparam, booltype, FINAL )
641- lazy val Any_!= = newMethod(AnyClass , nme.NE , anyparam, booltype, FINAL )
643+ lazy val Any_== = newMethod(AnyClass , nme.EQ , anyparam, booltype, FINAL )
644+ lazy val Any_!= = newMethod(AnyClass , nme.NE , anyparam, booltype, FINAL )
642645 lazy val Any_equals = newMethod(AnyClass , nme.equals_, anyparam, booltype)
643646 lazy val Any_hashCode = newMethod(AnyClass , nme.hashCode_, Nil , inttype)
644647 lazy val Any_toString = newMethod(AnyClass , nme.toString_, Nil , stringtype)
@@ -653,28 +656,21 @@ trait Definitions extends reflect.api.StandardDefinitions {
653656 // Since getClass is not actually a polymorphic method, this requires compiler
654657 // participation. At the "Any" level, the return type is Class[_] as it is in
655658 // java.lang.Object. Java also special cases the return type.
656- lazy val Any_getClass =
657- newMethod(AnyClass , nme.getClass_, Nil , getMember(ObjectClass , nme.getClass_).tpe.resultType, DEFERRED )
658- lazy val Any_isInstanceOf = newPolyMethod(
659- AnyClass , nme.isInstanceOf_, tparam => NullaryMethodType (booltype)) setFlag FINAL
660- lazy val Any_asInstanceOf = newPolyMethod(
661- AnyClass , nme.asInstanceOf_, tparam => NullaryMethodType (tparam.typeConstructor)) setFlag FINAL
659+ lazy val Any_getClass = newMethod(AnyClass , nme.getClass_, Nil , getMember(ObjectClass , nme.getClass_).tpe.resultType, DEFERRED )
660+ lazy val Any_isInstanceOf = newT1NullaryMethod(AnyClass , nme.isInstanceOf_, FINAL )(_ => booltype)
661+ lazy val Any_asInstanceOf = newT1NullaryMethod(AnyClass , nme.asInstanceOf_, FINAL )(_.typeConstructor)
662662
663663 // members of class java.lang.{ Object, String }
664664 lazy val Object_## = newMethod(ObjectClass , nme.HASHHASH , Nil , inttype, FINAL )
665665 lazy val Object_== = newMethod(ObjectClass , nme.EQ , anyrefparam, booltype, FINAL )
666666 lazy val Object_!= = newMethod(ObjectClass , nme.NE , anyrefparam, booltype, FINAL )
667667 lazy val Object_eq = newMethod(ObjectClass , nme.eq, anyrefparam, booltype, FINAL )
668668 lazy val Object_ne = newMethod(ObjectClass , nme.ne, anyrefparam, booltype, FINAL )
669- lazy val Object_synchronized = newPolyMethodCon(
670- ObjectClass , nme.synchronized_,
671- tparam => msym => MethodType (msym.newSyntheticValueParams(List (tparam.typeConstructor)), tparam.typeConstructor)) setFlag FINAL
672- lazy val Object_isInstanceOf = newPolyMethod(
673- ObjectClass , newTermName(" $isInstanceOf" ),
674- tparam => MethodType (List (), booltype)) setFlag (FINAL | SYNTHETIC )
675- lazy val Object_asInstanceOf = newPolyMethod(
676- ObjectClass , newTermName(" $asInstanceOf" ),
677- tparam => MethodType (List (), tparam.typeConstructor)) setFlag (FINAL | SYNTHETIC )
669+ lazy val Object_isInstanceOf = newT1NoParamsMethod(ObjectClass , nme.isInstanceOf_Ob, FINAL | SYNTHETIC )(_ => booltype)
670+ lazy val Object_asInstanceOf = newT1NoParamsMethod(ObjectClass , nme.asInstanceOf_Ob, FINAL | SYNTHETIC )(_.typeConstructor)
671+ lazy val Object_synchronized = newPolyMethod(1 , ObjectClass , nme.synchronized_, FINAL )(tps =>
672+ (Some (List (tps.head.typeConstructor)), tps.head.typeConstructor)
673+ )
678674 lazy val String_+ = newMethod(StringClass , nme.raw.PLUS , anyparam, stringtype, FINAL )
679675
680676 def Object_getClass = getMember(ObjectClass , nme.getClass_)
@@ -686,7 +682,6 @@ trait Definitions extends reflect.api.StandardDefinitions {
686682 def Object_hashCode = getMember(ObjectClass , nme.hashCode_)
687683 def Object_toString = getMember(ObjectClass , nme.toString_)
688684
689-
690685 // boxed classes
691686 lazy val ObjectRefClass = getRequiredClass(" scala.runtime.ObjectRef" )
692687 lazy val VolatileObjectRefClass = getRequiredClass(" scala.runtime.VolatileObjectRef" )
@@ -831,39 +826,36 @@ trait Definitions extends reflect.api.StandardDefinitions {
831826 */
832827 private def getModuleOrClass (path : Name ): Symbol = getModuleOrClass(path, path.length)
833828
834- private def newCovariantPolyClass (owner : Symbol , name : TypeName , parent : Symbol => Type ): Symbol = {
835- val clazz = newClass(owner, name, List ())
836- val tparam = newTypeParam(clazz, 0 ) setFlag COVARIANT
837- val p = parent(tparam)
838- /* p.typeSymbol.initialize
839- println(p.typeSymbol + " flags: " + Flags.flagsToString(p.typeSymbol.flags))
840- val parents = /* if (p.typeSymbol.isTrait)
841- List(definitions.AnyRefClass.tpe, p)
842- else*/ List(p)
843- println("creating " + name + " with parents " + parents) */
844- clazz.setInfo(
845- polyType(
846- List (tparam),
847- ClassInfoType (List (AnyRefClass .tpe, p), newScope, clazz)))
848- }
849-
850829 private def newAlias (owner : Symbol , name : TypeName , alias : Type ): Symbol =
851830 owner.newAliasType(name) setInfoAndEnter alias
852-
853- /** tcon receives the type parameter symbol as argument */
854- private def newPolyMethod (owner : Symbol , name : TermName , tcon : Symbol => Type ): Symbol =
855- newPolyMethodCon(owner, name, tparam => msym => tcon(tparam))
856-
857- /** tcon receives the type parameter symbol and the method symbol as arguments */
858- private def newPolyMethodCon (owner : Symbol , name : TermName , tcon : Symbol => Symbol => Type ): Symbol = {
859- val msym = owner.info.decls enter owner.newMethod(name.encode)
860- val tparam = newTypeParam(msym, 0 )
861-
862- msym setInfo polyType(List (tparam), tcon(tparam)(msym))
831+
832+ private def specialPolyClass (name : TypeName , flags : Long )(parentFn : Symbol => Type ): Symbol = {
833+ val clazz = newClass(ScalaPackageClass , name, Nil )
834+ val tparam = clazz.newSyntheticTypeParam(" T0" , flags)
835+ val parents = List (AnyRefClass .tpe, parentFn(tparam))
836+
837+ clazz setInfo polyType(List (tparam), ClassInfoType (parents, newScope, clazz))
863838 }
839+
840+ def newPolyMethod (typeParamCount : Int , owner : Symbol , name : TermName , flags : Long )(createFn : PolyMethodCreator ): Symbol = {
841+ val msym = owner.newMethod(name.encode, NoPosition , flags)
842+ val tparams = msym.newSyntheticTypeParams(typeParamCount)
843+ val mtpe = createFn(tparams) match {
844+ case (Some (formals), restpe) => MethodType (msym.newSyntheticValueParams(formals), restpe)
845+ case (_, restpe) => NullaryMethodType (restpe)
846+ }
864847
865- private def newTypeParam (owner : Symbol , index : Int ): Symbol =
866- owner.newTypeParameter(newTypeName(" T" + index)) setInfo TypeBounds .empty
848+ msym setInfoAndEnter polyType(tparams, mtpe)
849+ }
850+
851+ /** T1 means one type parameter.
852+ */
853+ def newT1NullaryMethod (owner : Symbol , name : TermName , flags : Long )(createFn : Symbol => Type ): Symbol = {
854+ newPolyMethod(1 , owner, name, flags)(tparams => (None , createFn(tparams.head)))
855+ }
856+ def newT1NoParamsMethod (owner : Symbol , name : TermName , flags : Long )(createFn : Symbol => Type ): Symbol = {
857+ newPolyMethod(1 , owner, name, flags)(tparams => (Some (Nil ), createFn(tparams.head)))
858+ }
867859
868860 lazy val boxedClassValues = boxedClass.values.toSet
869861 lazy val isUnbox = unboxMethod.values.toSet
0 commit comments