summaryrefslogtreecommitdiff
path: root/src/reflect
diff options
context:
space:
mode:
authorEugene Burmako <xeno.by@gmail.com>2013-05-28 09:04:09 +0200
committerEugene Burmako <xeno.by@gmail.com>2013-06-07 22:32:10 +0200
commita45d3e5658a1ccb57d3b420eb36d84f7170404b5 (patch)
treefb1661e2aa3bb0aced3c102d287def59d6654371 /src/reflect
parentee646e9c84290e721c4ee9fe6247d4b95840e871 (diff)
downloadscala-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/reflect')
-rw-r--r--src/reflect/scala/reflect/internal/Definitions.scala48
-rw-r--r--src/reflect/scala/reflect/internal/Types.scala38
2 files changed, 47 insertions, 39 deletions
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)
*/