summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugene Burmako <xeno.by@gmail.com>2014-01-28 18:21:21 +0300
committerEugene Burmako <xeno.by@gmail.com>2014-02-14 14:16:44 +0100
commitbe22698fa2c1cf368efc8d2cf0f63100c6d0afdc (patch)
treebca11260a7dc1a6dc79df93ccd73bc38fc5dc4be
parentd2365235b6b4252724c43addc7d867c35d558a39 (diff)
downloadscala-be22698fa2c1cf368efc8d2cf0f63100c6d0afdc.tar.gz
scala-be22698fa2c1cf368efc8d2cf0f63100c6d0afdc.tar.bz2
scala-be22698fa2c1cf368efc8d2cf0f63100c6d0afdc.zip
adds Type.companionType
Introduces a dedicated facility to go from a type to a type of its companion. Previously we had to do something really horrible for that, something like: tp.typeSymbol.companionSymbol.typeSignature.
-rw-r--r--src/reflect/scala/reflect/api/Types.scala5
-rw-r--r--src/reflect/scala/reflect/internal/Types.scala8
-rw-r--r--test/files/run/reflection-companiontype.check12
-rw-r--r--test/files/run/reflection-companiontype.scala22
4 files changed, 47 insertions, 0 deletions
diff --git a/src/reflect/scala/reflect/api/Types.scala b/src/reflect/scala/reflect/api/Types.scala
index 9e868c2b34..2900b7ab3d 100644
--- a/src/reflect/scala/reflect/api/Types.scala
+++ b/src/reflect/scala/reflect/api/Types.scala
@@ -121,6 +121,11 @@ trait Types {
*/
def members: MemberScope
+ /** Type signature of the companion of the underlying class symbol.
+ * NoType if the underlying symbol is not a class symbol, or if it doesn't have a companion.
+ */
+ def companionType: Type
+
/** Is this type a type constructor that is missing its type arguments?
*/
def takesTypeArgs: Boolean
diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala
index ca99b1af74..19dced5594 100644
--- a/src/reflect/scala/reflect/internal/Types.scala
+++ b/src/reflect/scala/reflect/internal/Types.scala
@@ -243,6 +243,14 @@ trait Types
def isSpliceable = {
this.isInstanceOf[TypeRef] && typeSymbol.isAbstractType && !typeSymbol.isExistential
}
+
+ def companionType = {
+ val sym = typeSymbolDirect
+ if (sym.isModule && !sym.isPackage) sym.companionSymbol.tpe
+ else if (sym.isModuleClass && !sym.isPackageClass) sym.sourceModule.companionSymbol.tpe
+ else if (sym.isClass && !sym.isModuleClass && !sym.isPackageClass) sym.companionSymbol.info
+ else NoType
+ }
}
/** The base class for all types */
diff --git a/test/files/run/reflection-companiontype.check b/test/files/run/reflection-companiontype.check
new file mode 100644
index 0000000000..e25605618f
--- /dev/null
+++ b/test/files/run/reflection-companiontype.check
@@ -0,0 +1,12 @@
+TypeRefs
+TypeRef(ThisType(<empty>#PK), C#MODC, List())
+TypeRef(ThisType(<empty>#PK), C#CLS, List())
+TypeRef(ThisType(<empty>#PK), C#CLS, List())
+ClassInfoTypes
+TypeRef(ThisType(<empty>#PK), C#MODC, List())
+TypeRef(ThisType(<empty>#PK), C#CLS, List())
+TypeRef(ThisType(<empty>#PK), C#CLS, List())
+Unrelated
+NoType
+NoType
+NoType
diff --git a/test/files/run/reflection-companiontype.scala b/test/files/run/reflection-companiontype.scala
new file mode 100644
index 0000000000..72c0444a70
--- /dev/null
+++ b/test/files/run/reflection-companiontype.scala
@@ -0,0 +1,22 @@
+import scala.reflect.runtime.universe._
+import scala.reflect.runtime.{currentMirror => cm}
+
+class C
+object C
+
+object Test extends App {
+ type T = C
+
+ println("TypeRefs")
+ println(showRaw(typeOf[C].companionType, printKinds = true))
+ println(showRaw(typeOf[C].companionType.companionType, printKinds = true))
+ println(showRaw(typeOf[C.type].companionType, printKinds = true))
+ println("ClassInfoTypes")
+ println(showRaw(typeOf[C].typeSymbol.typeSignature.companionType, printKinds = true))
+ println(showRaw(typeOf[C].typeSymbol.typeSignature.companionType.typeSymbol.typeSignature.companionType, printKinds = true))
+ println(showRaw(typeOf[C.type].typeSymbol.typeSignature.companionType, printKinds = true))
+ println("Unrelated")
+ println(showRaw(typeOf[T].companionType, printKinds = true))
+ println(showRaw(cm.staticPackage("scala").moduleClass.asType.toType.companionType, printKinds = true))
+ println(showRaw(cm.staticPackage("scala").typeSignature.companionType, printKinds = true))
+} \ No newline at end of file