summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2012-02-05 09:49:30 -0800
committerPaul Phillips <paulp@improving.org>2012-02-05 21:58:45 -0800
commit9d00ea8d389f4426f1f644e0a7f48e9ea380e9fc (patch)
treeda7f1c6a2fe12dcffe372b5165b19abc58947d61 /src/compiler
parent25c6d0a8bc23da696d76dd99ac670adb6eece2c3 (diff)
downloadscala-9d00ea8d389f4426f1f644e0a7f48e9ea380e9fc.tar.gz
scala-9d00ea8d389f4426f1f644e0a7f48e9ea380e9fc.tar.bz2
scala-9d00ea8d389f4426f1f644e0a7f48e9ea380e9fc.zip
Refining the reflection api.
In the pursuit of simplicity and consistency. - Method names like getType, getClass, and getValue are far too ambiguous, both internally and especially with java reflection names. Methods which accept or return scala symbols should not refer to them as "classes" in the reflection library. (We can live with the FooClass convention for naming the well-known symbols, it's names like "getClass" and "classToType" which are needlessly conflationary.) - Meaningless names like "subst" have to be expanded. - We should hew closely to the terms which are used by scala programmers wherever possible, thus using "thisType" to mean "C.this" can only beget confusion, given that "thisType" doesn't mean "this.type" but what is normally called the "self type." - It's either "enclosing" or "encl", not both, and similar consistency issues. - Eliminated getAnnotations. - Removed what I could get away with from the API; would like to push those which are presently justified as being "required for LiftCode" out of the core. - Changed a number of AnyRefs to Any both on general principles and because before long it may actually matter. - There are !!!s scattered all over this commit, mostly where I think the name could be better. - I think we should standardize on method names like "vmSignature, vmClass" etc. when we are talking about jvm (and ostensibly other vm) things. There are a bunch more places to make this distinction clear (e.g. Symbol's javaBinaryName, etc.) - There is a lot more I want to do on this and I don't know where the time will come from to do it. Review by @odersky, @scalamacros.
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/scala/reflect/internal/Definitions.scala3
-rw-r--r--src/compiler/scala/reflect/internal/Names.scala7
-rw-r--r--src/compiler/scala/reflect/internal/StdNames.scala2
-rw-r--r--src/compiler/scala/reflect/internal/Symbols.scala37
-rw-r--r--src/compiler/scala/reflect/internal/Trees.scala2
-rw-r--r--src/compiler/scala/reflect/internal/Types.scala1
-rw-r--r--src/compiler/scala/reflect/runtime/Mirror.scala14
-rw-r--r--src/compiler/scala/reflect/runtime/TreeBuildUtil.scala3
-rw-r--r--src/compiler/scala/tools/nsc/Global.scala2
-rw-r--r--src/compiler/scala/tools/nsc/ast/Reifiers.scala8
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala8
-rw-r--r--src/compiler/scala/tools/nsc/transform/Flatten.scala6
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Infer.scala4
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Macros.scala6
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala2
15 files changed, 60 insertions, 45 deletions
diff --git a/src/compiler/scala/reflect/internal/Definitions.scala b/src/compiler/scala/reflect/internal/Definitions.scala
index 6871822562..e05ac1087b 100644
--- a/src/compiler/scala/reflect/internal/Definitions.scala
+++ b/src/compiler/scala/reflect/internal/Definitions.scala
@@ -605,6 +605,9 @@ trait Definitions extends reflect.api.StandardDefinitions {
def ClassType(arg: Type) =
if (phase.erasedTypes || forMSIL) ClassClass.tpe
else appliedType(ClassClass.typeConstructor, List(arg))
+
+ def vmClassType(arg: Type): Type = ClassType(arg)
+ def vmSignature(sym: Symbol, info: Type): String = signature(info) // !!!
//
// .NET backend
diff --git a/src/compiler/scala/reflect/internal/Names.scala b/src/compiler/scala/reflect/internal/Names.scala
index 907b564d4c..e6ca4c49ba 100644
--- a/src/compiler/scala/reflect/internal/Names.scala
+++ b/src/compiler/scala/reflect/internal/Names.scala
@@ -387,6 +387,13 @@ trait Names extends api.Names {
* decode returns a String.
*/
+ /** !!! Duplicative but consistently named.
+ */
+ def decoded: String = decode
+ def encoded: String = "" + encode
+ // def decodedName: ThisNameType = newName(decoded)
+ def encodedName: ThisNameType = encode
+
/** Replace operator symbols by corresponding $op_name. */
def encode: ThisNameType = {
val str = toString
diff --git a/src/compiler/scala/reflect/internal/StdNames.scala b/src/compiler/scala/reflect/internal/StdNames.scala
index 045daa7eb1..a072a2eebe 100644
--- a/src/compiler/scala/reflect/internal/StdNames.scala
+++ b/src/compiler/scala/reflect/internal/StdNames.scala
@@ -370,7 +370,7 @@ trait StdNames extends NameManglers { self: SymbolTable =>
val self: NameType = "self"
val setAccessible: NameType = "setAccessible"
val setAnnotations: NameType = "setAnnotations"
- val setTypeSig: NameType = "setTypeSig"
+ val setTypeSignature: NameType = "setTypeSignature"
val synchronized_ : NameType = "synchronized"
val tail: NameType = "tail"
val thisModuleType: NameType = "thisModuleType"
diff --git a/src/compiler/scala/reflect/internal/Symbols.scala b/src/compiler/scala/reflect/internal/Symbols.scala
index b9ba269ee3..819d94f41a 100644
--- a/src/compiler/scala/reflect/internal/Symbols.scala
+++ b/src/compiler/scala/reflect/internal/Symbols.scala
@@ -61,13 +61,18 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
case n: TermName => newTermSymbol(n, pos, newFlags)
case n: TypeName => newTypeSymbol(n, pos, newFlags)
}
- def typeSig: Type = info
- def typeSigIn(site: Type): Type = site.memberInfo(this)
+ def enclosingClass: Symbol = enclClass
+ def enclosingMethod: Symbol = enclMethod
+ def thisPrefix: Type = thisType
+ def selfType: Type = typeOfThis
+ def typeSignature: Type = info
+ def typeSignatureIn(site: Type): Type = site memberInfo this
+
def asType: Type = tpe
def asTypeIn(site: Type): Type = site.memberType(this)
def asTypeConstructor: Type = typeConstructor
def setInternalFlags(flag: Long): this.type = { setFlag(flag); this }
- def setTypeSig(tpe: Type): this.type = { setInfo(tpe); this }
+ def setTypeSignature(tpe: Type): this.type = { setInfo(tpe); this }
def setAnnotations(annots: AnnotationInfo*): this.type = { setAnnotations(annots.toList); this }
}
@@ -103,12 +108,17 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
def pos = rawpos
def setPos(pos: Position): this.type = { this.rawpos = pos; this }
+ /** !!! The logic after "hasFlag" is far too opaque to be unexplained.
+ * I'm guessing it's attempting to compensate for flag overloading,
+ * and embedding such logic in an undocumented island like this is a
+ * notarized guarantee of future breakage.
+ */
override def hasModifier(mod: Modifier) =
hasFlag(flagOfModifier(mod)) &&
(!(mod == Modifier.bynameParameter) || isTerm) &&
(!(mod == Modifier.covariant) || isType)
- override def allModifiers: Set[Modifier] =
+ override def modifiers: Set[Modifier] =
Modifier.values filter hasModifier
// ------ creators -------------------------------------------------------------------
@@ -1271,14 +1281,11 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
/** After the typer phase (before, look at the definition's Modifiers), contains
* the annotations attached to member a definition (class, method, type, field).
*/
- def annotations: List[AnnotationInfo] = _annotations
+ def annotations: List[AnnotationInfo] = {
+ // Necessary for reflection, see SI-5423
+ if (inReflexiveMirror)
+ initialize
- /** This getter is necessary for reflection, see https://issues.scala-lang.org/browse/SI-5423
- * We could auto-inject completion into `annotations' and `setAnnotations', but I'm not sure about that
- * @odersky writes: I fear we can't do the forcing for all compiler symbols as that could introduce cycles
- */
- def getAnnotations: List[AnnotationInfo] = {
- initialize
_annotations
}
@@ -1572,10 +1579,10 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
else owner.logicallyEnclosingMember
/** The top-level class containing this symbol. */
- def toplevelClass: Symbol =
+ def enclosingTopLevelClass: Symbol =
if (owner.isPackageClass) {
if (isClass) this else moduleClass
- } else owner.toplevelClass
+ } else owner.enclosingTopLevelClass
/** Is this symbol defined in the same scope and compilation unit as `that` symbol? */
def isCoDefinedWith(that: Symbol) = (
@@ -1879,7 +1886,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
*/
def sourceFile: AbstractFileType =
if (isModule) moduleClass.sourceFile
- else toplevelClass.sourceFile
+ else enclosingTopLevelClass.sourceFile
def sourceFile_=(f: AbstractFileType) {
abort("sourceFile_= inapplicable for " + this)
@@ -2611,7 +2618,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
override def defString: String = toString
override def locationString: String = ""
override def enclClass: Symbol = this
- override def toplevelClass: Symbol = this
+ override def enclosingTopLevelClass: Symbol = this
override def enclMethod: Symbol = this
override def sourceFile: AbstractFileType = null
override def ownerChain: List[Symbol] = List()
diff --git a/src/compiler/scala/reflect/internal/Trees.scala b/src/compiler/scala/reflect/internal/Trees.scala
index f982c93656..6ce6a7fac0 100644
--- a/src/compiler/scala/reflect/internal/Trees.scala
+++ b/src/compiler/scala/reflect/internal/Trees.scala
@@ -74,7 +74,7 @@ trait Trees extends api.Trees { self: SymbolTable =>
override def hasModifier(mod: Modifier) =
hasFlag(flagOfModifier(mod))
- override def allModifiers: Set[Modifier] =
+ override def modifiers: Set[Modifier] =
Modifier.values filter hasModifier
override def mapAnnotations(f: List[Tree] => List[Tree]): Modifiers =
Modifiers(flags, privateWithin, f(annotations)) setPositions positions
diff --git a/src/compiler/scala/reflect/internal/Types.scala b/src/compiler/scala/reflect/internal/Types.scala
index 4e842c05da..cd44b700c1 100644
--- a/src/compiler/scala/reflect/internal/Types.scala
+++ b/src/compiler/scala/reflect/internal/Types.scala
@@ -261,6 +261,7 @@ trait Types extends api.Types { self: SymbolTable =>
def declarations = decls
def typeArguments = typeArgs
def erasedType = transformedType(this)
+ def substituteTypes(from: List[Symbol], to: List[Type]): Type = subst(from, to)
}
/** The base class for all types */
diff --git a/src/compiler/scala/reflect/runtime/Mirror.scala b/src/compiler/scala/reflect/runtime/Mirror.scala
index 4808326902..028a660a35 100644
--- a/src/compiler/scala/reflect/runtime/Mirror.scala
+++ b/src/compiler/scala/reflect/runtime/Mirror.scala
@@ -12,28 +12,28 @@ class Mirror extends Universe with RuntimeTypes with TreeBuildUtil with ToolBoxe
import definitions._
- def classWithName(name: String): Symbol = {
+ def symbolForName(name: String): Symbol = {
val clazz = javaClass(name, defaultReflectiveClassLoader())
classToScala(clazz)
}
- def getCompanionObject(clazz: Symbol): AnyRef = {
+ def companionInstance(clazz: Symbol): AnyRef = {
val singleton = ReflectionUtils.singletonInstance(clazz.fullName, defaultReflectiveClassLoader())
singleton
}
- def getClass(obj: AnyRef): Symbol = classToScala(obj.getClass)
- def getType(obj: AnyRef): Type = typeToScala(obj.getClass)
+ def symbolOfInstance(obj: Any): Symbol = classToScala(obj.getClass)
+ def typeOfInstance(obj: Any): Type = typeToScala(obj.getClass)
// to do add getClass/getType for instances of primitive types, probably like this:
// def getClass[T <: AnyVal : Manifest](x: T): Symbol = manifest[T].getClass
- def getValue(receiver: AnyRef, field: Symbol): Any = {
+ def getValueOfField(receiver: AnyRef, field: Symbol): Any = {
fieldToJava(field).get(receiver)
}
- def setValue(receiver: AnyRef, field: Symbol, value: Any): Unit = {
+ def setValueOfField(receiver: AnyRef, field: Symbol, value: Any): Unit = {
fieldToJava(field).set(receiver, value)
}
- def invoke(receiver: AnyRef, meth: Symbol, args: Any*): Any = {
+ def invoke(receiver: AnyRef, meth: Symbol)(args: Any*): Any = {
if (meth.owner == ArrayClass) {
meth.name match {
case nme.length => return Array.getLength(receiver)
diff --git a/src/compiler/scala/reflect/runtime/TreeBuildUtil.scala b/src/compiler/scala/reflect/runtime/TreeBuildUtil.scala
index fc4177e956..275c85f332 100644
--- a/src/compiler/scala/reflect/runtime/TreeBuildUtil.scala
+++ b/src/compiler/scala/reflect/runtime/TreeBuildUtil.scala
@@ -2,7 +2,6 @@ package scala.reflect
package runtime
trait TreeBuildUtil extends Universe with api.TreeBuildUtil {
-
def staticClass(fullname: String): Symbol = definitions.getRequiredClass(fullname)
def staticModule(fullname: String): Symbol = definitions.getRequiredModule(fullname)
def thisModuleType(fullname: String) = staticModule(fullname).moduleClass.thisType
@@ -39,7 +38,7 @@ trait TreeBuildUtil extends Universe with api.TreeBuildUtil {
selectIn(owner.info, idx)
}
- def freeVar(name: String, info: Type, value: Any) = newFreeVar(newTermName(name), info, value)
+ def newFreeVar(name: String, info: Type, value: Any) = newFreeVar(newTermName(name), info, value)
def modifiersFromInternalFlags(flags: Long, privateWithin: Name, annotations: List[Tree]): Modifiers =
Modifiers(flags, privateWithin, annotations)
diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala
index d4152dffdc..18735cafe2 100644
--- a/src/compiler/scala/tools/nsc/Global.scala
+++ b/src/compiler/scala/tools/nsc/Global.scala
@@ -1076,7 +1076,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb
def compiles(sym: Symbol): Boolean =
if (sym == NoSymbol) false
else if (symSource.isDefinedAt(sym)) true
- else if (!sym.owner.isPackageClass) compiles(sym.toplevelClass)
+ else if (!sym.owner.isPackageClass) compiles(sym.enclosingTopLevelClass)
else if (sym.isModuleClass) compiles(sym.sourceModule)
else false
diff --git a/src/compiler/scala/tools/nsc/ast/Reifiers.scala b/src/compiler/scala/tools/nsc/ast/Reifiers.scala
index ef87925959..ac6c8c4c77 100644
--- a/src/compiler/scala/tools/nsc/ast/Reifiers.scala
+++ b/src/compiler/scala/tools/nsc/ast/Reifiers.scala
@@ -160,8 +160,6 @@ trait Reifiers { self: Global =>
mirrorSelect("definitions.RootClass")
else if (sym == EmptyPackage)
mirrorSelect("definitions.EmptyPackage")
- else if (sym == EmptyPackageClass)
- mirrorSelect("definitions.EmptyPackageClass")
else if (sym.isModuleClass)
Select(reifySymRef(sym.sourceModule), "moduleClass")
else if (sym.isStatic && sym.isClass)
@@ -190,7 +188,7 @@ trait Reifiers { self: Global =>
val symtpe = lambdaLift.boxIfCaptured(sym, sym.tpe, erasedTypes = false)
def markIfCaptured(arg: Ident): Tree =
if (sym.isCapturedVariable) referenceCapturedVariable(arg) else arg
- mirrorCall("freeVar", reify(sym.name.toString), reify(symtpe), markIfCaptured(Ident(sym)))
+ mirrorCall("newFreeVar", reify(sym.name.toString), reify(symtpe), markIfCaptured(Ident(sym)))
} else {
if (reifyDebug) println("Late local: " + sym)
registerReifiableSymbol(sym)
@@ -218,7 +216,7 @@ trait Reifiers { self: Global =>
* Generate code to add type and annotation info to a reified symbol
*/
private def fillInSymbol(sym: Symbol): Tree = {
- val rset = Apply(Select(reifySymRef(sym), nme.setTypeSig), List(reifyType(sym.info)))
+ val rset = Apply(Select(reifySymRef(sym), nme.setTypeSignature), List(reifyType(sym.info)))
if (sym.annotations.isEmpty) rset
else Apply(Select(rset, nme.setAnnotations), List(reify(sym.annotations)))
}
@@ -335,7 +333,7 @@ trait Reifiers { self: Global =>
val sym = tree.symbol
if (reifyDebug) println("This for %s, reified as freeVar".format(sym))
if (reifyDebug) println("Free: " + sym)
- val freeVar = mirrorCall("freeVar", reify(sym.name.toString), reify(sym.tpe), This(sym))
+ val freeVar = mirrorCall("newFreeVar", reify(sym.name.toString), reify(sym.tpe), This(sym))
mirrorCall(nme.Ident, freeVar)
case This(_) =>
if (reifyDebug) println("This for %s, reified as This".format(tree.symbol))
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
index 9c0670e981..a8083d7a2d 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
@@ -1269,13 +1269,13 @@ abstract class ClassfileParser {
if ((jflags & (JAVA_ACC_PRIVATE | JAVA_ACC_PROTECTED | JAVA_ACC_PUBLIC)) == 0)
// See ticket #1687 for an example of when topLevelClass is NoSymbol: it
// apparently occurs when processing v45.3 bytecode.
- if (sym.toplevelClass != NoSymbol)
- sym.privateWithin = sym.toplevelClass.owner
+ if (sym.enclosingTopLevelClass != NoSymbol)
+ sym.privateWithin = sym.enclosingTopLevelClass.owner
// protected in java means package protected. #3946
if ((jflags & JAVA_ACC_PROTECTED) != 0)
- if (sym.toplevelClass != NoSymbol)
- sym.privateWithin = sym.toplevelClass.owner
+ if (sym.enclosingTopLevelClass != NoSymbol)
+ sym.privateWithin = sym.enclosingTopLevelClass.owner
}
@inline private def isPrivate(flags: Int) = (flags & JAVA_ACC_PRIVATE) != 0
diff --git a/src/compiler/scala/tools/nsc/transform/Flatten.scala b/src/compiler/scala/tools/nsc/transform/Flatten.scala
index 4fa5b52de3..89f1cc26e0 100644
--- a/src/compiler/scala/tools/nsc/transform/Flatten.scala
+++ b/src/compiler/scala/tools/nsc/transform/Flatten.scala
@@ -60,8 +60,8 @@ abstract class Flatten extends InfoTransform {
private val flattened = new TypeMap {
def apply(tp: Type): Type = tp match {
case TypeRef(pre, sym, args) if isFlattenablePrefix(pre) =>
- assert(args.isEmpty && sym.toplevelClass != NoSymbol, sym.ownerChain)
- typeRef(sym.toplevelClass.owner.thisType, sym, Nil)
+ assert(args.isEmpty && sym.enclosingTopLevelClass != NoSymbol, sym.ownerChain)
+ typeRef(sym.enclosingTopLevelClass.owner.thisType, sym, Nil)
case ClassInfoType(parents, decls, clazz) =>
var parents1 = parents
val decls1 = scopeTransform(clazz) {
@@ -119,7 +119,7 @@ abstract class Flatten extends InfoTransform {
val sym = tree.symbol
val tree1 = tree match {
case ClassDef(_, _, _, _) if sym.isNestedClass =>
- liftedDefs(sym.toplevelClass.owner) += tree
+ liftedDefs(sym.enclosingTopLevelClass.owner) += tree
EmptyTree
case Select(qual, name) if (sym.isStaticModule && !sym.owner.isPackageClass) =>
atPhase(phase.next) {
diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
index e8c03aff66..b97fbebec2 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
@@ -228,9 +228,9 @@ trait Infer {
if (sym.isError) {
tree setSymbol sym setType ErrorType
} else {
- val topClass = context.owner.toplevelClass
+ val topClass = context.owner.enclosingTopLevelClass
if (context.unit.exists)
- context.unit.depends += sym.toplevelClass
+ context.unit.depends += sym.enclosingTopLevelClass
var sym1 = sym filter (alt => context.isAccessible(alt, pre, site.isInstanceOf[Super]))
// Console.println("check acc " + (sym, sym1) + ":" + (sym.tpe, sym1.tpe) + " from " + pre);//DEBUG
diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala
index 4c790bfc34..b2ee36ee11 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala
@@ -106,11 +106,11 @@ trait Macros { self: Analyzer =>
val mmeth = macroMeth(mac)
if (mmeth == NoSymbol) None
else {
- val receiverClass: mirror.Symbol = mirror.classWithName(mmeth.owner.fullName)
+ val receiverClass: mirror.Symbol = mirror.symbolForName(mmeth.owner.fullName)
val receiverObj = receiverClass.companionModule
if (receiverObj == mirror.NoSymbol) None
else {
- val receiver = mirror.getCompanionObject(receiverClass)
+ val receiver = mirror.companionInstance(receiverClass)
val rmeth = receiverObj.info.member(mirror.newTermName(mmeth.name.toString))
if (rmeth == mirror.NoSymbol) None
else {
@@ -140,7 +140,7 @@ trait Macros { self: Analyzer =>
}
val rawArgs: Seq[Any] = rawArgss.flatten
try {
- Some(mirror.invoke(receiver, rmeth, rawArgs: _*))
+ Some(mirror.invoke(receiver, rmeth)(rawArgs: _*))
} catch {
case ex =>
val realex = ReflectionUtils.unwrapThrowable(ex)
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index eb0bed035c..bc8a8a31b5 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -3714,7 +3714,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
return typed(treeCopy.Select(tree, qual1, name), mode, pt)
}
if (!reallyExists(sym)) {
- if (context.owner.toplevelClass.isJavaDefined && name.isTypeName) {
+ if (context.owner.enclosingTopLevelClass.isJavaDefined && name.isTypeName) {
val tree1 = atPos(tree.pos) { gen.convertToSelectFromType(qual, name) }
if (tree1 != EmptyTree) return typed1(tree1, mode, pt)
}