summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEugene Burmako <xeno.by@gmail.com>2012-07-02 10:59:01 +0200
committerEugene Burmako <xeno.by@gmail.com>2012-07-02 11:39:53 +0200
commitf5b0d7b42c73327ce2392f3e498a72cd652e2064 (patch)
tree8e57596d3160604c00e0666a4270f3c2f488e7c0 /src
parent0a9cea6ea58571deb67d60193d60d12be6bb0233 (diff)
downloadscala-f5b0d7b42c73327ce2392f3e498a72cd652e2064.tar.gz
scala-f5b0d7b42c73327ce2392f3e498a72cd652e2064.tar.bz2
scala-f5b0d7b42c73327ce2392f3e498a72cd652e2064.zip
better module classes support in the reflection API
Diffstat (limited to 'src')
-rw-r--r--src/library/scala/reflect/base/Base.scala15
-rw-r--r--src/library/scala/reflect/base/Symbols.scala8
-rw-r--r--src/library/scala/reflect/base/Types.scala5
-rw-r--r--src/reflect/scala/reflect/internal/Symbols.scala1
4 files changed, 23 insertions, 6 deletions
diff --git a/src/library/scala/reflect/base/Base.scala b/src/library/scala/reflect/base/Base.scala
index 490a9e8c03..e9d963dc78 100644
--- a/src/library/scala/reflect/base/Base.scala
+++ b/src/library/scala/reflect/base/Base.scala
@@ -23,7 +23,7 @@ class Base extends Universe { self =>
new TermSymbol(this, name, flags)
def newModuleAndClassSymbol(name: Name, pos: Position = NoPosition, flags: FlagSet = NoFlags): (ModuleSymbol, ClassSymbol) = {
- val c = newClassSymbol(name.toTypeName, pos, flags)
+ val c = new ModuleClassSymbol(this, name.toTypeName, flags)
val m = new ModuleSymbol(this, name.toTermName, flags, c)
(m, c)
}
@@ -77,6 +77,8 @@ class Base extends Universe { self =>
class ClassSymbol(owner: Symbol, name: TypeName, flags: FlagSet)
extends TypeSymbol(owner, name, flags) with ClassSymbolBase
+ class ModuleClassSymbol(owner: Symbol, name: TypeName, flags: FlagSet)
+ extends ClassSymbol(owner, name, flags) { override def isModuleClass = true }
implicit val ClassSymbolTag = ClassTag[ClassSymbol](classOf[ClassSymbol])
class FreeTermSymbol(owner: Symbol, name: TermName, flags: FlagSet)
@@ -93,7 +95,10 @@ class Base extends Universe { self =>
}
// todo. write a decent toString that doesn't crash on recursive types
- class Type extends TypeBase { def typeSymbol: Symbol = NoSymbol }
+ class Type extends TypeBase {
+ def typeSymbol: Symbol = NoSymbol
+ def termSymbol: Symbol = NoSymbol
+ }
implicit val TypeTagg = ClassTag[Type](classOf[Type])
val NoType = new Type
@@ -106,7 +111,7 @@ class Base extends Universe { self =>
object ThisType extends ThisTypeExtractor
implicit val ThisTypeTag = ClassTag[ThisType](classOf[ThisType])
- case class SingleType(pre: Type, sym: Symbol) extends SingletonType
+ case class SingleType(pre: Type, sym: Symbol) extends SingletonType { override val termSymbol = sym }
object SingleType extends SingleTypeExtractor
implicit val SingleTypeTag = ClassTag[SingleType](classOf[SingleType])
@@ -341,9 +346,9 @@ class Base extends Universe { self =>
class Mirror extends MirrorOf[self.type] {
val universe: self.type = self
- lazy val RootClass = new ClassSymbol(NoSymbol, tpnme.ROOT, NoFlags)
+ lazy val RootClass = new ClassSymbol(NoSymbol, tpnme.ROOT, NoFlags) { override def isModuleClass = true }
lazy val RootPackage = new ModuleSymbol(NoSymbol, nme.ROOT, NoFlags, RootClass)
- lazy val EmptyPackageClass = new ClassSymbol(RootClass, tpnme.EMPTY_PACKAGE_NAME, NoFlags)
+ lazy val EmptyPackageClass = new ClassSymbol(RootClass, tpnme.EMPTY_PACKAGE_NAME, NoFlags) { override def isModuleClass = true }
lazy val EmptyPackage = new ModuleSymbol(RootClass, nme.EMPTY_PACKAGE_NAME, NoFlags, EmptyPackageClass)
def staticClass(fullName: String): ClassSymbol =
diff --git a/src/library/scala/reflect/base/Symbols.scala b/src/library/scala/reflect/base/Symbols.scala
index 9404520073..ced1f33395 100644
--- a/src/library/scala/reflect/base/Symbols.scala
+++ b/src/library/scala/reflect/base/Symbols.scala
@@ -174,6 +174,12 @@ trait Symbols { self: Universe =>
*/
def isClass: Boolean = false
+ /** Does this symbol represent the definition of a class implicitly associated
+ * with an object definition (module class in scala compiler parlance).
+ * If yes, `isType` is also guaranteed to be true.
+ */
+ def isModuleClass: Boolean = false
+
/** This symbol cast to a ClassSymbol representing a class or trait.
* Returns ClassCastException if `isClass` is false.
*/
@@ -244,6 +250,8 @@ trait Symbols { self: Universe =>
/** The base API that all module symbols support */
trait ModuleSymbolBase extends TermSymbolBase { this: ModuleSymbol =>
/** The class implicitly associated with the object definition.
+ * One can go back from a module class to the associated module symbol
+ * by inspecting its `selfType.termSymbol`.
*/
def moduleClass: Symbol // needed for tree traversals
// [Eugene++] when this becomes `moduleClass: ClassSymbol`, it will be the happiest day in my life
diff --git a/src/library/scala/reflect/base/Types.scala b/src/library/scala/reflect/base/Types.scala
index 6106e3fde7..6e8ffc7984 100644
--- a/src/library/scala/reflect/base/Types.scala
+++ b/src/library/scala/reflect/base/Types.scala
@@ -6,6 +6,11 @@ trait Types { self: Universe =>
/** The base API that all types support */
abstract class TypeBase {
+ /** The term symbol associated with the type, or `NoSymbol` for types
+ * that do not refer to a term symbol.
+ */
+ def termSymbol: Symbol
+
/** The type symbol associated with the type, or `NoSymbol` for types
* that do not refer to a type symbol.
*/
diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala
index a3893a0236..b69accaa75 100644
--- a/src/reflect/scala/reflect/internal/Symbols.scala
+++ b/src/reflect/scala/reflect/internal/Symbols.scala
@@ -539,7 +539,6 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
def isConcreteClass = false
def isImplClass = false // the implementation class of a trait
def isJavaInterface = false
- def isModuleClass = false
def isNumericValueClass = false
def isPrimitiveValueClass = false
def isRefinementClass = false