diff options
author | Eugene Burmako <xeno.by@gmail.com> | 2013-05-28 09:04:09 +0200 |
---|---|---|
committer | Eugene Burmako <xeno.by@gmail.com> | 2013-06-07 22:32:10 +0200 |
commit | a45d3e5658a1ccb57d3b420eb36d84f7170404b5 (patch) | |
tree | fb1661e2aa3bb0aced3c102d287def59d6654371 /src | |
parent | ee646e9c84290e721c4ee9fe6247d4b95840e871 (diff) | |
download | scala-a45d3e5658a1ccb57d3b420eb36d84f7170404b5.tar.gz scala-a45d3e5658a1ccb57d3b420eb36d84f7170404b5.tar.bz2 scala-a45d3e5658a1ccb57d3b420eb36d84f7170404b5.zip |
unifies handling of T's in various analyses of Foo[T]'s
Diffstat (limited to 'src')
-rw-r--r-- | src/compiler/scala/reflect/macros/util/Helpers.scala | 6 | ||||
-rw-r--r-- | src/reflect/scala/reflect/internal/Definitions.scala | 48 | ||||
-rw-r--r-- | src/reflect/scala/reflect/internal/Types.scala | 38 |
3 files changed, 50 insertions, 42 deletions
diff --git a/src/compiler/scala/reflect/macros/util/Helpers.scala b/src/compiler/scala/reflect/macros/util/Helpers.scala index ada8efa833..9b7680717e 100644 --- a/src/compiler/scala/reflect/macros/util/Helpers.scala +++ b/src/compiler/scala/reflect/macros/util/Helpers.scala @@ -54,7 +54,7 @@ trait Helpers { * * @see Metalevels.scala for more information and examples about metalevels */ - def increaseMetalevel(pre: Type, tp: Type): Type = dealiasAndRewrap(tp) { + def increaseMetalevel(pre: Type, tp: Type): Type = transparentShallowTransform(RepeatedParamClass, tp) { case tp => typeRef(pre, MacroContextExprClass, List(tp)) } @@ -64,8 +64,8 @@ trait Helpers { * * @see Metalevels.scala for more information and examples about metalevels */ - def decreaseMetalevel(tp: Type): Type = dealiasAndRewrap(tp) { + def decreaseMetalevel(tp: Type): Type = transparentShallowTransform(RepeatedParamClass, tp) { case ExprClassOf(runtimeType) => runtimeType - case _ => AnyClass.tpe // so that macro impls with rhs = ??? don't screw up our inference + case _ => AnyTpe // so that macro impls with rhs = ??? don't screw up our inference } }
\ No newline at end of file diff --git a/src/reflect/scala/reflect/internal/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala index 1b46d9e00b..5892053b5e 100644 --- a/src/reflect/scala/reflect/internal/Definitions.scala +++ b/src/reflect/scala/reflect/internal/Definitions.scala @@ -407,10 +407,6 @@ trait Definitions extends api.StandardDefinitions { lazy val JavaRepeatedParamClass = specialPolyClass(tpnme.JAVA_REPEATED_PARAM_CLASS_NAME, COVARIANT)(tparam => arrayType(tparam.tpe)) lazy val RepeatedParamClass = specialPolyClass(tpnme.REPEATED_PARAM_CLASS_NAME, COVARIANT)(tparam => seqType(tparam.tpe)) - def dropByName(tp: Type): Type = tp match { - case TypeRef(_, ByNameParamClass, arg :: Nil) => arg - case _ => tp - } def isByNameParamType(tp: Type) = tp.typeSymbol == ByNameParamClass def isScalaRepeatedParamType(tp: Type) = tp.typeSymbol == RepeatedParamClass def isJavaRepeatedParamType(tp: Type) = tp.typeSymbol == JavaRepeatedParamClass @@ -431,29 +427,15 @@ trait Definitions extends api.StandardDefinitions { case _ => false } - def repeatedToSingle(tp: Type): Type = tp match { - case TypeRef(_, RepeatedParamClass, arg :: Nil) => arg - case _ => tp - } - - def repeatedToSeq(tp: Type): Type = (tp baseType RepeatedParamClass) match { - case TypeRef(_, RepeatedParamClass, arg :: Nil) => seqType(arg) - case _ => tp - } - - def seqToRepeated(tp: Type): Type = (tp baseType SeqClass) match { - case TypeRef(_, SeqClass, arg :: Nil) => scalaRepeatedType(arg) - case _ => tp - } - - def isReferenceArray(tp: Type) = tp match { - case TypeRef(_, ArrayClass, arg :: Nil) => arg <:< AnyRefTpe - case _ => false - } - def isArrayOfSymbol(tp: Type, elem: Symbol) = tp match { - case TypeRef(_, ArrayClass, arg :: Nil) => arg.typeSymbol == elem - case _ => false - } + // wrapping and unwrapping + def dropByName(tp: Type): Type = elementExtract(ByNameParamClass, tp) orElse tp + def repeatedToSingle(tp: Type): Type = elementExtract(RepeatedParamClass, tp) orElse tp + def repeatedToSeq(tp: Type): Type = elementTransform(RepeatedParamClass, tp)(seqType) orElse tp + def seqToRepeated(tp: Type): Type = elementTransform(SeqClass, tp)(scalaRepeatedType) orElse tp + def isReferenceArray(tp: Type) = elementTest(ArrayClass, tp)(_ <:< AnyRefTpe) + def isArrayOfSymbol(tp: Type, elem: Symbol) = elementTest(ArrayClass, tp)(_.typeSymbol == elem) + def elementType(container: Symbol, tp: Type): Type = elementExtract(container, tp) + object ExprClassOf { def unapply(tp: Type): Option[Type] = elementExtractOption(ExprClass, tp) } // collections classes lazy val ConsClass = requiredClass[scala.collection.immutable.::[_]] @@ -512,13 +494,6 @@ trait Definitions extends api.StandardDefinitions { lazy val ExprClass = ExprsClass.map(sym => getMemberClass(sym, tpnme.Expr)) def ExprSplice = ExprClass.map(sym => getMemberMethod(sym, nme.splice)) def ExprValue = ExprClass.map(sym => getMemberMethod(sym, nme.value)) - object ExprClassOf { - def unapply(tpe: Type): Option[Type] = tpe.dealias match { - case ExistentialType(_, underlying) => unapply(underlying) - case TypeRef(_, ExprClass, t :: Nil) => Some(t) - case _ => None - } - } lazy val ClassTagModule = requiredModule[scala.reflect.ClassTag[_]] lazy val ClassTagClass = requiredClass[scala.reflect.ClassTag[_]] @@ -707,11 +682,6 @@ trait Definitions extends api.StandardDefinitions { (sym eq PartialFunctionClass) || (sym eq AbstractPartialFunctionClass) } - def elementType(container: Symbol, tp: Type): Type = tp match { - case TypeRef(_, `container`, arg :: Nil) => arg - case _ => NoType - } - def arrayType(arg: Type) = appliedType(ArrayClass, arg) def byNameType(arg: Type) = appliedType(ByNameParamClass, arg) def iteratorOfType(tp: Type) = appliedType(IteratorClass, tp) diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala index 00a929003e..f27e6c979a 100644 --- a/src/reflect/scala/reflect/internal/Types.scala +++ b/src/reflect/scala/reflect/internal/Types.scala @@ -2436,6 +2436,7 @@ trait Types else super.prefixString ) + def copy(pre: Type = this.pre, sym: Symbol = this.sym, args: List[Type] = this.args) = TypeRef(pre, sym, args) override def kind = "TypeRef" } @@ -3700,6 +3701,43 @@ trait Types object unwrapToStableClass extends ClassUnwrapper(existential = false) { } object unwrapWrapperTypes extends TypeUnwrapper(true, true, true, true) { } + def elementExtract(container: Symbol, tp: Type): Type = { + assert(!container.isAliasType, container) + unwrapWrapperTypes(tp baseType container).dealiasWiden match { + case TypeRef(_, `container`, arg :: Nil) => arg + case _ => NoType + } + } + def elementExtractOption(container: Symbol, tp: Type): Option[Type] = { + elementExtract(container, tp) match { + case NoType => None + case tp => Some(tp) + } + } + def elementTest(container: Symbol, tp: Type)(f: Type => Boolean): Boolean = { + elementExtract(container, tp) match { + case NoType => false + case tp => f(tp) + } + } + def elementTransform(container: Symbol, tp: Type)(f: Type => Type): Type = { + elementExtract(container, tp) match { + case NoType => NoType + case tp => f(tp) + } + } + + def transparentShallowTransform(container: Symbol, tp: Type)(f: Type => Type): Type = { + def loop(tp: Type): Type = tp match { + case tp @ AnnotatedType(_, underlying, _) => tp.copy(underlying = loop(underlying)) + case tp @ ExistentialType(_, underlying) => tp.copy(underlying = loop(underlying)) + case tp @ PolyType(_, resultType) => tp.copy(resultType = loop(resultType)) + case tp @ NullaryMethodType(resultType) => tp.copy(resultType = loop(resultType)) + case tp => elementTransform(container, tp)(el => appliedType(container, f(el))).orElse(f(tp)) + } + loop(tp) + } + /** Repack existential types, otherwise they sometimes get unpacked in the * wrong location (type inference comes up with an unexpected skolem) */ |