summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2012-04-22 05:46:50 -0700
committerPaul Phillips <paulp@improving.org>2012-04-22 06:12:23 -0700
commit8c95273b70288e4e3a547fa43f2dbdb40a71b9ea (patch)
tree214e7cb1fb5655f002a58ae8b6b3a60e53e50817 /src/compiler/scala/tools
parent3c9c18ddccc17c2b0e62195315ba2abb72d3b761 (diff)
downloadscala-8c95273b70288e4e3a547fa43f2dbdb40a71b9ea.tar.gz
scala-8c95273b70288e4e3a547fa43f2dbdb40a71b9ea.tar.bz2
scala-8c95273b70288e4e3a547fa43f2dbdb40a71b9ea.zip
Reflection and reification: Names and Symbols.
- Consolidating many islands of name organization. Folds NameManglers into StdNames. Brings more of the string constants together with similar constants. Move name manipulation methods which produce TypeNames into object tpnme rather than nme. - Starting on MethodSymbolApi, ClassSymbolApi, etc so we can put sensible methods on sensible entities. This pushed into Definitions, where I pulled a whole bunch out of the api side (or at least marked my intention to do so -- too many tests use them to make them easy to remove) and on the compiler side, returned something more specific than Symbol a bunch of places. - Added a number of conveniences to Definitions to make it easier to get properly typed symbols. Note: one way in which you might notice having better typed Symbols is with Sets, which have the annoying property of inferring a type based on what they've been constructed with and then hard failing when you test for the presence of a more general type. So this: val mySet = Set(a, b) println(mySet(c)) ..goes from compiling to not compiling if a and b receive more specific types (e.g. they are MethodSymbols) and c is a Symbol or ClassSymbol or whatever. This is easily remedied on a site-by-site basis - create Set[Symbol](...) not Set(...) - but is an interesting and unfortunate consequence of type inference married to invariance. The changes to DummyMirror where things became ??? were driven by the need to lower its tax; type "Nothing" is a lot more forgiving about changes than is any specific symbol type.
Diffstat (limited to 'src/compiler/scala/tools')
-rw-r--r--src/compiler/scala/tools/nsc/Global.scala2
-rwxr-xr-xsrc/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala13
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala2
-rw-r--r--src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala4
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/IMain.scala11
-rw-r--r--src/compiler/scala/tools/nsc/matching/MatchSupport.scala2
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/AddInterfaces.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/LambdaLift.scala4
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Implicits.scala59
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala2
12 files changed, 52 insertions, 53 deletions
diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala
index 6c038162b3..cf024ebacf 100644
--- a/src/compiler/scala/tools/nsc/Global.scala
+++ b/src/compiler/scala/tools/nsc/Global.scala
@@ -1531,7 +1531,7 @@ class Global(var currentSettings: Settings, var reporter: NscReporter) extends S
/** We resolve the class/object ambiguity by passing a type/term name.
*/
def showDef(fullName: Name, declsOnly: Boolean, ph: Phase) = {
- val boringOwners = Set(definitions.AnyClass, definitions.AnyRefClass, definitions.ObjectClass)
+ val boringOwners = Set[Symbol](definitions.AnyClass, definitions.AnyRefClass, definitions.ObjectClass)
def phased[T](body: => T): T = afterPhase(ph)(body)
def boringMember(sym: Symbol) = boringOwners(sym.owner)
def symString(sym: Symbol) = if (sym.isTerm) sym.defString else sym.toString
diff --git a/src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala b/src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala
index 0f2a3e0395..b0204c5971 100755
--- a/src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala
@@ -30,7 +30,7 @@ abstract class SymbolicXMLBuilder(p: Parsers#Parser, preserveWS: Boolean) {
private[parser] var isPattern: Boolean = _
- private trait XMLTypeNames extends TypeNames {
+ private object xmltypes extends TypeNames {
val _Comment: NameType = "Comment"
val _Elem: NameType = "Elem"
val _EntityRef: NameType = "EntityRef"
@@ -45,7 +45,7 @@ abstract class SymbolicXMLBuilder(p: Parsers#Parser, preserveWS: Boolean) {
val _UnprefixedAttribute: NameType = "UnprefixedAttribute"
}
- private trait XMLTermNames extends TermNames {
+ private object xmlterms extends TermNames {
val _Null: NameType = "Null"
val __Elem: NameType = "Elem"
val __Text: NameType = "Text"
@@ -57,15 +57,6 @@ abstract class SymbolicXMLBuilder(p: Parsers#Parser, preserveWS: Boolean) {
val _xml: NameType = "xml"
}
- private object xmltypes extends XMLTypeNames {
- type NameType = TypeName
- implicit def createNameType(name: String): TypeName = newTypeNameCached(name)
- }
- private object xmlterms extends XMLTermNames {
- type NameType = TermName
- implicit def createNameType(name: String): TermName = newTermNameCached(name)
- }
-
import xmltypes.{_Comment, _Elem, _EntityRef, _Group, _MetaData, _NamespaceBinding, _NodeBuffer,
_PrefixedAttribute, _ProcInstr, _Text, _Unparsed, _UnprefixedAttribute}
diff --git a/src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala b/src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala
index f61f78ebb2..1ec2cf017a 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala
@@ -420,7 +420,7 @@ trait TypeKinds { self: ICodes =>
// between "object PackratParsers$class" and "trait PackratParsers"
if (sym.isImplClass) {
// pos/spec-List.scala is the sole failure if we don't check for NoSymbol
- val traitSym = sym.owner.info.decl(nme.interfaceName(sym.name))
+ val traitSym = sym.owner.info.decl(tpnme.interfaceName(sym.name))
if (traitSym != NoSymbol)
return REFERENCE(traitSym)
}
diff --git a/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala b/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala
index 124a7509e8..a6728654cd 100644
--- a/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala
+++ b/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala
@@ -42,7 +42,7 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
memberSym.isOmittablePrefix || (closestPackage(memberSym) == closestPackage(templateSym))
}
- private lazy val noSubclassCache = Set(AnyClass, AnyRefClass, ObjectClass)
+ private lazy val noSubclassCache = Set[Symbol](AnyClass, AnyRefClass, ObjectClass)
/** */
def makeModel: Option[Universe] = {
@@ -675,7 +675,7 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
}
/* Refined types */
case RefinedType(parents, defs) =>
- val ignoreParents = Set(AnyClass, ObjectClass)
+ val ignoreParents = Set[Symbol](AnyClass, ObjectClass)
val filtParents = parents filterNot (x => ignoreParents(x.typeSymbol)) match {
case Nil => parents
case ps => ps
diff --git a/src/compiler/scala/tools/nsc/interpreter/IMain.scala b/src/compiler/scala/tools/nsc/interpreter/IMain.scala
index 13124e6afc..e0a98ace9d 100644
--- a/src/compiler/scala/tools/nsc/interpreter/IMain.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/IMain.scala
@@ -197,8 +197,9 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends
import global._
import definitions.{
- ScalaPackage, JavaLangPackage, PredefModule, RootClass,
- getClassIfDefined, getModuleIfDefined, getRequiredModule, getRequiredClass
+ ScalaPackage, JavaLangPackage, RootClass,
+ getClassIfDefined, getModuleIfDefined, getRequiredModule, getRequiredClass,
+ termMember, typeMember
}
private implicit def privateTreeOps(t: Tree): List[Tree] = {
@@ -807,9 +808,9 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends
*/
def resolvePathToSymbol(accessPath: String): Symbol = {
val readRoot = getRequiredModule(readPath) // the outermost wrapper
- (accessPath split '.').foldLeft(readRoot) { (sym, name) =>
- if (name == "") sym else
- afterTyper(sym.info member newTermName(name))
+ (accessPath split '.').foldLeft(readRoot: Symbol) {
+ case (sym, "") => sym
+ case (sym, name) => afterTyper(termMember(sym, name))
}
}
/** We get a bunch of repeated warnings for reasons I haven't
diff --git a/src/compiler/scala/tools/nsc/matching/MatchSupport.scala b/src/compiler/scala/tools/nsc/matching/MatchSupport.scala
index 249f754e8f..72e6f32af1 100644
--- a/src/compiler/scala/tools/nsc/matching/MatchSupport.scala
+++ b/src/compiler/scala/tools/nsc/matching/MatchSupport.scala
@@ -31,7 +31,7 @@ trait MatchSupport extends ast.TreeDSL { self: ParallelMatching =>
object Types {
import definitions._
- val subrangeTypes = Set(ByteClass, ShortClass, CharClass, IntClass)
+ val subrangeTypes = Set[Symbol](ByteClass, ShortClass, CharClass, IntClass)
implicit class RichType(undecodedTpe: Type) {
def tpe = decodedEqualsType(undecodedTpe)
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala
index 775a7a9d38..862a3ffdc7 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala
@@ -165,7 +165,7 @@ abstract class ICodeReader extends ClassfileParser {
else if (name == fulltpnme.RuntimeNull)
definitions.NullClass
else if (nme.isImplClassName(name)) {
- val iface = definitions.getClass(nme.interfaceName(name))
+ val iface = definitions.getClass(tpnme.interfaceName(name))
log("forcing " + iface.owner + " at phase: " + phase + " impl: " + iface.implClass)
iface.owner.info // force the mixin type-transformer
definitions.getClass(name)
diff --git a/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala b/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala
index 5a11926048..3581f1b923 100644
--- a/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala
+++ b/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala
@@ -66,7 +66,7 @@ abstract class AddInterfaces extends InfoTransform { self: Erasure =>
private def newImplClass(iface: Symbol): Symbol = {
val inClass = iface.owner.isClass
- val implName = nme.implClassName(iface.name)
+ val implName = tpnme.implClassName(iface.name)
val implFlags = (iface.flags & ~(INTERFACE | lateINTERFACE)) | IMPLCLASS
val impl0 = (
diff --git a/src/compiler/scala/tools/nsc/transform/LambdaLift.scala b/src/compiler/scala/tools/nsc/transform/LambdaLift.scala
index 6bddfe8d57..618a1cbba4 100644
--- a/src/compiler/scala/tools/nsc/transform/LambdaLift.scala
+++ b/src/compiler/scala/tools/nsc/transform/LambdaLift.scala
@@ -159,7 +159,7 @@ abstract class LambdaLift extends InfoTransform {
// for that failure. There should be exactly one method for any given
// entity which always gives the right answer.
if (sym.isImplClass)
- localImplClasses((sym.owner, nme.interfaceName(sym.name))) = sym
+ localImplClasses((sym.owner, tpnme.interfaceName(sym.name))) = sym
else {
renamable addEntry sym
if (sym.isTrait)
@@ -229,7 +229,7 @@ abstract class LambdaLift extends InfoTransform {
def renameTrait(traitSym: Symbol, implSym: Symbol) {
val originalImplName = implSym.name
renameSym(traitSym)
- implSym setName nme.implClassName(traitSym.name)
+ implSym setName tpnme.implClassName(traitSym.name)
debuglog("renaming impl class in step with %s: %s => %s".format(traitSym, originalImplName, implSym.name))
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
index 651120db4f..f8da6a462d 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
@@ -1121,10 +1121,10 @@ trait Implicits {
}
// these should be lazy, otherwise we wouldn't be able to compile scala-library with starr
- private val TagSymbols = Set(ClassTagClass, TypeTagClass, ConcreteTypeTagClass)
- private val TagMaterializers = Map(
- ClassTagClass -> MacroInternal_materializeClassTag,
- TypeTagClass -> MacroInternal_materializeTypeTag,
+ private val TagSymbols = Set[Symbol](ClassTagClass, TypeTagClass, ConcreteTypeTagClass)
+ private val TagMaterializers = Map[Symbol, MethodSymbol](
+ ClassTagClass -> MacroInternal_materializeClassTag,
+ TypeTagClass -> MacroInternal_materializeTypeTag,
ConcreteTypeTagClass -> MacroInternal_materializeConcreteTypeTag
)
@@ -1140,27 +1140,34 @@ trait Implicits {
failure(arg, "failed to typecheck the materialized typetag: %n%s".format(ex.msg), ex.pos)
}
- val prefix = (tagClass, pre) match {
- // ClassTags only exist for scala.reflect.mirror, so their materializer doesn't care about prefixes
- case (ClassTagClass, _) =>
- gen.mkAttributedRef(Reflect_mirror) setType singleType(Reflect_mirror.owner.thisPrefix, Reflect_mirror)
- // [Eugene to Martin] this is the crux of the interaction between implicits and reifiers
- // here we need to turn a (supposedly path-dependent) type into a tree that will be used as a prefix
- // I'm not sure if I've done this right - please, review
- case (_, SingleType(prePre, preSym)) =>
- gen.mkAttributedRef(prePre, preSym) setType pre
- // necessary only to compile typetags used inside the Universe cake
- case (_, ThisType(thisSym)) =>
- gen.mkAttributedThis(thisSym)
- case _ =>
- // if ``pre'' is not a PDT, e.g. if someone wrote
- // implicitly[scala.reflect.makro.Context#TypeTag[Int]]
- // then we need to fail, because we don't know the prefix to use during type reification
- return failure(tp, "tag error: unsupported prefix type %s (%s)".format(pre, pre.kind))
- }
-
+ val prefix = (
+ // ClassTags only exist for scala.reflect.mirror, so their materializer
+ // doesn't care about prefixes
+ if (tagClass eq ClassTagClass) (
+ gen.mkAttributedRef(Reflect_mirror)
+ setType singleType(Reflect_mirror.owner.thisPrefix, Reflect_mirror)
+ )
+ else pre match {
+ // [Eugene to Martin] this is the crux of the interaction between
+ // implicits and reifiers here we need to turn a (supposedly
+ // path-dependent) type into a tree that will be used as a prefix I'm
+ // not sure if I've done this right - please, review
+ case SingleType(prePre, preSym) =>
+ gen.mkAttributedRef(prePre, preSym) setType pre
+ // necessary only to compile typetags used inside the Universe cake
+ case ThisType(thisSym) =>
+ gen.mkAttributedThis(thisSym)
+ case _ =>
+ // if ``pre'' is not a PDT, e.g. if someone wrote
+ // implicitly[scala.reflect.makro.Context#TypeTag[Int]]
+ // then we need to fail, because we don't know the prefix to use during type reification
+ return failure(tp, "tag error: unsupported prefix type %s (%s)".format(pre, pre.kind))
+ }
+ )
// todo. migrate hardcoded materialization in Implicits to corresponding implicit macros
- var materializer = atPos(pos.focus)(Apply(TypeApply(Ident(TagMaterializers(tagClass)), List(TypeTree(tp))), List(prefix)))
+ var materializer = atPos(pos.focus)(
+ gen.mkMethodCall(TagMaterializers(tagClass), List(tp), List(prefix))
+ )
if (settings.XlogImplicits.value) println("materializing requested %s.%s[%s] using %s".format(pre, tagClass.name, tp, materializer))
if (context.macrosEnabled) success(materializer)
else failure(materializer, "macros are disabled")
@@ -1169,8 +1176,8 @@ trait Implicits {
/** The manifest corresponding to type `pt`, provided `pt` is an instance of Manifest.
*/
private def implicitTagOrOfExpectedType(pt: Type): SearchResult = pt.dealias match {
- case TypeRef(pre, sym, args) if TagSymbols(sym) =>
- tagOfType(pre, args.head, sym)
+ case TypeRef(pre, sym, arg :: Nil) if TagSymbols(sym) =>
+ tagOfType(pre, arg, sym)
case tp@TypeRef(_, sym, _) if sym.isAbstractType =>
implicitTagOrOfExpectedType(tp.bounds.lo) // #3977: use tp (==pt.dealias), not pt (if pt is a type alias, pt.bounds.lo == pt)
case _ =>
diff --git a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
index 43cbea83ff..d327d9c397 100644
--- a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
@@ -134,7 +134,7 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT
// otherwise lead to either a compiler crash or runtime failure.
private lazy val isDisallowed = {
import definitions._
- Set(Any_isInstanceOf, Object_isInstanceOf, Any_asInstanceOf, Object_asInstanceOf, Object_==, Object_!=, Object_##)
+ Set[Symbol](Any_isInstanceOf, Object_isInstanceOf, Any_asInstanceOf, Object_asInstanceOf, Object_==, Object_!=, Object_##)
}
override def transform(tree: Tree): Tree = {
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 9a59d8f28a..54be9c9a87 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -3322,7 +3322,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
val typeParams: List[Symbol] = rawSyms map { sym =>
val name = sym.name match {
case x: TypeName => x
- case x => nme.singletonName(x)
+ case x => tpnme.singletonName(x)
}
val bound = allBounds(sym)
val sowner = if (isRawParameter(sym)) context.owner else sym.owner