summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
authorEugene Burmako <xeno.by@gmail.com>2012-06-06 02:46:31 +0200
committerEugene Burmako <xeno.by@gmail.com>2012-06-08 15:31:33 +0200
commit6bb5975289c5b11cb8c88dd4629286956b5d3d27 (patch)
tree39b1f4bffc4c64c98ae3cb01cedae88cdc95d9b5 /src/compiler
parent8ce47873f2207a72d902e01cc54eef26f28d1213 (diff)
downloadscala-6bb5975289c5b11cb8c88dd4629286956b5d3d27.tar.gz
scala-6bb5975289c5b11cb8c88dd4629286956b5d3d27.tar.bz2
scala-6bb5975289c5b11cb8c88dd4629286956b5d3d27.zip
The new reflection
A must read: "SIP: Scala Reflection": https://docs.google.com/document/d/1Z1VhhNPplbUpaZPIYdc0_EUv5RiGQ2X4oqp0i-vz1qw/edit Highlights: * Architecture has undergone a dramatic rehash. * Universes and mirrors are now separate entities: universes host reflection artifacts (trees, symbols, types, etc), mirrors abstract loading of those artifacts (e.g. JavaMirror loads stuff using a classloader and annotation unpickler, while GlobalMirror uses internal compiler classreader to achieve the same goal). * No static reflection mirror is imposed on the user. One is free to choose between lightweight mirrors and full-blown classloader-based mirror (read below). * Public reflection API is split into scala.reflect.base and scala.reflect.api. The former represents a minimalistic snapshot that is exactly enough to build reified trees and types. To build, but not to analyze - everything smart (for example, getting a type signature) is implemented in scala.reflect.api. * Both reflection domains have their own universe: scala.reflect.basis and scala.reflect.runtime.universe. The former is super lightweight and doesn't involve any classloaders, while the latter represents a stripped down compiler. * Classloader problems from 2.10.0-M3 are solved. * Exprs and type tags are now bound to a mirror upon creation. * However there is an easy way to migrate exprs and type tags between mirrors and even between universes. * This means that no classloader is imposed on the user of type tags and exprs. If one doesn't like a classloader that's there (associated with tag's mirror), one can create a custom mirror and migrate the tag or the expr to it. * There is a shortcut that works in most cases. Requesting a type tag from a full-blown universe will create that tag in a mirror that corresponds to the callsite classloader aka `getClass.getClassLoader`. This imposes no obligations on the programmer, since Type construction is lazy, so one can always migrate a tag into a different mirror. Migration notes for 2.10.0-M3 users: * Incantations in Predef are gone, some of them have moved to scala.reflect. * Everything path-dependent requires implicit prefix (for example, to refer to a type tag, you need to explicitly specify the universe it belongs to, e.g. reflect.basis.TypeTag or reflect.runtime.universe.TypeTag). * ArrayTags have been removed, ConcreteTypeTag have been renamed to TypeTags, TypeTags have been renamed to AbsTypeTags. Look for the reasoning in the nearby children of this commit. Why not in this commit? Scroll this message to the very bottom to find out the reason. * Some of the functions have been renamed or moved around. The rule of thumb is to look for anything non-trivial in scala.reflect.api. Some of tree build utils have been moved to Universe.build. * staticModule and staticClass have been moved from universes to mirrors * ClassTag.erasure => ClassTag.runtimeClass * For the sake of purity, type tags no longer have erasures. Use multiple context bounds (e.g. def foo[T: ru.TypeTag : ClassTag](...) = ...) if you're interested in having both erasures and types for type parameters. * reify now rolls back macro applications. * Runtime evaluation is now explicit, requires import scala.tools.reflect.Eval and scala-compiler.jar on the classpath. * Macro context now has separate universe and mirror fields. * Most of the useful stuff is declared in c.universe, so be sure to change your "import c.universe._" to "import c.mirror._". * Due to the changes in expressions and type tags, their regular factories are now really difficult to use. We acknowledge that macro users need to frequently create exprs and tags, so we added old-style factories to context. Bottom line: almost always prepend Expr(...)/TypeTag(...) with "c.". * Expr.eval has been renamed to Expr.splice. * Expr.value no longer splices (it can still be used to express cross-stage path-dependent types as specified in SIP-16). * c.reifyTree now has a mirror parameter that lets one customize the initial mirror the resulting Expr will be bound to. If you provide EmptyTree, then the reifier will automatically pick a reasonable mirror (callsite classloader mirror for a full-blown universe and rootMirror for a basis universe). Bottom line: this parameter should be EmptyTree in 99% of cases. * c.reifyErasure => c.reifyRuntimeClass. Known issues: * API is really raw, need your feedback. * All reflection artifacts are now represented by abstract types. This means that pattern matching against them will emit unchecked warnings. Adriaan is working on a patch that will fix that. WARNING, FELLOW CODE EXPLORER! You have entered a turbulence zone. For this commit and its nearby parents and children tests are not guaranteed to work. Things get back to normal only after the "repairs the tests after the refactoring spree" commit. Why so weird? These twentish changesets were once parts of a humongous blob, which spanned 1200 files and 15 kLOC. I did my best to split up the blob, so that the individual parts of the code compile and make sense in isolation. However doing the same for tests would be too much work.
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/scala/reflect/api/JavaUniverse.scala19
-rw-r--r--src/compiler/scala/reflect/api/TagInterop.scala38
-rw-r--r--src/compiler/scala/reflect/internal/AbstractFileApi.scala7
-rw-r--r--src/compiler/scala/reflect/internal/AnnotationInfos.scala16
-rw-r--r--src/compiler/scala/reflect/internal/BuildUtils.scala69
-rw-r--r--src/compiler/scala/reflect/internal/Constants.scala4
-rw-r--r--src/compiler/scala/reflect/internal/Definitions.scala515
-rw-r--r--src/compiler/scala/reflect/internal/FlagSets.scala66
-rw-r--r--src/compiler/scala/reflect/internal/Flags.scala41
-rw-r--r--src/compiler/scala/reflect/internal/FreeVars.scala60
-rw-r--r--src/compiler/scala/reflect/internal/HasFlags.scala1
-rw-r--r--src/compiler/scala/reflect/internal/Importers.scala9
-rw-r--r--src/compiler/scala/reflect/internal/Mirrors.scala243
-rw-r--r--src/compiler/scala/reflect/internal/Names.scala10
-rw-r--r--src/compiler/scala/reflect/internal/Positions.scala1
-rw-r--r--src/compiler/scala/reflect/internal/Required.scala2
-rw-r--r--src/compiler/scala/reflect/internal/Scopes.scala2
-rw-r--r--src/compiler/scala/reflect/internal/StdAttachments.scala2
-rw-r--r--src/compiler/scala/reflect/internal/StdCreators.scala21
-rw-r--r--src/compiler/scala/reflect/internal/StdNames.scala286
-rw-r--r--src/compiler/scala/reflect/internal/SymbolTable.scala23
-rw-r--r--src/compiler/scala/reflect/internal/Symbols.scala164
-rw-r--r--src/compiler/scala/reflect/internal/TreeBuildUtil.scala66
-rw-r--r--src/compiler/scala/reflect/internal/TreeGen.scala10
-rw-r--r--src/compiler/scala/reflect/internal/TreeInfo.scala35
-rw-r--r--src/compiler/scala/reflect/internal/TreePrinters.scala6
-rw-r--r--src/compiler/scala/reflect/internal/Trees.scala1325
-rw-r--r--src/compiler/scala/reflect/internal/Types.scala75
-rw-r--r--src/compiler/scala/reflect/internal/package.scala6
-rw-r--r--src/compiler/scala/reflect/internal/pickling/UnPickler.scala15
-rw-r--r--src/compiler/scala/reflect/internal/util/TraceSymbolActivity.scala2
-rw-r--r--src/compiler/scala/reflect/makro/runtime/AbortMacroException.scala2
-rw-r--r--src/compiler/scala/reflect/makro/runtime/Aliases.scala4
-rw-r--r--src/compiler/scala/reflect/makro/runtime/Context.scala3
-rw-r--r--src/compiler/scala/reflect/makro/runtime/Exprs.scala8
-rw-r--r--src/compiler/scala/reflect/makro/runtime/FrontEnds.scala4
-rw-r--r--src/compiler/scala/reflect/makro/runtime/Reifiers.scala18
-rw-r--r--src/compiler/scala/reflect/makro/runtime/Symbols.scala10
-rw-r--r--src/compiler/scala/reflect/makro/runtime/TypeTags.scala9
-rw-r--r--src/compiler/scala/reflect/reify/NodePrinters.scala89
-rw-r--r--src/compiler/scala/reflect/reify/Taggers.scala17
-rw-r--r--src/compiler/scala/reflect/reify/codegen/Symbols.scala14
-rw-r--r--src/compiler/scala/reflect/reify/codegen/Trees.scala6
-rw-r--r--src/compiler/scala/reflect/runtime/AbstractFile.scala2
-rw-r--r--src/compiler/scala/reflect/runtime/ClassLoaders.scala25
-rw-r--r--src/compiler/scala/reflect/runtime/ConversionUtil.scala92
-rw-r--r--src/compiler/scala/reflect/runtime/JavaMirrors.scala981
-rw-r--r--src/compiler/scala/reflect/runtime/JavaToScala.scala697
-rw-r--r--src/compiler/scala/reflect/runtime/JavaUniverse.scala33
-rw-r--r--src/compiler/scala/reflect/runtime/Mirror.scala85
-rw-r--r--src/compiler/scala/reflect/runtime/ReflectSetup.scala12
-rw-r--r--src/compiler/scala/reflect/runtime/ReflectionUtils.scala80
-rw-r--r--src/compiler/scala/reflect/runtime/ScalaToJava.scala87
-rw-r--r--src/compiler/scala/reflect/runtime/SymbolLoaders.scala55
-rw-r--r--src/compiler/scala/reflect/runtime/SymbolTable.scala5
-rw-r--r--src/compiler/scala/reflect/runtime/SynchronizedSymbols.scala14
-rw-r--r--src/compiler/scala/reflect/runtime/SynchronizedTypes.scala13
-rw-r--r--src/compiler/scala/reflect/runtime/TwoWayCache.scala52
-rw-r--r--src/compiler/scala/reflect/runtime/Universe.scala43
-rw-r--r--src/compiler/scala/reflect/runtime/package.scala12
-rw-r--r--src/compiler/scala/tools/cmd/FromString.scala3
-rw-r--r--src/compiler/scala/tools/nsc/ClassLoaders.scala64
-rw-r--r--src/compiler/scala/tools/nsc/Global.scala77
-rw-r--r--src/compiler/scala/tools/nsc/ReflectGlobal.scala28
-rw-r--r--src/compiler/scala/tools/nsc/ReflectMain.scala7
-rw-r--r--src/compiler/scala/tools/nsc/ReflectSetup.scala7
-rw-r--r--src/compiler/scala/tools/nsc/ToolBoxes.scala84
-rwxr-xr-xsrc/compiler/scala/tools/nsc/ast/DocComments.scala4
-rw-r--r--src/compiler/scala/tools/nsc/ast/FreeVars.scala26
-rw-r--r--src/compiler/scala/tools/nsc/ast/NodePrinters.scala2
-rw-r--r--src/compiler/scala/tools/nsc/ast/TreeBrowsers.scala2
-rw-r--r--src/compiler/scala/tools/nsc/ast/Trees.scala5
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/Parsers.scala2
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala5
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala10
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/GenAndroid.scala4
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala8
-rw-r--r--src/compiler/scala/tools/nsc/doc/Uncompilable.scala3
-rw-r--r--src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala5
-rw-r--r--src/compiler/scala/tools/nsc/interactive/Picklers.scala2
-rw-r--r--src/compiler/scala/tools/nsc/interactive/RangePositions.scala2
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/ILoop.scala4
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/IMain.scala55
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/JLineCompletion.scala3
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/NamedParam.scala11
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/Power.scala40
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/ReplVals.scala9
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/TypeStrings.scala22
-rw-r--r--src/compiler/scala/tools/nsc/io/AbstractFile.scala3
-rw-r--r--src/compiler/scala/tools/nsc/scratchpad/Executor.scala2
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala14
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala8
-rw-r--r--src/compiler/scala/tools/nsc/symtab/clr/TypeParser.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala6
-rw-r--r--src/compiler/scala/tools/nsc/transform/Mixin.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala15
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Contexts.scala8
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/DestructureTypes.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Implicits.scala33
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Infer.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Macros.scala26
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala35
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala12
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/RefChecks.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala4
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala4
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Taggings.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala14
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Unapplies.scala5
-rw-r--r--src/compiler/scala/tools/nsc/util/Position.scala43
-rw-r--r--src/compiler/scala/tools/nsc/util/ScalaClassLoader.scala2
-rw-r--r--src/compiler/scala/tools/reflect/FastTrack.scala1
-rw-r--r--src/compiler/scala/tools/reflect/FrontEnds.scala (renamed from src/compiler/scala/reflect/internal/FrontEnds.scala)12
-rw-r--r--src/compiler/scala/tools/reflect/StdTags.scala31
-rw-r--r--src/compiler/scala/tools/reflect/ToolBox.scala93
-rw-r--r--src/compiler/scala/tools/reflect/ToolBoxFactory.scala (renamed from src/compiler/scala/reflect/runtime/ToolBoxes.scala)221
-rw-r--r--src/compiler/scala/tools/reflect/package.scala33
120 files changed, 4127 insertions, 2621 deletions
diff --git a/src/compiler/scala/reflect/api/JavaUniverse.scala b/src/compiler/scala/reflect/api/JavaUniverse.scala
new file mode 100644
index 0000000000..8bf62a357c
--- /dev/null
+++ b/src/compiler/scala/reflect/api/JavaUniverse.scala
@@ -0,0 +1,19 @@
+package scala.reflect
+package api
+
+// [Martin] Moved to compiler because it needs to see runtime.Universe
+// The two will be united in scala-reflect anyway.
+trait JavaUniverse extends Universe with Mirrors with TagInterop { self =>
+
+ type RuntimeClass = java.lang.Class[_]
+
+ override type Mirror >: Null <: JavaMirror
+
+ trait JavaMirror extends MirrorOf[self.type] with RuntimeMirror {
+ val classLoader: ClassLoader
+ override def toString = s"JavaMirror with ${runtime.ReflectionUtils.show(classLoader)}"
+ }
+
+ def runtimeMirror(cl: ClassLoader): Mirror
+}
+
diff --git a/src/compiler/scala/reflect/api/TagInterop.scala b/src/compiler/scala/reflect/api/TagInterop.scala
new file mode 100644
index 0000000000..a5b303bb37
--- /dev/null
+++ b/src/compiler/scala/reflect/api/TagInterop.scala
@@ -0,0 +1,38 @@
+package scala.reflect
+package api
+
+import scala.reflect.base.TypeCreator
+import scala.reflect.base.{Universe => BaseUniverse}
+
+// [Martin] Moved to compiler because it needs to see runtime.Universe
+// The two will be united in scala-reflect anyway.
+trait TagInterop { self: JavaUniverse =>
+
+ // [Eugene++] would be great if we could approximate the interop without any mirrors
+ // todo. think how to implement that
+
+ override def concreteTypeTagToManifest[T: ClassTag](mirror0: Any, tag: base.Universe # ConcreteTypeTag[T]): Manifest[T] = {
+ // [Eugene++] implement more sophisticated logic
+ // Martin said it'd be okay to simply copypaste `Implicits.manifestOfType`
+ val mirror = mirror0.asInstanceOf[Mirror]
+ val erasure = mirror.runtimeClass(tag.in(mirror).tpe)
+ Manifest.classType(erasure).asInstanceOf[Manifest[T]]
+ }
+
+ override def manifestToConcreteTypeTag[T](mirror0: Any, manifest: Manifest[T]): base.Universe # ConcreteTypeTag[T] =
+ ConcreteTypeTag(mirror0.asInstanceOf[Mirror], new TypeCreator {
+ def apply[U <: BaseUniverse with Singleton](mirror: MirrorOf[U]): U # Type = {
+ mirror.universe match {
+ case ju: JavaUniverse =>
+ val jm = mirror.asInstanceOf[ju.Mirror]
+ val sym = jm.reflectClass(manifest.erasure).symbol
+ val tpe =
+ if (manifest.typeArguments.isEmpty) sym.asType
+ else ju.appliedType(sym.asTypeConstructor, manifest.typeArguments map (targ => ju.manifestToConcreteTypeTag(jm, targ)) map (_.in(jm).tpe))
+ tpe.asInstanceOf[U # Type]
+ case u =>
+ u.manifestToConcreteTypeTag(mirror.asInstanceOf[u.Mirror], manifest).in(mirror).tpe
+ }
+ }
+ })
+}
diff --git a/src/compiler/scala/reflect/internal/AbstractFileApi.scala b/src/compiler/scala/reflect/internal/AbstractFileApi.scala
new file mode 100644
index 0000000000..9f37f4536f
--- /dev/null
+++ b/src/compiler/scala/reflect/internal/AbstractFileApi.scala
@@ -0,0 +1,7 @@
+package scala.reflect
+package internal
+
+trait AbstractFileApi {
+ def path: String
+ def canonicalPath: String
+}
diff --git a/src/compiler/scala/reflect/internal/AnnotationInfos.scala b/src/compiler/scala/reflect/internal/AnnotationInfos.scala
index 91e1c3d50d..c283ae408e 100644
--- a/src/compiler/scala/reflect/internal/AnnotationInfos.scala
+++ b/src/compiler/scala/reflect/internal/AnnotationInfos.scala
@@ -46,23 +46,26 @@ trait AnnotationInfos extends api.AnnotationInfos { self: SymbolTable =>
* - or nested classfile annotations
*/
abstract class ClassfileAnnotArg extends Product
+ implicit val ClassfileAnnotArgTag = ClassTag[ClassfileAnnotArg](classOf[ClassfileAnnotArg])
/** Represents a compile-time Constant (`Boolean`, `Byte`, `Short`,
* `Char`, `Int`, `Long`, `Float`, `Double`, `String`, `java.lang.Class` or
* an instance of a Java enumeration value).
*/
case class LiteralAnnotArg(const: Constant)
- extends ClassfileAnnotArg {
+ extends ClassfileAnnotArg with LiteralAnnotArgApi {
override def toString = const.escapedStringValue
}
+ implicit val LiteralAnnotArgTag = ClassTag[LiteralAnnotArg](classOf[LiteralAnnotArg])
object LiteralAnnotArg extends LiteralAnnotArgExtractor
/** Represents an array of classfile annotation arguments */
case class ArrayAnnotArg(args: Array[ClassfileAnnotArg])
- extends ClassfileAnnotArg {
+ extends ClassfileAnnotArg with ArrayAnnotArgApi {
override def toString = args.mkString("[", ", ", "]")
}
+ implicit val ArrayAnnotArgTag = ClassTag[ArrayAnnotArg](classOf[ArrayAnnotArg])
object ArrayAnnotArg extends ArrayAnnotArgExtractor
@@ -105,11 +108,12 @@ trait AnnotationInfos extends api.AnnotationInfos { self: SymbolTable =>
}
/** Represents a nested classfile annotation */
- case class NestedAnnotArg(annInfo: AnnotationInfo) extends ClassfileAnnotArg {
+ case class NestedAnnotArg(annInfo: AnnotationInfo) extends ClassfileAnnotArg with NestedAnnotArgApi {
// The nested annotation should not have any Scala annotation arguments
assert(annInfo.args.isEmpty, annInfo.args)
override def toString = annInfo.toString
}
+ implicit val NestedAnnotArgTag = ClassTag[NestedAnnotArg](classOf[NestedAnnotArg])
object NestedAnnotArg extends NestedAnnotArgExtractor
@@ -191,7 +195,7 @@ trait AnnotationInfos extends api.AnnotationInfos { self: SymbolTable =>
*
* `assocs` stores arguments to classfile annotations as name-value pairs.
*/
- sealed abstract class AnnotationInfo {
+ sealed abstract class AnnotationInfo extends AnnotationInfoApi {
def atp: Type
def args: List[Tree]
def assocs: List[(Name, ClassfileAnnotArg)]
@@ -258,7 +262,7 @@ trait AnnotationInfos extends api.AnnotationInfos { self: SymbolTable =>
/** Change all ident's with Symbol "from" to instead use symbol "to" */
def substIdentSyms(from: Symbol, to: Symbol) =
- AnnotationInfo(atp, args map (_ substTreeSyms (from -> to)), assocs) setPos pos
+ AnnotationInfo(atp, args map (_ substituteSymbols (List(from), List(to))), assocs) setPos pos
def stringArg(index: Int) = constantAtIndex(index) map (_.stringValue)
def intArg(index: Int) = constantAtIndex(index) map (_.intValue)
@@ -283,7 +287,7 @@ trait AnnotationInfos extends api.AnnotationInfos { self: SymbolTable =>
}
}
- lazy val classfileAnnotArgTag: ArrayTag[ClassfileAnnotArg] = arrayTag[ClassfileAnnotArg]
+ implicit val AnnotationInfoTag = ClassTag[AnnotationInfo](classOf[AnnotationInfo])
object UnmappableAnnotation extends CompleteAnnotationInfo(NoType, Nil, Nil)
}
diff --git a/src/compiler/scala/reflect/internal/BuildUtils.scala b/src/compiler/scala/reflect/internal/BuildUtils.scala
new file mode 100644
index 0000000000..3bde57ded8
--- /dev/null
+++ b/src/compiler/scala/reflect/internal/BuildUtils.scala
@@ -0,0 +1,69 @@
+package scala.reflect
+package internal
+
+import Flags._
+
+trait BuildUtils extends base.BuildUtils { self: SymbolTable =>
+
+ class BuildImpl extends BuildBase {
+
+ def selectType(owner: Symbol, name: String): TypeSymbol = {
+ val result = owner.info.decl(newTypeName(name))
+ if (result ne NoSymbol) result.asTypeSymbol
+ else MissingRequirementError.notFound("type %s in %s".format(name, owner.fullName))
+ }
+
+ def selectTerm(owner: Symbol, name: String): TermSymbol = {
+ val sym = owner.info.decl(newTermName(name))
+ val result =
+ if (sym.isOverloaded) sym.suchThat(!_.isMethod)
+ else sym
+ if (result ne NoSymbol) result.asTermSymbol
+ else MissingRequirementError.notFound("term %s in %s".format(name, owner.fullName))
+ }
+
+ def selectOverloadedMethod(owner: Symbol, name: String, index: Int): MethodSymbol = {
+ val result = owner.info.decl(newTermName(name)).alternatives(index)
+ if (result ne NoSymbol) result.asMethodSymbol
+ else MissingRequirementError.notFound("overloaded method %s #%d in %s".format(name, index, owner.fullName))
+ }
+
+ def newFreeTerm(name: String, info: Type, value: => Any, flags: Long = 0L, origin: String = null): FreeTermSymbol =
+ newFreeTermSymbol(newTermName(name), info, value, flags, origin)
+
+ def newFreeType(name: String, info: Type, value: => Any, flags: Long = 0L, origin: String = null): FreeTypeSymbol =
+ newFreeTypeSymbol(newTypeName(name), info, value, (if (flags == 0L) PARAM else flags) | DEFERRED, origin)
+
+ def newFreeExistential(name: String, info: Type, value: => Any, flags: Long = 0L, origin: String = null): FreeTypeSymbol =
+ newFreeTypeSymbol(newTypeName(name), info, value, (if (flags == 0L) EXISTENTIAL else flags) | DEFERRED, origin)
+
+ def newNestedSymbol(owner: Symbol, name: Name, pos: Position, flags: Long, isClass: Boolean): Symbol =
+ owner.newNestedSymbol(name, pos, flags, isClass)
+
+ def setAnnotations[S <: Symbol](sym: S, annots: List[AnnotationInfo]): S =
+ sym.setAnnotations(annots)
+
+ def setTypeSignature[S <: Symbol](sym: S, tpe: Type): S =
+ sym.setTypeSignature(tpe)
+
+ def flagsFromBits(bits: Long): FlagSet = bits
+
+ def emptyValDef: ValDef = self.emptyValDef
+
+ def This(sym: Symbol): Tree = self.This(sym)
+
+ def Select(qualifier: Tree, sym: Symbol): Select = self.Select(qualifier, sym)
+
+ def Ident(sym: Symbol): Ident = self.Ident(sym)
+
+ def TypeTree(tp: Type): TypeTree = self.TypeTree(tp)
+
+ def thisPrefix(sym: Symbol): Type = sym.thisPrefix
+
+ def setType[T <: Tree](tree: T, tpe: Type): T = { tree.setType(tpe); tree }
+
+ def setSymbol[T <: Tree](tree: T, sym: Symbol): T = { tree.setSymbol(sym); tree }
+ }
+
+ val build: BuildBase = new BuildImpl
+}
diff --git a/src/compiler/scala/reflect/internal/Constants.scala b/src/compiler/scala/reflect/internal/Constants.scala
index 861bc870a7..820dfe0868 100644
--- a/src/compiler/scala/reflect/internal/Constants.scala
+++ b/src/compiler/scala/reflect/internal/Constants.scala
@@ -30,7 +30,7 @@ trait Constants extends api.Constants {
// For supporting java enumerations inside java annotations (see ClassfileParser)
final val EnumTag = 13
- case class Constant(value: Any) extends AbsConstant {
+ case class Constant(value: Any) extends ConstantApi {
val tag: Int = value match {
case null => NullTag
case x: Unit => UnitTag
@@ -235,4 +235,6 @@ trait Constants extends api.Constants {
}
object Constant extends ConstantExtractor
+
+ implicit val ConstantTag = ClassTag[Constant](classOf[Constant])
}
diff --git a/src/compiler/scala/reflect/internal/Definitions.scala b/src/compiler/scala/reflect/internal/Definitions.scala
index 6141cc184d..b3a651563e 100644
--- a/src/compiler/scala/reflect/internal/Definitions.scala
+++ b/src/compiler/scala/reflect/internal/Definitions.scala
@@ -10,11 +10,13 @@ import annotation.{ switch, meta }
import scala.collection.{ mutable, immutable }
import Flags._
import PartialFunction._
-import scala.reflect.{ mirror => rm }
+import scala.reflect.base.{Universe => BaseUniverse}
-trait Definitions extends reflect.api.StandardDefinitions {
+trait Definitions extends api.StandardDefinitions {
self: SymbolTable =>
+ import rootMirror.{getModule, getClassByName, getRequiredClass, getRequiredModule, getRequiredPackage, getClassIfDefined, getModuleIfDefined, getPackageObject, getPackageObjectIfDefined, requiredClass, requiredModule}
+
object definitions extends DefinitionsClass
// [Eugene] find a way to make these non-lazy
@@ -99,7 +101,7 @@ trait Definitions extends reflect.api.StandardDefinitions {
case _ => catastrophicFailure()
}
}
- private def valueCompanionMember(className: Name, methodName: TermName): MethodSymbol =
+ private def valueCompanionMember(className: Name, methodName: TermName): TermSymbol =
getMemberMethod(valueClassCompanion(className.toTermName).moduleClass, methodName)
private def classesMap[T](f: Name => T) = symbolsMap(ScalaValueClassesNoUnit, f)
@@ -111,7 +113,7 @@ trait Definitions extends reflect.api.StandardDefinitions {
lazy val abbrvTag = symbolsMap(ScalaValueClasses, nameToTag) withDefaultValue OBJECT_TAG
lazy val numericWeight = symbolsMapFilt(ScalaValueClasses, nameToWeight.keySet, nameToWeight)
lazy val boxedModule = classesMap(x => getModule(boxedName(x)))
- lazy val boxedClass = classesMap(x => getClass(boxedName(x)))
+ lazy val boxedClass = classesMap(x => getClassByName(boxedName(x)))
lazy val refClass = classesMap(x => getRequiredClass("scala.runtime." + x + "Ref"))
lazy val volatileRefClass = classesMap(x => getRequiredClass("scala.runtime.Volatile" + x + "Ref"))
lazy val boxMethod = classesMap(x => valueCompanionMember(x, nme.box))
@@ -138,9 +140,9 @@ trait Definitions extends reflect.api.StandardDefinitions {
lazy val FloatClass = valueClassSymbol(tpnme.Float)
lazy val DoubleClass = valueClassSymbol(tpnme.Double)
lazy val BooleanClass = valueClassSymbol(tpnme.Boolean)
- lazy val Boolean_and = getMember(BooleanClass, nme.ZAND)
- lazy val Boolean_or = getMember(BooleanClass, nme.ZOR)
- lazy val Boolean_not = getMember(BooleanClass, nme.UNARY_!)
+ lazy val Boolean_and = getMemberMethod(BooleanClass, nme.ZAND)
+ lazy val Boolean_or = getMemberMethod(BooleanClass, nme.ZOR)
+ lazy val Boolean_not = getMemberMethod(BooleanClass, nme.UNARY_!)
lazy val ScalaNumericValueClasses = ScalaValueClasses filterNot Set[Symbol](UnitClass, BooleanClass)
@@ -160,68 +162,21 @@ trait Definitions extends reflect.api.StandardDefinitions {
def ScalaPrimitiveValueClasses: List[ClassSymbol] = ScalaValueClasses
}
- abstract class DefinitionsClass extends AbsDefinitions with ValueClassDefinitions {
+ abstract class DefinitionsClass extends DefinitionsApi with ValueClassDefinitions {
private var isInitialized = false
def isDefinitionsInitialized = isInitialized
// symbols related to packages
var emptypackagescope: Scope = null //debug
- // TODO - having these as objects means they elude the attempt to
- // add synchronization in SynchronizedSymbols. But we should either
- // flip on object overrides or find some other accomodation, because
- // lazy vals are unnecessarily expensive relative to objects and it
- // is very beneficial for a handful of bootstrap symbols to have
- // first class identities
- sealed trait WellKnownSymbol extends Symbol {
- this initFlags TopLevelCreationFlags
- }
- // Features common to RootClass and RootPackage, the roots of all
- // type and term symbols respectively.
- sealed trait RootSymbol extends WellKnownSymbol {
- final override def isRootSymbol = true
- override def owner = NoSymbol
- override def typeOfThis = thisSym.tpe
- }
- // This is the package _root_. The actual root cannot be referenced at
- // the source level, but _root_ is essentially a function => <root>.
- final object RootPackage extends PackageSymbol(NoSymbol, NoPosition, nme.ROOTPKG) with RootSymbol {
- this setInfo NullaryMethodType(RootClass.tpe)
- RootClass.sourceModule = this
-
- override def isRootPackage = true
- }
- // This is <root>, the actual root of everything except the package _root_.
- // <root> and _root_ (RootPackage and RootClass) should be the only "well known"
- // symbols owned by NoSymbol. All owner chains should go through RootClass,
- // although it is probable that some symbols are created as direct children
- // of NoSymbol to ensure they will not be stumbled upon. (We should designate
- // a better encapsulated place for that.)
- final object RootClass extends PackageClassSymbol(NoSymbol, NoPosition, tpnme.ROOT) with RootSymbol {
- this setInfo rootLoader
-
- override def isRoot = true
- override def isEffectiveRoot = true
- override def isStatic = true
- override def isNestedClass = false
- override def ownerOfNewSymbols = EmptyPackageClass
- }
- // The empty package, which holds all top level types without given packages.
- final object EmptyPackage extends PackageSymbol(RootClass, NoPosition, nme.EMPTY_PACKAGE_NAME) with WellKnownSymbol {
- override def isEmptyPackage = true
- }
- final object EmptyPackageClass extends PackageClassSymbol(RootClass, NoPosition, tpnme.EMPTY_PACKAGE_NAME) with WellKnownSymbol {
- override def isEffectiveRoot = true
- override def isEmptyPackageClass = true
- }
// It becomes tricky to create dedicated objects for other symbols because
// of initialization order issues.
lazy val JavaLangPackage = getRequiredPackage(sn.JavaLang)
- lazy val JavaLangPackageClass = JavaLangPackage.moduleClass
+ lazy val JavaLangPackageClass = JavaLangPackage.moduleClass.asClassSymbol
lazy val ScalaPackage = getRequiredPackage(nme.scala_)
- lazy val ScalaPackageClass = ScalaPackage.moduleClass
+ lazy val ScalaPackageClass = ScalaPackage.moduleClass.asClassSymbol
lazy val RuntimePackage = getRequiredPackage("scala.runtime")
- lazy val RuntimePackageClass = RuntimePackage.moduleClass
+ lazy val RuntimePackageClass = RuntimePackage.moduleClass.asClassSymbol
lazy val JavaLangEnumClass = requiredClass[java.lang.Enum[_]]
@@ -235,9 +190,6 @@ trait Definitions extends reflect.api.StandardDefinitions {
private def inttype = IntClass.tpe
private def stringtype = StringClass.tpe
- // Java types
- def javaTypeName(jclazz: Class[_]): TypeName = newTypeName(jclazz.getName)
-
def javaTypeToValueClass(jtype: Class[_]): Symbol = jtype match {
case java.lang.Void.TYPE => UnitClass
case java.lang.Byte.TYPE => ByteClass
@@ -282,7 +234,7 @@ trait Definitions extends reflect.api.StandardDefinitions {
// Note: this is not the type alias AnyRef, it's a companion-like
// object used by the @specialize annotation.
- lazy val AnyRefModule = getMember(ScalaPackageClass, nme.AnyRef)
+ lazy val AnyRefModule = getMemberModule(ScalaPackageClass, nme.AnyRef)
@deprecated("Use AnyRefModule", "2.10.0")
def Predef_AnyRef = AnyRefModule
@@ -294,8 +246,8 @@ trait Definitions extends reflect.api.StandardDefinitions {
}).asInstanceOf[ClassSymbol]
// bottom types
- lazy val RuntimeNothingClass = getClass(fulltpnme.RuntimeNothing)
- lazy val RuntimeNullClass = getClass(fulltpnme.RuntimeNull)
+ lazy val RuntimeNothingClass = getClassByName(fulltpnme.RuntimeNothing)
+ lazy val RuntimeNullClass = getClassByName(fulltpnme.RuntimeNull)
sealed abstract class BottomClassSymbol(name: TypeName, parent: Symbol) extends ClassSymbol(ScalaPackageClass, NoPosition, name) {
locally {
@@ -316,12 +268,12 @@ trait Definitions extends reflect.api.StandardDefinitions {
// exceptions and other throwables
lazy val ClassCastExceptionClass = requiredClass[ClassCastException]
- lazy val IndexOutOfBoundsExceptionClass = getClass(sn.IOOBException)
- lazy val InvocationTargetExceptionClass = getClass(sn.InvTargetException)
+ lazy val IndexOutOfBoundsExceptionClass = getClassByName(sn.IOOBException)
+ lazy val InvocationTargetExceptionClass = getClassByName(sn.InvTargetException)
lazy val MatchErrorClass = requiredClass[MatchError]
lazy val NonLocalReturnControlClass = requiredClass[scala.runtime.NonLocalReturnControl[_]]
- lazy val NullPointerExceptionClass = getClass(sn.NPException)
- lazy val ThrowableClass = getClass(sn.Throwable)
+ lazy val NullPointerExceptionClass = getClassByName(sn.NPException)
+ lazy val ThrowableClass = getClassByName(sn.Throwable)
lazy val UninitializedErrorClass = requiredClass[UninitializedFieldError]
// fundamental reference classes
@@ -331,14 +283,17 @@ trait Definitions extends reflect.api.StandardDefinitions {
lazy val StringClass = requiredClass[java.lang.String]
lazy val StringModule = StringClass.linkedClassOfClass
lazy val ClassClass = requiredClass[java.lang.Class[_]]
- def Class_getMethod = getMember(ClassClass, nme.getMethod_)
+ def Class_getMethod = getMemberMethod(ClassClass, nme.getMethod_)
lazy val DynamicClass = requiredClass[Dynamic]
// fundamental modules
lazy val SysPackage = getPackageObject("scala.sys")
- def Sys_error = getMember(SysPackage, nme.error)
+ def Sys_error = getMemberMethod(SysPackage, nme.error)
// Modules whose members are in the default namespace
+ // [Eugene++] ScalaPackage and JavaLangPackage are never ever shared between mirrors
+ // as a result, `Int` becomes `scala.Int` and `String` becomes `java.lang.String`
+ // I could just change `isOmittablePrefix`, but there's more to it, so I'm leaving this as a todo for now
lazy val UnqualifiedModules = List(PredefModule, ScalaPackage, JavaLangPackage)
// Those modules and their module classes
lazy val UnqualifiedOwners = UnqualifiedModules.toSet ++ UnqualifiedModules.map(_.moduleClass)
@@ -346,11 +301,12 @@ trait Definitions extends reflect.api.StandardDefinitions {
lazy val PredefModule = requiredModule[scala.Predef.type]
lazy val PredefModuleClass = PredefModule.moduleClass
- def Predef_classOf = getMember(PredefModule, nme.classOf)
- def Predef_identity = getMember(PredefModule, nme.identity)
- def Predef_conforms = getMember(PredefModule, nme.conforms)
- def Predef_wrapRefArray = getMember(PredefModule, nme.wrapRefArray)
- def Predef_??? = getMember(PredefModule, nme.???)
+ def Predef_classOf = getMemberMethod(PredefModule, nme.classOf)
+ def Predef_identity = getMemberMethod(PredefModule, nme.identity)
+ def Predef_conforms = getMemberMethod(PredefModule, nme.conforms)
+ def Predef_wrapRefArray = getMemberMethod(PredefModule, nme.wrapRefArray)
+ def Predef_??? = getMemberMethod(PredefModule, nme.???)
+ def Predef_implicitly = getMemberMethod(PredefModule, nme.implicitly)
/** Is `sym` a member of Predef with the given name?
* Note: DON't replace this by sym == Predef_conforms/etc, as Predef_conforms is a `def`
@@ -364,32 +320,32 @@ trait Definitions extends reflect.api.StandardDefinitions {
/** Specialization.
*/
lazy val SpecializableModule = requiredModule[Specializable]
- lazy val GroupOfSpecializable = getMember(SpecializableModule, tpnme.Group)
-
- lazy val ConsoleModule: Symbol = requiredModule[scala.Console.type]
- lazy val ScalaRunTimeModule: Symbol = requiredModule[scala.runtime.ScalaRunTime.type]
- lazy val SymbolModule: Symbol = requiredModule[scala.Symbol.type]
- lazy val Symbol_apply = SymbolModule.info decl nme.apply
-
- def SeqFactory = getMember(ScalaRunTimeModule, nme.Seq)
- def arrayApplyMethod = getMember(ScalaRunTimeModule, nme.array_apply)
- def arrayUpdateMethod = getMember(ScalaRunTimeModule, nme.array_update)
- def arrayLengthMethod = getMember(ScalaRunTimeModule, nme.array_length)
- def arrayCloneMethod = getMember(ScalaRunTimeModule, nme.array_clone)
- def ensureAccessibleMethod = getMember(ScalaRunTimeModule, nme.ensureAccessible)
- def scalaRuntimeSameElements = getMember(ScalaRunTimeModule, nme.sameElements)
- def arrayClassMethod = getMember(ScalaRunTimeModule, nme.arrayClass)
- def arrayElementClassMethod = getMember(ScalaRunTimeModule, nme.arrayElementClass)
+ lazy val GroupOfSpecializable = getMemberClass(SpecializableModule, tpnme.Group)
+
+ lazy val ConsoleModule = requiredModule[scala.Console.type]
+ lazy val ScalaRunTimeModule = requiredModule[scala.runtime.ScalaRunTime.type]
+ lazy val SymbolModule = requiredModule[scala.Symbol.type]
+ lazy val Symbol_apply = getMemberMethod(SymbolModule, nme.apply)
+
+ def SeqFactory = getMember(ScalaRunTimeModule, nme.Seq) // [Eugene++] obsolete?
+ def arrayApplyMethod = getMemberMethod(ScalaRunTimeModule, nme.array_apply)
+ def arrayUpdateMethod = getMemberMethod(ScalaRunTimeModule, nme.array_update)
+ def arrayLengthMethod = getMemberMethod(ScalaRunTimeModule, nme.array_length)
+ def arrayCloneMethod = getMemberMethod(ScalaRunTimeModule, nme.array_clone)
+ def ensureAccessibleMethod = getMemberMethod(ScalaRunTimeModule, nme.ensureAccessible)
+ def scalaRuntimeSameElements = getMemberMethod(ScalaRunTimeModule, nme.sameElements)
+ def arrayClassMethod = getMemberMethod(ScalaRunTimeModule, nme.arrayClass)
+ def arrayElementClassMethod = getMemberMethod(ScalaRunTimeModule, nme.arrayElementClass)
// classes with special meanings
lazy val StringAddClass = requiredClass[scala.runtime.StringAdd]
lazy val ArrowAssocClass = getRequiredClass("scala.Predef.ArrowAssoc") // SI-5731
- lazy val StringAdd_+ = getMember(StringAddClass, nme.PLUS)
+ lazy val StringAdd_+ = getMemberMethod(StringAddClass, nme.PLUS)
lazy val NotNullClass = getRequiredClass("scala.NotNull")
lazy val ScalaNumberClass = requiredClass[scala.math.ScalaNumber]
lazy val TraitSetterAnnotationClass = requiredClass[scala.runtime.TraitSetter]
lazy val DelayedInitClass = requiredClass[scala.DelayedInit]
- def delayedInitMethod = getMember(DelayedInitClass, nme.delayedInit)
+ def delayedInitMethod = getMemberMethod(DelayedInitClass, nme.delayedInit)
// a dummy value that communicates that a delayedInit call is compiler-generated
// from phase UnCurry to phase Constructors
// !!! This is not used anywhere (it was checked in that way.)
@@ -454,40 +410,37 @@ trait Definitions extends reflect.api.StandardDefinitions {
lazy val TraversableClass = requiredClass[scala.collection.Traversable[_]]
lazy val ListModule = requiredModule[scala.collection.immutable.List.type]
- lazy val List_apply = getMember(ListModule, nme.apply)
+ lazy val List_apply = getMemberMethod(ListModule, nme.apply)
lazy val NilModule = requiredModule[scala.collection.immutable.Nil.type]
lazy val SeqModule = requiredModule[scala.collection.Seq.type]
- lazy val IteratorModule = requiredModule[scala.collection.Iterator.type]
- lazy val Iterator_apply = getMember(IteratorModule, nme.apply)
+ lazy val IteratorModule = requiredModule[scala.collection.Iterator.type]
+ lazy val Iterator_apply = getMemberMethod(IteratorModule, nme.apply)
// arrays and their members
- lazy val ArrayModule = requiredModule[scala.Array.type]
- lazy val ArrayModule_overloadedApply = getMember(ArrayModule, nme.apply)
- lazy val ArrayClass = getRequiredClass("scala.Array") // requiredClass[scala.Array[_]]
- lazy val Array_apply = getMember(ArrayClass, nme.apply)
- lazy val Array_update = getMember(ArrayClass, nme.update)
- lazy val Array_length = getMember(ArrayClass, nme.length)
- lazy val Array_clone = getMember(ArrayClass, nme.clone_)
+ lazy val ArrayModule = requiredModule[scala.Array.type]
+ lazy val ArrayModule_overloadedApply = getMemberMethod(ArrayModule, nme.apply)
+ lazy val ArrayClass = getRequiredClass("scala.Array") // requiredClass[scala.Array[_]]
+ lazy val Array_apply = getMemberMethod(ArrayClass, nme.apply)
+ lazy val Array_update = getMemberMethod(ArrayClass, nme.update)
+ lazy val Array_length = getMemberMethod(ArrayClass, nme.length)
+ lazy val Array_clone = getMemberMethod(ArrayClass, nme.clone_)
// reflection / structural types
lazy val SoftReferenceClass = requiredClass[java.lang.ref.SoftReference[_]]
lazy val WeakReferenceClass = requiredClass[java.lang.ref.WeakReference[_]]
- lazy val MethodClass = getClass(sn.MethodAsObject)
- def methodClass_setAccessible = getMember(MethodClass, nme.setAccessible)
+ lazy val MethodClass = getClassByName(sn.MethodAsObject)
+ def methodClass_setAccessible = getMemberMethod(MethodClass, nme.setAccessible)
lazy val EmptyMethodCacheClass = requiredClass[scala.runtime.EmptyMethodCache]
lazy val MethodCacheClass = requiredClass[scala.runtime.MethodCache]
- def methodCache_find = getMember(MethodCacheClass, nme.find_)
- def methodCache_add = getMember(MethodCacheClass, nme.add_)
+ def methodCache_find = getMemberMethod(MethodCacheClass, nme.find_)
+ def methodCache_add = getMemberMethod(MethodCacheClass, nme.add_)
// scala.reflect
- lazy val ReflectPackageClass = getMember(ScalaPackageClass, nme.reflect)
- lazy val ReflectPackage = requiredModule[scala.reflect.`package`.type]
- def ReflectMirror = getMember(ReflectPackage, nme.mirror)
- // [Eugene] is this a good place for ReflectMirrorPrefix?
- def ReflectMirrorPrefix = gen.mkAttributedRef(ReflectMirror) setType singleType(ReflectMirror.owner.thisPrefix, ReflectMirror)
-
- lazy val ApiUniverseClass = requiredClass[scala.reflect.api.Universe]
- def ApiUniverseReify = getMemberMethod(ApiUniverseClass, nme.reify)
+ lazy val ReflectPackage = requiredModule[scala.reflect.`package`.type]
+ def ReflectBasis = getMemberValue(ReflectPackage, nme.basis)
+ lazy val ReflectRuntimePackage = getPackageObjectIfDefined("scala.reflect.runtime") // defined in scala-reflect.jar, so we need to be careful
+ def ReflectRuntimeUniverse = if (ReflectRuntimePackage != NoSymbol) getMemberValue(ReflectRuntimePackage, nme.universe) else NoSymbol
+ def ReflectRuntimeCurrentMirror = if (ReflectRuntimePackage != NoSymbol) getMemberMethod(ReflectRuntimePackage, nme.currentMirror) else NoSymbol
lazy val PartialManifestClass = requiredClass[scala.reflect.ClassManifest[_]]
lazy val PartialManifestModule = requiredModule[scala.reflect.ClassManifest.type]
@@ -496,38 +449,39 @@ trait Definitions extends reflect.api.StandardDefinitions {
lazy val OptManifestClass = requiredClass[scala.reflect.OptManifest[_]]
lazy val NoManifest = requiredModule[scala.reflect.NoManifest.type]
- lazy val ExprClass = getMember(requiredClass[scala.reflect.api.Exprs], tpnme.Expr)
- def ExprTree = getMember(ExprClass, nme.tree)
- def ExprTpe = getMember(ExprClass, nme.tpe)
- def ExprEval = getMember(ExprClass, nme.eval)
- def ExprValue = getMember(ExprClass, nme.value)
- lazy val ExprModule = getMember(requiredClass[scala.reflect.api.Exprs], nme.Expr)
+ lazy val ExprsClass = getClassIfDefined("scala.reflect.api.Exprs") // defined in scala-reflect.jar, so we need to be careful
+ lazy val ExprClass = if (ExprsClass != NoSymbol) getMemberClass(ExprsClass, tpnme.Expr) else NoSymbol
+ def ExprSplice = if (ExprsClass != NoSymbol) getMemberMethod(ExprClass, nme.splice) else NoSymbol
+ def ExprValue = if (ExprsClass != NoSymbol) getMemberMethod(ExprClass, nme.value) else NoSymbol
+ lazy val ExprModule = if (ExprsClass != NoSymbol) getMemberModule(ExprsClass, nme.Expr) else NoSymbol
lazy val ArrayTagClass = requiredClass[scala.reflect.ArrayTag[_]]
- lazy val ErasureTagClass = requiredClass[scala.reflect.ErasureTag[_]]
lazy val ClassTagModule = requiredModule[scala.reflect.ClassTag[_]]
lazy val ClassTagClass = requiredClass[scala.reflect.ClassTag[_]]
- lazy val TypeTagsClass = requiredClass[scala.reflect.api.TypeTags]
+ lazy val TypeTagsClass = requiredClass[scala.reflect.base.TypeTags]
lazy val TypeTagClass = getMemberClass(TypeTagsClass, tpnme.TypeTag)
lazy val TypeTagModule = getMemberModule(TypeTagsClass, nme.TypeTag)
lazy val ConcreteTypeTagClass = getMemberClass(TypeTagsClass, tpnme.ConcreteTypeTag)
lazy val ConcreteTypeTagModule = getMemberModule(TypeTagsClass, nme.ConcreteTypeTag)
- def ArrayTagWrap = getMemberMethod(ArrayTagClass, nme.wrap)
- def ArrayTagNewArray = getMemberMethod(ArrayTagClass, nme.newArray)
- def ErasureTagErasure = getMemberMethod(ErasureTagClass, nme.erasure)
- def ClassTagTpe = getMemberMethod(ClassTagClass, nme.tpe)
- def TypeTagTpe = getMemberMethod(TypeTagClass, nme.tpe)
-
- lazy val MacroContextClass = requiredClass[scala.reflect.makro.Context]
- def MacroContextPrefix = getMember(MacroContextClass, nme.prefix)
- def MacroContextPrefixType = getMember(MacroContextClass, tpnme.PrefixType)
- def MacroContextMirror = getMember(MacroContextClass, nme.mirror)
- def MacroContextReify = getMember(MacroContextClass, nme.reify)
+ lazy val BaseUniverseClass = requiredClass[scala.reflect.base.Universe]
+ lazy val ApiUniverseClass = getClassIfDefined("scala.reflect.api.Universe") // defined in scala-reflect.jar, so we need to be careful
+ def ApiUniverseReify = if (ApiUniverseClass != NoSymbol) getMemberMethod(ApiUniverseClass, nme.reify) else NoSymbol
+ lazy val JavaUniverseClass = getClassIfDefined("scala.reflect.api.JavaUniverse") // defined in scala-reflect.jar, so we need to be careful
+
+ lazy val MirrorOfClass = requiredClass[scala.reflect.base.MirrorOf[_]]
+
+ lazy val TypeCreatorClass = requiredClass[scala.reflect.base.TypeCreator]
+ lazy val TreeCreatorClass = requiredClass[scala.reflect.base.TreeCreator]
+
+ lazy val MacroContextClass = getClassIfDefined("scala.reflect.makro.Context") // defined in scala-reflect.jar, so we need to be careful
+ def MacroContextPrefix = if (MacroContextClass != NoSymbol) getMemberMethod(MacroContextClass, nme.prefix) else NoSymbol
+ def MacroContextPrefixType = if (MacroContextClass != NoSymbol) getMemberType(MacroContextClass, tpnme.PrefixType) else NoSymbol
+ def MacroContextMirror = if (MacroContextClass != NoSymbol) getMemberMethod(MacroContextClass, nme.mirror) else NoSymbol
+ def MacroContextReify = if (MacroContextClass != NoSymbol) getMemberMethod(MacroContextClass, nme.reify) else NoSymbol
lazy val MacroImplAnnotation = requiredClass[scala.reflect.makro.internal.macroImpl]
lazy val MacroInternalPackage = getPackageObject("scala.reflect.makro.internal")
def MacroInternal_materializeArrayTag = getMemberMethod(MacroInternalPackage, nme.materializeArrayTag)
- def MacroInternal_materializeErasureTag = getMemberMethod(MacroInternalPackage, nme.materializeErasureTag)
def MacroInternal_materializeClassTag = getMemberMethod(MacroInternalPackage, nme.materializeClassTag)
def MacroInternal_materializeTypeTag = getMemberMethod(MacroInternalPackage, nme.materializeTypeTag)
def MacroInternal_materializeConcreteTypeTag = getMemberMethod(MacroInternalPackage, nme.materializeConcreteTypeTag)
@@ -536,18 +490,13 @@ trait Definitions extends reflect.api.StandardDefinitions {
lazy val ScalaLongSignatureAnnotation = requiredClass[scala.reflect.ScalaLongSignature]
// Option classes
- lazy val OptionClass: Symbol = requiredClass[Option[_]]
- lazy val SomeClass: Symbol = requiredClass[Some[_]]
- lazy val NoneModule: Symbol = requiredModule[scala.None.type]
- lazy val SomeModule: Symbol = requiredModule[scala.Some.type]
-
- // [Eugene] how do I make this work without casts?
- // private lazy val importerFromRm = self.mkImporter(rm)
- private lazy val importerFromRm = self.mkImporter(rm).asInstanceOf[self.Importer { val from: rm.type }]
+ lazy val OptionClass: ClassSymbol = requiredClass[Option[_]]
+ lazy val SomeClass: ClassSymbol = requiredClass[Some[_]]
+ lazy val NoneModule: ModuleSymbol = requiredModule[scala.None.type]
+ lazy val SomeModule: ModuleSymbol = requiredModule[scala.Some.type]
- def compilerTypeFromTag(t: rm.TypeTag[_]): Type = importerFromRm.importType(t.tpe)
-
- def compilerSymbolFromTag(t: rm.TypeTag[_]): Symbol = importerFromRm.importSymbol(t.sym)
+ def compilerTypeFromTag(tt: BaseUniverse # TypeTag[_]): Type = tt.in(rootMirror).tpe
+ def compilerSymbolFromTag(tt: BaseUniverse # TypeTag[_]): Symbol = tt.in(rootMirror).tpe.typeSymbol
// The given symbol represents either String.+ or StringAdd.+
def isStringAddition(sym: Symbol) = sym == String_+ || sym == StringAdd_+
@@ -569,20 +518,21 @@ trait Definitions extends reflect.api.StandardDefinitions {
def isNoneType(tp: Type) = tp.typeSymbol eq NoneModule
// Product, Tuple, Function, AbstractFunction
- private def mkArityArray(name: String, arity: Int, countFrom: Int = 1): Array[Symbol] = {
+ private def mkArityArray(name: String, arity: Int, countFrom: Int): Array[ClassSymbol] = {
val list = countFrom to arity map (i => getRequiredClass("scala." + name + i))
- if (countFrom == 0) list.toArray
- else (NoSymbol +: list).toArray
+ list.toArray
}
- private def aritySpecificType(symbolArray: Array[Symbol], args: List[Type], others: Type*): Type = {
+ def prepend[S >: ClassSymbol : ClassTag](elem0: S, elems: Array[ClassSymbol]): Array[S] = elem0 +: elems
+
+ private def aritySpecificType[S <: Symbol](symbolArray: Array[S], args: List[Type], others: Type*): Type = {
val arity = args.length
if (arity >= symbolArray.length) NoType
else appliedType(symbolArray(arity), args ++ others: _*)
}
val MaxTupleArity, MaxProductArity, MaxFunctionArity = 22
- lazy val ProductClass = { val arr = mkArityArray("Product", MaxProductArity) ; arr(0) = UnitClass ; arr }
- lazy val TupleClass = mkArityArray("Tuple", MaxTupleArity)
+ lazy val ProductClass: Array[ClassSymbol] = prepend(UnitClass, mkArityArray("Product", MaxProductArity, 1))
+ lazy val TupleClass: Array[Symbol] = prepend(NoSymbol, mkArityArray("Tuple", MaxTupleArity, 1))
lazy val FunctionClass = mkArityArray("Function", MaxFunctionArity, 0)
lazy val AbstractFunctionClass = mkArityArray("runtime.AbstractFunction", MaxFunctionArity, 0)
@@ -610,7 +560,7 @@ trait Definitions extends reflect.api.StandardDefinitions {
@deprecated("Use isTupleType", "2.10.0")
def isTupleTypeOrSubtype(tp: Type) = isTupleType(tp)
- def tupleField(n: Int, j: Int) = getMember(TupleClass(n), nme.productAccessorName(j))
+ def tupleField(n: Int, j: Int) = getMemberValue(TupleClass(n), nme.productAccessorName(j))
// NOTE: returns true for NoSymbol since it's included in the TupleClass array -- is this intensional?
def isTupleSymbol(sym: Symbol) = TupleClass contains unspecializedSymbol(sym)
def isProductNClass(sym: Symbol) = ProductClass contains sym
@@ -658,8 +608,8 @@ trait Definitions extends reflect.api.StandardDefinitions {
def Product_canEqual = getMemberMethod(ProductRootClass, nme.canEqual_)
// def Product_productElementName = getMemberMethod(ProductRootClass, nme.productElementName)
- def productProj(z:Symbol, j: Int): Symbol = getMember(z, nme.productAccessorName(j))
- def productProj(n: Int, j: Int): Symbol = productProj(ProductClass(n), j)
+ def productProj(z:Symbol, j: Int): TermSymbol = getMemberValue(z, nme.productAccessorName(j))
+ def productProj(n: Int, j: Int): TermSymbol = productProj(ProductClass(n), j)
/** returns true if this type is exactly ProductN[T1,...,Tn], not some subclass */
def isExactProductType(tp: Type): Boolean = isProductNClass(tp.typeSymbol)
@@ -675,7 +625,7 @@ trait Definitions extends reflect.api.StandardDefinitions {
case tp => tp
}
- def functionApply(n: Int) = getMember(FunctionClass(n), nme.apply)
+ def functionApply(n: Int) = getMemberMethod(FunctionClass(n), nme.apply)
def abstractFunctionForFunctionType(tp: Type) =
if (isFunctionType(tp)) abstractFunctionType(tp.typeArgs.init, tp.typeArgs.last)
@@ -746,9 +696,9 @@ trait Definitions extends reflect.api.StandardDefinitions {
lazy val ComparatorClass = getRequiredClass("scala.runtime.Comparator")
// System.ValueType
- lazy val ValueTypeClass: Symbol = getClass(sn.ValueType)
+ lazy val ValueTypeClass: ClassSymbol = getClassByName(sn.ValueType)
// System.MulticastDelegate
- lazy val DelegateClass: Symbol = getClass(sn.Delegate)
+ lazy val DelegateClass: ClassSymbol = getClassByName(sn.Delegate)
var Delegate_scalaCallers: List[Symbol] = List() // Syncnote: No protection necessary yet as only for .NET where reflection is not supported.
// Symbol -> (Symbol, Type): scalaCaller -> (scalaMethodSym, DelegateType)
// var Delegate_scalaCallerInfos: HashMap[Symbol, (Symbol, Type)] = _
@@ -787,7 +737,7 @@ trait Definitions extends reflect.api.StandardDefinitions {
// Since getClass is not actually a polymorphic method, this requires compiler
// participation. At the "Any" level, the return type is Class[_] as it is in
// java.lang.Object. Java also special cases the return type.
- lazy val Any_getClass = enterNewMethod(AnyClass, nme.getClass_, Nil, getMember(ObjectClass, nme.getClass_).tpe.resultType, DEFERRED)
+ lazy val Any_getClass = enterNewMethod(AnyClass, nme.getClass_, Nil, getMemberMethod(ObjectClass, nme.getClass_).tpe.resultType, DEFERRED)
lazy val Any_isInstanceOf = newT1NullaryMethod(AnyClass, nme.isInstanceOf_, FINAL)(_ => booltype)
lazy val Any_asInstanceOf = newT1NullaryMethod(AnyClass, nme.asInstanceOf_, FINAL)(_.typeConstructor)
@@ -887,14 +837,14 @@ trait Definitions extends reflect.api.StandardDefinitions {
)
lazy val String_+ = enterNewMethod(StringClass, nme.raw.PLUS, anyparam, stringtype, FINAL)
- def Object_getClass = getMember(ObjectClass, nme.getClass_)
- def Object_clone = getMember(ObjectClass, nme.clone_)
- def Object_finalize = getMember(ObjectClass, nme.finalize_)
- def Object_notify = getMember(ObjectClass, nme.notify_)
- def Object_notifyAll = getMember(ObjectClass, nme.notifyAll_)
- def Object_equals = getMember(ObjectClass, nme.equals_)
- def Object_hashCode = getMember(ObjectClass, nme.hashCode_)
- def Object_toString = getMember(ObjectClass, nme.toString_)
+ def Object_getClass = getMemberMethod(ObjectClass, nme.getClass_)
+ def Object_clone = getMemberMethod(ObjectClass, nme.clone_)
+ def Object_finalize = getMemberMethod(ObjectClass, nme.finalize_)
+ def Object_notify = getMemberMethod(ObjectClass, nme.notify_)
+ def Object_notifyAll = getMemberMethod(ObjectClass, nme.notifyAll_)
+ def Object_equals = getMemberMethod(ObjectClass, nme.equals_)
+ def Object_hashCode = getMemberMethod(ObjectClass, nme.hashCode_)
+ def Object_toString = getMemberMethod(ObjectClass, nme.toString_)
// boxed classes
lazy val ObjectRefClass = requiredClass[scala.runtime.ObjectRef[_]]
@@ -902,9 +852,9 @@ trait Definitions extends reflect.api.StandardDefinitions {
lazy val RuntimeStaticsModule = getRequiredModule("scala.runtime.Statics")
lazy val BoxesRunTimeModule = getRequiredModule("scala.runtime.BoxesRunTime")
lazy val BoxesRunTimeClass = BoxesRunTimeModule.moduleClass
- lazy val BoxedNumberClass = getClass(sn.BoxedNumber)
- lazy val BoxedCharacterClass = getClass(sn.BoxedCharacter)
- lazy val BoxedBooleanClass = getClass(sn.BoxedBoolean)
+ lazy val BoxedNumberClass = getClassByName(sn.BoxedNumber)
+ lazy val BoxedCharacterClass = getClassByName(sn.BoxedCharacter)
+ lazy val BoxedBooleanClass = getClassByName(sn.BoxedBoolean)
lazy val BoxedByteClass = requiredClass[java.lang.Byte]
lazy val BoxedShortClass = requiredClass[java.lang.Short]
lazy val BoxedIntClass = requiredClass[java.lang.Integer]
@@ -912,13 +862,13 @@ trait Definitions extends reflect.api.StandardDefinitions {
lazy val BoxedFloatClass = requiredClass[java.lang.Float]
lazy val BoxedDoubleClass = requiredClass[java.lang.Double]
- lazy val Boxes_isNumberOrBool = getDecl(BoxesRunTimeClass, nme.isBoxedNumberOrBoolean)
- lazy val Boxes_isNumber = getDecl(BoxesRunTimeClass, nme.isBoxedNumber)
+ lazy val Boxes_isNumberOrBool = getDecl(BoxesRunTimeClass, nme.isBoxedNumberOrBoolean)
+ lazy val Boxes_isNumber = getDecl(BoxesRunTimeClass, nme.isBoxedNumber)
lazy val BoxedUnitClass = requiredClass[scala.runtime.BoxedUnit]
lazy val BoxedUnitModule = getRequiredModule("scala.runtime.BoxedUnit")
- def BoxedUnit_UNIT = getMember(BoxedUnitModule, nme.UNIT)
- def BoxedUnit_TYPE = getMember(BoxedUnitModule, nme.TYPE_)
+ def BoxedUnit_UNIT = getMemberValue(BoxedUnitModule, nme.UNIT)
+ def BoxedUnit_TYPE = getMemberValue(BoxedUnitModule, nme.TYPE_)
// Annotation base classes
lazy val AnnotationClass = requiredClass[scala.annotation.Annotation]
@@ -969,7 +919,7 @@ trait Definitions extends reflect.api.StandardDefinitions {
// Language features
lazy val languageFeatureModule = getRequiredModule("scala.languageFeature")
- lazy val experimentalModule = getMember(languageFeatureModule, nme.experimental)
+ lazy val experimentalModule = getMemberModule(languageFeatureModule, nme.experimental)
lazy val MacrosFeature = getLanguageFeature("macros", experimentalModule)
lazy val DynamicsFeature = getLanguageFeature("dynamics")
lazy val PostfixOpsFeature = getLanguageFeature("postfixOps")
@@ -988,99 +938,27 @@ trait Definitions extends reflect.api.StandardDefinitions {
BeanGetterTargetClass, BeanSetterTargetClass
)
- lazy val AnnotationDefaultAttr: Symbol = {
+ lazy val AnnotationDefaultAttr: ClassSymbol = {
val attr = enterNewClass(RuntimePackageClass, tpnme.AnnotationDefaultATTR, List(AnnotationClass.tpe))
// This attribute needs a constructor so that modifiers in parsed Java code make sense
attr.info.decls enter attr.newClassConstructor(NoPosition)
attr
}
- def getPackageObjectClass(fullname: String): Symbol =
- getPackageObject(fullname).companionClass
-
- def getPackageObject(fullname: String): Symbol =
- getModule(newTermName(fullname)).info member nme.PACKAGE
-
- def getModule(fullname: Name): ModuleSymbol =
- getModuleOrClass(fullname.toTermName) match {
- case x: ModuleSymbol => x
- case _ => MissingRequirementError.notFound("object " + fullname)
- }
-
- def getPackage(fullname: Name): PackageSymbol =
- getModuleOrClass(fullname.toTermName) match {
- case x: PackageSymbol => x
- case _ => MissingRequirementError.notFound("package " + fullname)
- }
- @inline private def wrapMissing(body: => Symbol): Symbol =
- try body
- catch { case _: MissingRequirementError => NoSymbol }
-
private def fatalMissingSymbol(owner: Symbol, name: Name, what: String = "member") = {
throw new FatalError(owner + " does not have a " + what + " " + name)
}
- @deprecated("Use getClassByName", "2.10.0")
- def getClass(fullname: Name): Symbol = getClassByName(fullname)
-
- def getRequiredPackage(fullname: String): PackageSymbol =
- getPackage(newTermNameCached(fullname))
-
- def getRequiredModule(fullname: String): ModuleSymbol =
- getModule(newTermNameCached(fullname))
-
- def erasureName[T: ErasureTag] : String = {
- /** We'd like the String representation to be a valid
- * scala type, so we have to decode the jvm's secret language.
- */
- def erasureString(clazz: Class[_]): String = {
- if (clazz.isArray) "Array[" + erasureString(clazz.getComponentType) + "]"
- else clazz.getName
- }
- erasureString(implicitly[ErasureTag[T]].erasure)
- }
-
- def requiredClass[T: ClassTag] : ClassSymbol = getRequiredClass(erasureName[T])
-
- // TODO: What syntax do we think should work here? Say you have an object
- // like scala.Predef. You can't say requiredModule[scala.Predef] since there's
- // no accompanying Predef class, and if you say requiredModule[scala.Predef.type]
- // the name found via the erasure is scala.Predef$. For now I am
- // removing the trailing $, but I think that classTag should have
- // a method which returns a usable name, one which doesn't expose this
- // detail of the backend.
- def requiredModule[T: ClassTag] : ModuleSymbol =
- getRequiredModule(erasureName[T] stripSuffix "$")
-
- def getRequiredClass(fullname: String): ClassSymbol =
- getClassByName(newTypeNameCached(fullname)) match {
- case x: ClassSymbol => x
- case _ => MissingRequirementError.notFound("class " + fullname)
- }
-
- def getClassIfDefined(fullname: String): Symbol =
- getClassIfDefined(newTypeName(fullname))
-
- def getClassIfDefined(fullname: Name): Symbol =
- wrapMissing(getClass(fullname.toTypeName))
-
- def getModuleIfDefined(fullname: String): Symbol =
- getModuleIfDefined(newTermName(fullname))
-
- def getModuleIfDefined(fullname: Name): Symbol =
- wrapMissing(getModule(fullname.toTermName))
-
- def getLanguageFeature(name: String, owner: Symbol = languageFeatureModule) =
+ def getLanguageFeature(name: String, owner: Symbol = languageFeatureModule): Symbol =
+ // [Eugene++] `getMemberClass` leads to crashes in mixin:
+ // "object languageFeature does not have a member class implicitConversions"
+ // that's because by that time `implicitConversions` becomes a module
+ // getMemberClass(owner, newTypeName(name))
getMember(owner, newTypeName(name))
def termMember(owner: Symbol, name: String): Symbol = owner.info.member(newTermName(name))
def typeMember(owner: Symbol, name: String): Symbol = owner.info.member(newTypeName(name))
- def findMemberFromRoot(fullName: Name): Symbol = {
- val segs = nme.segments(fullName.toString, fullName.isTermName)
- if (segs.isEmpty) NoSymbol
- else findNamedMember(segs.tail, definitions.RootClass.info member segs.head)
- }
def findNamedMember(fullName: Name, root: Symbol): Symbol = {
val segs = nme.segments(fullName.toString, fullName.isTermName)
if (segs.isEmpty || segs.head != root.simpleName) NoSymbol
@@ -1100,22 +978,81 @@ trait Definitions extends reflect.api.StandardDefinitions {
else fatalMissingSymbol(owner, name)
}
}
+ def getMemberValue(owner: Symbol, name: Name): TermSymbol = {
+ // [Eugene++] should be a ClassCastException instead?
+ getMember(owner, name.toTermName) match {
+ case x: TermSymbol => x
+ case _ => fatalMissingSymbol(owner, name, "member value")
+ }
+ }
def getMemberModule(owner: Symbol, name: Name): ModuleSymbol = {
+ // [Eugene++] should be a ClassCastException instead?
getMember(owner, name.toTermName) match {
case x: ModuleSymbol => x
case _ => fatalMissingSymbol(owner, name, "member object")
}
}
+ def getMemberType(owner: Symbol, name: Name): TypeSymbol = {
+ // [Eugene++] should be a ClassCastException instead?
+ getMember(owner, name.toTypeName) match {
+ case x: TypeSymbol => x
+ case _ => fatalMissingSymbol(owner, name, "member type")
+ }
+ }
def getMemberClass(owner: Symbol, name: Name): ClassSymbol = {
+ // [Eugene++] should be a ClassCastException instead?
+ val y = getMember(owner, name.toTypeName)
getMember(owner, name.toTypeName) match {
case x: ClassSymbol => x
case _ => fatalMissingSymbol(owner, name, "member class")
}
}
- def getMemberMethod(owner: Symbol, name: Name): MethodSymbol = {
+ def getMemberMethod(owner: Symbol, name: Name): TermSymbol = {
+ // [Eugene++] is this a bug?
+ //
+ // System.err.println(result.getClass)
+ // System.err.println(result.flags)
+ // System.err.println("isMethod = " + result.isMethod)
+ // System.err.println("isTerm = " + result.isTerm)
+ // System.err.println("isValue = " + result.isValue)
+ // result.asMethodSymbol
+ //
+ // prints this:
+ //
+ // quick.lib:
+ // [javac] Compiling 1 source file to C:\Projects\KeplerUnderRefactoring\build\quick\classes\library
+ // [scalacfork] Compiling 769 files to C:\Projects\KeplerUnderRefactoring\build\quick\classes\library
+ // [scalacfork] class scala.reflect.internal.Symbols$TermSymbol
+ // [scalacfork] 8589934592
+ // [scalacfork] isMethod = false
+ // [scalacfork] isTerm = true
+ // [scalacfork] isValue = true
+ // [scalacfork]
+ // [scalacfork] while compiling: C:\Projects\KeplerUnderRefactoring\src\library\scala\LowPriorityImplicits.scala
+ // [scalacfork] current phase: cleanup
+ // [scalacfork] library version: version 2.10.0-20120507-185519-665d1d9127
+ // [scalacfork] compiler version: version 2.10.0-20120507-185519-665d1d9127
+ // [scalacfork] reconstructed args: -Xmacros -classpath C:\\Projects\\KeplerUnderRefactoring\\build\\quick\\classes\\library;C:\\Projects\\KeplerUnderRefactoring\\lib\\forkjoin.jar -d C:\\Projects\\KeplerUnderRefactoring\\build\\quick\\classes\\library -sourcepath C:\\Projects\\KeplerUnderRefactoring\\src\\library
+ // [scalacfork]
+ // [scalacfork] unhandled exception while transforming LowPriorityImplicits.scala
+ // [scalacfork] error:
+ // [scalacfork] while compiling: C:\Projects\KeplerUnderRefactoring\src\library\scala\LowPriorityImplicits.scala
+ // [scalacfork] current phase: cleanup
+ // [scalacfork] library version: version 2.10.0-20120507-185519-665d1d9127
+ // [scalacfork] compiler version: version 2.10.0-20120507-185519-665d1d9127
+ // [scalacfork] reconstructed args: -Xmacros -classpath C:\\Projects\\KeplerUnderRefactoring\\build\\quick\\classes\\library;C:\\Projects\\KeplerUnderRefactoring\\lib\\forkjoin.jar -d C:\\Projects\\KeplerUnderRefactoring\\build\\quick\\classes\\library -sourcepath C:\\Projects\\KeplerUnderRefactoring\\src\\library
+ // [scalacfork]
+ // [scalacfork] uncaught exception during compilation: java.lang.ClassCastException
+ // [scalacfork] error: java.lang.ClassCastException: value apply
+ // [scalacfork] at scala.reflect.base.Symbols$SymbolBase$class.asMethodSymbol(Symbols.scala:118)
+ // [scalacfork] at scala.reflect.internal.Symbols$SymbolContextApiImpl.asMethodSymbol(Symbols.scala:63)
+ // [scalacfork] at scala.reflect.internal.Definitions$DefinitionsClass.Symbol_apply(Definitions.scala:381)
+
+ // [Eugene++] should be a ClassCastException instead?
getMember(owner, name.toTermName) match {
- case x: MethodSymbol => x
- case _ => fatalMissingSymbol(owner, name, "method")
+ // case x: MethodSymbol => x
+ case x: TermSymbol => x
+ case _ => fatalMissingSymbol(owner, name, "method")
}
}
@@ -1135,34 +1072,6 @@ trait Definitions extends reflect.api.StandardDefinitions {
def packageExists(packageName: String): Boolean =
getModuleIfDefined(packageName).isPackage
- private def getModuleOrClass(path: Name, len: Int): Symbol = {
- val point = path lastPos('.', len - 1)
- val owner =
- if (point > 0) getModuleOrClass(path.toTermName, point)
- else RootClass
- val name = path subName (point + 1, len)
- val sym = owner.info member name
- val result = if (path.isTermName) sym.suchThat(_ hasFlag MODULE) else sym
- if (result != NoSymbol) result
- else {
- if (settings.debug.value) { log(sym.info); log(sym.info.members) }//debug
- missingHook(owner, name) orElse {
- MissingRequirementError.notFound((if (path.isTermName) "object " else "class ")+path)
- }
- }
- }
-
- /** If you're looking for a class, pass a type name.
- * If a module, a term name.
- */
- private def getModuleOrClass(path: Name): Symbol = getModuleOrClass(path, path.length)
-
- def getClassByName(fullname: Name): Symbol = {
- var result = getModuleOrClass(fullname.toTypeName)
- while (result.isAliasType) result = result.info.typeSymbol
- result
- }
-
private def newAlias(owner: Symbol, name: TypeName, alias: Type): AliasTypeSymbol =
owner.newAliasType(name) setInfoAndEnter alias
@@ -1221,7 +1130,7 @@ trait Definitions extends reflect.api.StandardDefinitions {
def unboxedValueClass(sym: Symbol): Symbol =
if (isPrimitiveValueClass(sym)) sym
else if (sym == BoxedUnitClass) UnitClass
- else boxedClass.map(_.swap).getOrElse(sym, NoSymbol)
+ else boxedClass.map(kvp => (kvp._2: Symbol, kvp._1)).getOrElse(sym, NoSymbol)
/** Is type's symbol a numeric value class? */
def isNumericValueType(tp: Type): Boolean = tp match {
@@ -1250,28 +1159,7 @@ trait Definitions extends reflect.api.StandardDefinitions {
else flatNameString(etp.typeSymbol, '.')
}
- /** getModule2/getClass2 aren't needed at present but may be again,
- * so for now they're mothballed.
- */
- // def getModule2(name1: Name, name2: Name) = {
- // try getModuleOrClass(name1.toTermName)
- // catch { case ex1: FatalError =>
- // try getModuleOrClass(name2.toTermName)
- // catch { case ex2: FatalError => throw ex1 }
- // }
- // }
- // def getClass2(name1: Name, name2: Name) = {
- // try {
- // val result = getModuleOrClass(name1.toTypeName)
- // if (result.isAliasType) getClass(name2) else result
- // }
- // catch { case ex1: FatalError =>
- // try getModuleOrClass(name2.toTypeName)
- // catch { case ex2: FatalError => throw ex1 }
- // }
- // }
-
- /** Surgery on the value classes. Without this, AnyVals defined in source
+ /** Surgery on the value classes. Without this, AnyVals defined in source
* files end up with an AnyRef parent. It is likely there is a better way
* to evade that AnyRef.
*/
@@ -1285,17 +1173,6 @@ trait Definitions extends reflect.api.StandardDefinitions {
def init() {
if (isInitialized) return
- // Still fiddling with whether it's cleaner to do some of this setup here
- // or from constructors. The latter approach tends to invite init order issues.
- EmptyPackageClass setInfo ClassInfoType(Nil, newPackageScope(EmptyPackageClass), EmptyPackageClass)
- EmptyPackage setInfo EmptyPackageClass.tpe
-
- connectModuleToClass(EmptyPackage, EmptyPackageClass)
- connectModuleToClass(RootPackage, RootClass)
-
- RootClass.info.decls enter EmptyPackage
- RootClass.info.decls enter RootPackage
-
val forced = List( // force initialization of every symbol that is entered as a side effect
AnnotationDefaultAttr, // #2264
RepeatedParamClass,
@@ -1334,7 +1211,7 @@ trait Definitions extends reflect.api.StandardDefinitions {
} //init
var nbScalaCallers: Int = 0
- def newScalaCaller(delegateType: Type): Symbol = {
+ def newScalaCaller(delegateType: Type): MethodSymbol = {
assert(forMSIL, "scalaCallers can only be created if target is .NET")
// object: reference to object on which to call (scala-)method
val paramTypes: List[Type] = List(ObjectClass.tpe)
diff --git a/src/compiler/scala/reflect/internal/FlagSets.scala b/src/compiler/scala/reflect/internal/FlagSets.scala
new file mode 100644
index 0000000000..0354d2513c
--- /dev/null
+++ b/src/compiler/scala/reflect/internal/FlagSets.scala
@@ -0,0 +1,66 @@
+package scala.reflect
+package internal
+
+import language.implicitConversions
+
+trait FlagSets extends api.FlagSets { self: SymbolTable =>
+
+ type FlagSet = Long
+ implicit val FlagSetTag = ClassTag[FlagSet](classOf[FlagSet])
+
+ implicit def addFlagOps(left: FlagSet): FlagOps =
+ new FlagOpsImpl(left)
+
+ private class FlagOpsImpl(left: Long) extends FlagOps {
+ def | (right: Long): Long = left | right
+ def & (right: Long): Long = left & right
+ def containsAll (right: Long): Boolean = (right & ~left) == 0
+ }
+
+ val NoFlags: FlagSet = 0L
+
+ trait FlagValues extends FlagValuesApi
+
+ object Flag extends FlagValues {
+ val TRAIT : FlagSet = Flags.TRAIT
+ val MODULE : FlagSet = Flags.MODULE
+ val MUTABLE : FlagSet = Flags.MUTABLE
+ val PACKAGE : FlagSet = Flags.PACKAGE
+ val METHOD : FlagSet = Flags.METHOD
+ val MACRO : FlagSet = Flags.MACRO
+ val DEFERRED : FlagSet = Flags.DEFERRED
+ val ABSTRACT : FlagSet = Flags.ABSTRACT
+ val FINAL : FlagSet = Flags.FINAL
+ val SEALED : FlagSet = Flags.SEALED
+ val IMPLICIT : FlagSet = Flags.IMPLICIT
+ val LAZY : FlagSet = Flags.LAZY
+ val OVERRIDE : FlagSet = Flags.OVERRIDE
+ val PRIVATE : FlagSet = Flags.PRIVATE
+ val PROTECTED : FlagSet = Flags.PROTECTED
+ val CASE : FlagSet = Flags.CASE
+ val ABSOVERRIDE : FlagSet = Flags.ABSOVERRIDE
+ val BYNAMEPARAM : FlagSet = Flags.BYNAMEPARAM
+ val PARAM : FlagSet = Flags.PARAM
+ val PARAMACCESSOR : FlagSet = Flags.PARAMACCESSOR
+ val CASEACCESSOR : FlagSet = Flags.CASEACCESSOR
+ val COVARIANT : FlagSet = Flags.COVARIANT
+ val CONTRAVARIANT : FlagSet = Flags.CONTRAVARIANT
+ val DEFAULTPARAM : FlagSet = Flags.DEFAULTPARAM
+ val INTERFACE : FlagSet = Flags.INTERFACE
+
+ def union(flags: FlagSet*): FlagSet = {
+ var acc = 0L
+ for (flag <- flags) acc |= flag
+ acc
+ }
+
+ def intersection(flags: FlagSet*): FlagSet = {
+ var acc = -1L
+ for (flag <- flags) acc &= flag
+ acc
+ }
+
+ def containsAll(superset: FlagSet, subset: FlagSet): Boolean =
+ (subset & ~superset) == 0
+ }
+}
diff --git a/src/compiler/scala/reflect/internal/Flags.scala b/src/compiler/scala/reflect/internal/Flags.scala
index e6820cf78a..37e5a23819 100644
--- a/src/compiler/scala/reflect/internal/Flags.scala
+++ b/src/compiler/scala/reflect/internal/Flags.scala
@@ -6,7 +6,6 @@
package scala.reflect
package internal
-import api.Modifier
import scala.collection.{ mutable, immutable }
// Flags at each index of a flags Long. Those marked with /M are used in
@@ -479,46 +478,6 @@ class Flags extends ModifierFlags {
front.toList ++ (all filterNot (front contains _))
}
final val rawFlagPickledOrder: Array[Long] = pickledListOrder.toArray
-
- def flagOfModifier(mod: Modifier): Long = mod match {
- case Modifier.`protected` => PROTECTED
- case Modifier.`private` => PRIVATE
- case Modifier.`override` => OVERRIDE
- case Modifier.`abstract` => ABSTRACT
- case Modifier.`final` => FINAL
- case Modifier.`sealed` => SEALED
- case Modifier.`implicit` => IMPLICIT
- case Modifier.`lazy` => LAZY
- case Modifier.`case` => CASE
- case Modifier.`trait` => TRAIT
- case Modifier.deferred => DEFERRED
- case Modifier.interface => INTERFACE
- case Modifier.mutable => MUTABLE
- case Modifier.parameter => PARAM
- case Modifier.`macro` => MACRO
- case Modifier.covariant => COVARIANT
- case Modifier.contravariant => CONTRAVARIANT
- case Modifier.preSuper => PRESUPER
- case Modifier.abstractOverride => ABSOVERRIDE
- case Modifier.local => LOCAL
- case Modifier.java => JAVA
- case Modifier.static => STATIC
- case Modifier.caseAccessor => CASEACCESSOR
- case Modifier.defaultParameter => DEFAULTPARAM
- case Modifier.defaultInit => DEFAULTINIT
- case Modifier.paramAccessor => PARAMACCESSOR
- case Modifier.bynameParameter => BYNAMEPARAM
- case _ => 0
- }
-
- def flagsOfModifiers(mods: List[Modifier]): Long =
- (mods :\ 0L) { (mod, curr) => curr | flagOfModifier(mod) }
-
- def modifierOfFlag(flag: Long): Option[Modifier] =
- Modifier.values find { mod => flagOfModifier(mod) == flag }
-
- def modifiersOfFlags(flags: Long): List[Modifier] =
- pickledListOrder map (mask => modifierOfFlag(flags & mask)) flatMap { mod => mod }
}
object Flags extends Flags { }
diff --git a/src/compiler/scala/reflect/internal/FreeVars.scala b/src/compiler/scala/reflect/internal/FreeVars.scala
deleted file mode 100644
index 8b6e8b61f3..0000000000
--- a/src/compiler/scala/reflect/internal/FreeVars.scala
+++ /dev/null
@@ -1,60 +0,0 @@
-package scala.reflect
-package internal
-
-trait FreeVars extends api.FreeVars {
- self: SymbolTable =>
-
- object FreeTerm extends FreeTermExtractor {
- def unapply(freeTerm: FreeTerm): Option[(TermName, Type, Any, String)] =
- Some(freeTerm.name, freeTerm.info, freeTerm.value, freeTerm.origin)
- }
-
- object FreeType extends FreeTypeExtractor {
- def unapply(freeType: FreeType): Option[(TypeName, Type, String)] =
- Some(freeType.name, freeType.info, freeType.origin)
- }
-
- // [Eugene] am I doing this right?
- def freeTerms(tree: Tree): List[FreeTerm] = {
- def isFreeTermSym(sym: Symbol) = sym != null && sym.isFreeTerm
- def isFreeTermTpe(t: Type) = t != null && isFreeTermSym(t.termSymbol)
-
- val buf = collection.mutable.Set[Symbol]()
- tree foreach (sub => {
- if (sub.tpe != null) buf ++= (sub.tpe collect { case tpe if isFreeTermTpe(tpe) => tpe.typeSymbol })
- if (sub.symbol != null && isFreeTermSym(sub.symbol)) buf += sub.symbol
- })
-
- buf.toList.collect{ case fty: FreeTerm => fty }
- }
-
- // [Eugene] am I doing this right?
- def freeTypes(tree: Tree): List[FreeType] = {
- def isFreeTypeSym(sym: Symbol) = sym != null && sym.isFreeType
- def isFreeTypeTpe(t: Type) = t != null && isFreeTypeSym(t.typeSymbol)
-
- val buf = collection.mutable.Set[Symbol]()
- tree foreach (sub => {
- if (sub.tpe != null) buf ++= (sub.tpe collect { case tpe if isFreeTypeTpe(tpe) => tpe.typeSymbol })
- if (sub.symbol != null && isFreeTypeSym(sub.symbol)) buf += sub.symbol
- })
-
- buf.toList.collect{ case fty: FreeType => fty }
- }
-
- // todo. also update tpe's of dependent free vars
- // e.g. if we substitute free$C, then free$C$this should have its info updated
- // todo. should also transform typetags of types dependent on that free type?
- // [Eugene] how do I check that the substitution is legal w.r.t fty.info?
- def substituteFreeTypes(tree0: Tree, subs: Map[FreeType, Type]): Tree = {
- val tree = tree0.duplicate
- new TreeTypeSubstituter(subs.keys.toList, subs.values.toList).traverse(tree)
- tree
- }
-
- // [Eugene] how do I check that the substitution is legal w.r.t fty.info?
- def substituteFreeTypes(tpe0: Type, subs: Map[FreeType, Type]): Type = {
- val tpe = tpe0 // [Eugene] tpe0.duplicate?
- tpe.subst(subs.keys.toList, subs.values.toList)
- }
-} \ No newline at end of file
diff --git a/src/compiler/scala/reflect/internal/HasFlags.scala b/src/compiler/scala/reflect/internal/HasFlags.scala
index 0937577ca3..c7c0882209 100644
--- a/src/compiler/scala/reflect/internal/HasFlags.scala
+++ b/src/compiler/scala/reflect/internal/HasFlags.scala
@@ -102,6 +102,7 @@ trait HasFlags {
def isOverride = hasFlag(OVERRIDE)
def isParamAccessor = hasFlag(PARAMACCESSOR)
def isPrivate = hasFlag(PRIVATE)
+ def isPackage = hasFlag(PACKAGE)
def isPrivateLocal = hasAllFlags(PrivateLocal)
def isProtected = hasFlag(PROTECTED)
def isProtectedLocal = hasAllFlags(ProtectedLocal)
diff --git a/src/compiler/scala/reflect/internal/Importers.scala b/src/compiler/scala/reflect/internal/Importers.scala
index 6d6a0ec317..72b6288d87 100644
--- a/src/compiler/scala/reflect/internal/Importers.scala
+++ b/src/compiler/scala/reflect/internal/Importers.scala
@@ -2,6 +2,7 @@ package scala.reflect
package internal
import scala.collection.mutable.WeakHashMap
+// todo: move importers to a mirror
trait Importers { self: SymbolTable =>
// [Eugene] possible to make this less cast-heavy?
@@ -70,9 +71,9 @@ trait Importers { self: SymbolTable =>
linkReferenced(myowner.newMethod(myname, mypos, myflags), x, importSymbol)
case x: from.ModuleSymbol =>
linkReferenced(myowner.newModuleSymbol(myname, mypos, myflags), x, importSymbol)
- case x: from.FreeTerm =>
+ case x: from.FreeTermSymbol =>
newFreeTermSymbol(importName(x.name).toTermName, importType(x.info), x.value, x.flags, x.origin)
- case x: from.FreeType =>
+ case x: from.FreeTypeSymbol =>
newFreeTypeSymbol(importName(x.name).toTypeName, importType(x.info), x.value, x.flags, x.origin)
case x: from.TermSymbol =>
linkReferenced(myowner.newValue(myname, mypos, myflags), x, importSymbol)
@@ -124,7 +125,7 @@ trait Importers { self: SymbolTable =>
else if (sym == from.NoSymbol)
NoSymbol
else if (sym.isRoot)
- definitions.RootClass
+ rootMirror.RootClass // !!! replace with actual mirror when we move importers to the mirror
else {
val name = sym.name
val owner = sym.owner
@@ -376,8 +377,6 @@ trait Importers { self: SymbolTable =>
new ApplyToImplicitArgs(importTree(fun), args map importTree)
case _: from.ApplyImplicitView =>
new ApplyImplicitView(importTree(fun), args map importTree)
- case _: from.ApplyConstructor =>
- new ApplyConstructor(importTree(fun), args map importTree)
case _ =>
new Apply(importTree(fun), args map importTree)
}
diff --git a/src/compiler/scala/reflect/internal/Mirrors.scala b/src/compiler/scala/reflect/internal/Mirrors.scala
new file mode 100644
index 0000000000..fa411bc935
--- /dev/null
+++ b/src/compiler/scala/reflect/internal/Mirrors.scala
@@ -0,0 +1,243 @@
+/* NSC -- new Scala compiler
+ * Copyright 2005-2011 LAMP/EPFL
+ * Copyright 2005-2011 LAMP/EPFL
+ * @author Martin Odersky
+ */
+
+package scala.reflect
+package internal
+
+import Flags._
+
+trait Mirrors extends api.Mirrors {
+ self: SymbolTable =>
+
+ override type Mirror >: Null <: RootsBase
+
+ abstract class RootsBase(rootOwner: Symbol) extends MirrorOf[Mirrors.this.type] { thisMirror =>
+
+ protected[scala] def rootLoader: LazyType
+
+ val RootClass: ClassSymbol
+ val RootPackage: ModuleSymbol
+ val EmptyPackageClass: ClassSymbol
+ val EmptyPackage: ModuleSymbol
+
+ def findMemberFromRoot(fullName: Name): Symbol = {
+ val segs = nme.segments(fullName.toString, fullName.isTermName)
+ if (segs.isEmpty) NoSymbol
+ else definitions.findNamedMember(segs.tail, RootClass.info member segs.head)
+ }
+
+ /** Todo: organize similar to mkStatic in reflect.Base */
+ private def getModuleOrClass(path: Name, len: Int): Symbol = {
+ val point = path lastPos('.', len - 1)
+ val owner =
+ if (point > 0) getModuleOrClass(path.toTermName, point)
+ else RootClass
+ val name = path subName (point + 1, len)
+ val sym = owner.info member name
+ val result = if (path.isTermName) sym.suchThat(_ hasFlag MODULE) else sym
+ if (result != NoSymbol) result
+ else {
+ if (settings.debug.value) { log(sym.info); log(sym.info.members) }//debug
+ mirrorMissingHook(owner, name) orElse symbolTableMissingHook(owner, name) orElse {
+ MissingRequirementError.notFound((if (path.isTermName) "object " else "class ")+path+" in "+thisMirror)
+ }
+ }
+ }
+
+ protected def mirrorMissingHook(owner: Symbol, name: Name): Symbol = NoSymbol
+
+ protected def symbolTableMissingHook(owner: Symbol, name: Name): Symbol = self.missingHook(owner, name)
+
+ /** If you're looking for a class, pass a type name.
+ * If a module, a term name.
+ */
+ private def getModuleOrClass(path: Name): Symbol = getModuleOrClass(path, path.length)
+
+ override def staticClass(fullName: String): ClassSymbol = getRequiredClass(fullName)
+
+ // todo: get rid of most creation methods and keep just staticClass/Module/Package
+
+ def getClassByName(fullname: Name): ClassSymbol = {
+ var result = getModuleOrClass(fullname.toTypeName)
+ while (result.isAliasType) result = result.info.typeSymbol
+ result match {
+ case x: ClassSymbol => x
+ case _ => MissingRequirementError.notFound("class " + fullname)
+ }
+ }
+
+ override def staticModule(fullName: String): ModuleSymbol = getRequiredModule(fullName)
+
+ def getModule(fullname: Name): ModuleSymbol =
+ // [Eugene++] should be a ClassCastException instead?
+ getModuleOrClass(fullname.toTermName) match {
+ case x: ModuleSymbol => x
+ case _ => MissingRequirementError.notFound("object " + fullname)
+ }
+
+ def getPackage(fullname: Name): ModuleSymbol = getModule(fullname)
+
+ def getRequiredPackage(fullname: String): ModuleSymbol =
+ getPackage(newTermNameCached(fullname))
+
+ @deprecated("Use getClassByName", "2.10.0")
+ def getClass(fullname: Name): ClassSymbol = getClassByName(fullname)
+
+ def getRequiredClass(fullname: String): ClassSymbol =
+ getClassByName(newTypeNameCached(fullname)) match {
+ case x: ClassSymbol => x
+ case _ => MissingRequirementError.notFound("class " + fullname)
+ }
+
+ def getRequiredModule(fullname: String): ModuleSymbol =
+ getModule(newTermNameCached(fullname))
+
+ def erasureName[T: ClassTag] : String = {
+ /** We'd like the String representation to be a valid
+ * scala type, so we have to decode the jvm's secret language.
+ */
+ def erasureString(clazz: Class[_]): String = {
+ if (clazz.isArray) "Array[" + erasureString(clazz.getComponentType) + "]"
+ else clazz.getName
+ }
+ erasureString(classTag[T].erasure)
+ }
+
+ def requiredClass[T: ClassTag] : ClassSymbol =
+ getRequiredClass(erasureName[T])
+
+ // TODO: What syntax do we think should work here? Say you have an object
+ // like scala.Predef. You can't say requiredModule[scala.Predef] since there's
+ // no accompanying Predef class, and if you say requiredModule[scala.Predef.type]
+ // the name found via the erasure is scala.Predef$. For now I am
+ // removing the trailing $, but I think that classTag should have
+ // a method which returns a usable name, one which doesn't expose this
+ // detail of the backend.
+ def requiredModule[T: ClassTag] : ModuleSymbol =
+ getRequiredModule(erasureName[T] stripSuffix "$")
+
+ def getClassIfDefined(fullname: String): Symbol =
+ getClassIfDefined(newTypeName(fullname))
+
+ def getClassIfDefined(fullname: Name): Symbol =
+ wrapMissing(getClassByName(fullname.toTypeName))
+
+ def getModuleIfDefined(fullname: String): Symbol =
+ getModuleIfDefined(newTermName(fullname))
+
+ def getModuleIfDefined(fullname: Name): Symbol =
+ wrapMissing(getModule(fullname.toTermName))
+
+ def getPackageObject(fullname: String): ModuleSymbol =
+ (getModule(newTermName(fullname)).info member nme.PACKAGE) match {
+ case x: ModuleSymbol => x
+ case _ => MissingRequirementError.notFound("package object " + fullname)
+ }
+
+ def getPackageObjectIfDefined(fullname: String): Symbol = {
+ val module = getModuleIfDefined(newTermName(fullname))
+ if (module == NoSymbol) NoSymbol
+ else {
+ val packageObject = module.info member nme.PACKAGE
+ packageObject match {
+ case x: ModuleSymbol => x
+ case _ => NoSymbol
+ }
+ }
+ }
+
+ @inline private def wrapMissing(body: => Symbol): Symbol =
+ try body
+ catch { case _: MissingRequirementError => NoSymbol }
+
+ /** getModule2/getClass2 aren't needed at present but may be again,
+ * so for now they're mothballed.
+ */
+ // def getModule2(name1: Name, name2: Name) = {
+ // try getModuleOrClass(name1.toTermName)
+ // catch { case ex1: FatalError =>
+ // try getModuleOrClass(name2.toTermName)
+ // catch { case ex2: FatalError => throw ex1 }
+ // }
+ // }
+ // def getClass2(name1: Name, name2: Name) = {
+ // try {
+ // val result = getModuleOrClass(name1.toTypeName)
+ // if (result.isAliasType) getClass(name2) else result
+ // }
+ // catch { case ex1: FatalError =>
+ // try getModuleOrClass(name2.toTypeName)
+ // catch { case ex2: FatalError => throw ex1 }
+ // }
+ // }
+
+ def init() {
+ // Still fiddling with whether it's cleaner to do some of this setup here
+ // or from constructors. The latter approach tends to invite init order issues.
+
+ EmptyPackageClass setInfo ClassInfoType(Nil, newPackageScope(EmptyPackageClass), EmptyPackageClass)
+ EmptyPackage setInfo EmptyPackageClass.tpe
+
+ connectModuleToClass(EmptyPackage, EmptyPackageClass)
+ connectModuleToClass(RootPackage, RootClass)
+
+ RootClass.info.decls enter EmptyPackage
+ RootClass.info.decls enter RootPackage
+ }
+ }
+
+ abstract class Roots(rootOwner: Symbol) extends RootsBase(rootOwner) { thisMirror =>
+
+ // TODO - having these as objects means they elude the attempt to
+ // add synchronization in SynchronizedSymbols. But we should either
+ // flip on object overrides or find some other accomodation, because
+ // lazy vals are unnecessarily expensive relative to objects and it
+ // is very beneficial for a handful of bootstrap symbols to have
+ // first class identities
+ sealed trait WellKnownSymbol extends Symbol {
+ this initFlags TopLevelCreationFlags
+ }
+ // Features common to RootClass and RootPackage, the roots of all
+ // type and term symbols respectively.
+ sealed trait RootSymbol extends WellKnownSymbol {
+ final override def isRootSymbol = true
+ override def owner = rootOwner
+ override def typeOfThis = thisSym.tpe
+ }
+
+ // This is the package _root_. The actual root cannot be referenced at
+ // the source level, but _root_ is essentially a function => <root>.
+ final object RootPackage extends ModuleSymbol(rootOwner, NoPosition, nme.ROOTPKG) with RootSymbol {
+ this setInfo NullaryMethodType(RootClass.tpe)
+ RootClass.sourceModule = this
+
+ override def isRootPackage = true
+ }
+ // This is <root>, the actual root of everything except the package _root_.
+ // <root> and _root_ (RootPackage and RootClass) should be the only "well known"
+ // symbols owned by NoSymbol. All owner chains should go through RootClass,
+ // although it is probable that some symbols are created as direct children
+ // of NoSymbol to ensure they will not be stumbled upon. (We should designate
+ // a better encapsulated place for that.)
+ final object RootClass extends PackageClassSymbol(rootOwner, NoPosition, tpnme.ROOT) with RootSymbol {
+ this setInfo rootLoader
+
+ override def isRoot = true
+ override def isEffectiveRoot = true
+ override def isStatic = true
+ override def isNestedClass = false
+ override def ownerOfNewSymbols = EmptyPackageClass
+ }
+ // The empty package, which holds all top level types without given packages.
+ final object EmptyPackage extends ModuleSymbol(RootClass, NoPosition, nme.EMPTY_PACKAGE_NAME) with WellKnownSymbol {
+ override def isEmptyPackage = true
+ }
+ final object EmptyPackageClass extends PackageClassSymbol(RootClass, NoPosition, tpnme.EMPTY_PACKAGE_NAME) with WellKnownSymbol {
+ override def isEffectiveRoot = true
+ override def isEmptyPackageClass = true
+ }
+ }
+}
diff --git a/src/compiler/scala/reflect/internal/Names.scala b/src/compiler/scala/reflect/internal/Names.scala
index 17924f0c0c..18671871ae 100644
--- a/src/compiler/scala/reflect/internal/Names.scala
+++ b/src/compiler/scala/reflect/internal/Names.scala
@@ -139,8 +139,8 @@ trait Names extends api.Names {
* or Strings as Names. Give names the key functions the absence of which
* make people want Strings all the time.
*/
- sealed abstract class Name(protected val index: Int, protected val len: Int) extends AbsName with Function1[Int, Char] {
- type ThisNameType <: Name
+ sealed abstract class Name(protected val index: Int, protected val len: Int) extends NameApi with Function1[Int, Char] {
+ type ThisNameType >: Null <: Name
protected[this] def thisName: ThisNameType
/** Index into name table */
@@ -429,6 +429,8 @@ trait Names extends api.Names {
def debugString = { val s = decode ; if (isTypeName) s + "!" else s }
}
+ implicit val NameTag = ClassTag[Name](classOf[Name])
+
/** A name that contains no operator chars nor dollar signs.
* TODO - see if it's any faster to do something along these lines.
* Cute: now that exhaustivity kind of works, the mere presence of
@@ -491,6 +493,8 @@ trait Names extends api.Names {
protected def createCompanionName(h: Int): TypeName
}
+ implicit val TermNameTag = ClassTag[TermName](classOf[TermName])
+
sealed abstract class TypeName(index0: Int, len0: Int, hash: Int) extends Name(index0, len0) {
type ThisNameType = TypeName
protected[this] def thisName: TypeName = this
@@ -518,4 +522,6 @@ trait Names extends api.Names {
override def decode = if (nameDebug) super.decode + "!" else super.decode
protected def createCompanionName(h: Int): TermName
}
+
+ implicit val TypeNameTag = ClassTag[TypeName](classOf[TypeName])
}
diff --git a/src/compiler/scala/reflect/internal/Positions.scala b/src/compiler/scala/reflect/internal/Positions.scala
index 5ec2659098..bbd8880e35 100644
--- a/src/compiler/scala/reflect/internal/Positions.scala
+++ b/src/compiler/scala/reflect/internal/Positions.scala
@@ -5,6 +5,7 @@ trait Positions extends api.Positions { self: SymbolTable =>
type Position = scala.tools.nsc.util.Position
val NoPosition = scala.tools.nsc.util.NoPosition
+ implicit val PositionTag = ClassTag[Position](classOf[Position])
/** A position that wraps a set of trees.
* The point of the wrapping position is the point of the default position.
diff --git a/src/compiler/scala/reflect/internal/Required.scala b/src/compiler/scala/reflect/internal/Required.scala
index 6d146354a3..abbe8fbfb7 100644
--- a/src/compiler/scala/reflect/internal/Required.scala
+++ b/src/compiler/scala/reflect/internal/Required.scala
@@ -5,7 +5,7 @@ import settings.MutableSettings
trait Required { self: SymbolTable =>
- type AbstractFileType >: Null <: api.RequiredFile
+ type AbstractFileType >: Null <: AbstractFileApi
def picklerPhase: Phase
diff --git a/src/compiler/scala/reflect/internal/Scopes.scala b/src/compiler/scala/reflect/internal/Scopes.scala
index 36e8ebb212..ceacd2afb0 100644
--- a/src/compiler/scala/reflect/internal/Scopes.scala
+++ b/src/compiler/scala/reflect/internal/Scopes.scala
@@ -317,6 +317,8 @@ trait Scopes extends api.Scopes { self: SymbolTable =>
}
+ implicit val ScopeTag = ClassTag[Scope](classOf[Scope])
+
/** Create a new scope */
def newScope: Scope = new Scope()
diff --git a/src/compiler/scala/reflect/internal/StdAttachments.scala b/src/compiler/scala/reflect/internal/StdAttachments.scala
index ae2ad87deb..33e3eb03b7 100644
--- a/src/compiler/scala/reflect/internal/StdAttachments.scala
+++ b/src/compiler/scala/reflect/internal/StdAttachments.scala
@@ -7,4 +7,6 @@ trait StdAttachments {
self: SymbolTable =>
case class ReifyAttachment(original: Symbol)
+
+ case object BackquotedIdentifierAttachment
} \ No newline at end of file
diff --git a/src/compiler/scala/reflect/internal/StdCreators.scala b/src/compiler/scala/reflect/internal/StdCreators.scala
new file mode 100644
index 0000000000..3e6b7c1ab4
--- /dev/null
+++ b/src/compiler/scala/reflect/internal/StdCreators.scala
@@ -0,0 +1,21 @@
+package scala.reflect
+package internal
+
+import scala.reflect.base.{TreeCreator, TypeCreator}
+import scala.reflect.base.{Universe => BaseUniverse}
+
+trait StdCreators {
+ self: SymbolTable =>
+
+ case class FixedMirrorTreeCreator(mirror: MirrorOf[StdCreators.this.type], tree: Tree) extends TreeCreator {
+ def apply[U <: BaseUniverse with Singleton](m: MirrorOf[U]): U # Tree =
+ if (m eq mirror) tree.asInstanceOf[U # Tree]
+ else throw new IllegalArgumentException(s"Expr defined in $mirror cannot be migrated to other mirrors.")
+ }
+
+ case class FixedMirrorTypeCreator(mirror: MirrorOf[StdCreators.this.type], tpe: Type) extends TypeCreator {
+ def apply[U <: BaseUniverse with Singleton](m: MirrorOf[U]): U # Type =
+ if (m eq mirror) tpe.asInstanceOf[U # Type]
+ else throw new IllegalArgumentException(s"Type tag defined in $mirror cannot be migrated to other mirrors.")
+ }
+} \ No newline at end of file
diff --git a/src/compiler/scala/reflect/internal/StdNames.scala b/src/compiler/scala/reflect/internal/StdNames.scala
index 14d42387f7..e166994b98 100644
--- a/src/compiler/scala/reflect/internal/StdNames.scala
+++ b/src/compiler/scala/reflect/internal/StdNames.scala
@@ -82,8 +82,8 @@ trait StdNames {
)
}
- abstract class CommonNames {
- type NameType <: Name
+ abstract class CommonNames extends NamesApi {
+ type NameType >: Null <: Name
protected implicit def createNameType(name: String): NameType
def flattenedName(segments: Name*): NameType =
@@ -122,15 +122,16 @@ trait StdNames {
scala.List(Byte, Char, Short, Int, Long, Float, Double, Boolean, Unit)
// some types whose companions we utilize
- final val AnyRef: NameType = "AnyRef"
- final val Array: NameType = "Array"
- final val List: NameType = "List"
- final val Seq: NameType = "Seq"
- final val Symbol: NameType = "Symbol"
- final val ClassTag: NameType = "ClassTag"
- final val TypeTag : NameType = "TypeTag"
+ final val AnyRef: NameType = "AnyRef"
+ final val Array: NameType = "Array"
+ final val List: NameType = "List"
+ final val Seq: NameType = "Seq"
+ final val Symbol: NameType = "Symbol"
+ final val ClassTag: NameType = "ClassTag"
+ final val TypeTag : NameType = "TypeTag"
final val ConcreteTypeTag: NameType = "ConcreteTypeTag"
- final val String: NameType = "String"
+ final val Expr: NameType = "Expr"
+ final val String: NameType = "String"
// fictions we use as both types and terms
final val ERROR: NameType = "<error>"
@@ -201,7 +202,7 @@ trait StdNames {
final val javaKeywords = new JavaKeywords()
}
- abstract class TypeNames extends Keywords {
+ abstract class TypeNames extends Keywords with TypeNamesApi {
type NameType = TypeName
protected implicit def createNameType(name: String): TypeName = newTypeNameCached(name)
@@ -215,7 +216,8 @@ trait StdNames {
final val Any: NameType = "Any"
final val AnyVal: NameType = "AnyVal"
- final val Expr: NameType = "Expr"
+ final val ExprApi: NameType = "ExprApi"
+ final val Mirror: NameType = "Mirror"
final val Nothing: NameType = "Nothing"
final val Null: NameType = "Null"
final val Object: NameType = "Object"
@@ -229,9 +231,10 @@ trait StdNames {
final val Annotation: NameType = "Annotation"
final val ClassfileAnnotation: NameType = "ClassfileAnnotation"
final val Enum: NameType = "Enum"
- final val Group: NameType = "Group"
- final val Tree: NameType = "Tree"
- final val TypeTree: NameType = "TypeTree"
+ final val Group: NameType = "Group"
+ final val Tree: NameType = "Tree"
+ final val Type : NameType = "Type"
+ final val TypeTree: NameType = "TypeTree"
// Annotation simple names, used in Namer
final val BeanPropertyAnnot: NameType = "BeanProperty"
@@ -263,7 +266,7 @@ trait StdNames {
def interfaceName(implname: Name): TypeName = implname dropRight IMPL_CLASS_SUFFIX.length toTypeName
}
- abstract class TermNames extends Keywords {
+ abstract class TermNames extends Keywords with TermNamesApi {
type NameType = TermName
protected implicit def createNameType(name: String): TermName = newTermNameCached(name)
@@ -290,6 +293,7 @@ trait StdNames {
// Compiler internal names
val ANYNAME: NameType = "<anyname>"
val CONSTRUCTOR: NameType = "<init>"
+ val EQEQ_LOCAL_VAR: NameType = "eqEqTemp$"
val FAKE_LOCAL_THIS: NameType = "this$"
val INITIALIZER: NameType = CONSTRUCTOR // Is this buying us something?
val LAZY_LOCAL: NameType = "$lzy"
@@ -306,6 +310,7 @@ trait StdNames {
val OUTER: NameType = "$outer"
val OUTER_LOCAL: NameType = OUTER + LOCAL_SUFFIX_STRING // "$outer ", note the space
val OUTER_SYNTH: NameType = "<outer>" // emitted by virtual pattern matcher, replaced by outer accessor in explicitouter
+ val ROOTPKG: NameType = "_root_"
val SELECTOR_DUMMY: NameType = "<unapply-selector>"
val SELF: NameType = "$this"
val SETTER_SUFFIX: NameType = encode("_=")
@@ -511,6 +516,32 @@ trait StdNames {
case _ => newTermName("x$" + i)
}
+ @switch def productAccessorName(j: Int): TermName = j match {
+ case 1 => nme._1
+ case 2 => nme._2
+ case 3 => nme._3
+ case 4 => nme._4
+ case 5 => nme._5
+ case 6 => nme._6
+ case 7 => nme._7
+ case 8 => nme._8
+ case 9 => nme._9
+ case 10 => nme._10
+ case 11 => nme._11
+ case 12 => nme._12
+ case 13 => nme._13
+ case 14 => nme._14
+ case 15 => nme._15
+ case 16 => nme._16
+ case 17 => nme._17
+ case 18 => nme._18
+ case 19 => nme._19
+ case 20 => nme._20
+ case 21 => nme._21
+ case 22 => nme._22
+ case _ => newTermName("_" + j)
+ }
+
val ??? = encode("???")
val wrapRefArray: NameType = "wrapRefArray"
@@ -539,12 +570,14 @@ trait StdNames {
val EmptyPackage: NameType = "EmptyPackage"
val EmptyPackageClass: NameType = "EmptyPackageClass"
val ExistentialTypeTree: NameType = "ExistentialTypeTree"
- val Expr: NameType = "Expr"
+ val Flag : NameType = "Flag"
val Ident: NameType = "Ident"
val Import: NameType = "Import"
val Literal: NameType = "Literal"
val LiteralAnnotArg: NameType = "LiteralAnnotArg"
+ val Modifiers: NameType = "Modifiers"
val NestedAnnotArg: NameType = "NestedAnnotArg"
+ val NoFlags: NameType = "NoFlags"
val NoPrefix: NameType = "NoPrefix"
val NoSymbol: NameType = "NoSymbol"
val Nothing: NameType = "Nothing"
@@ -556,6 +589,7 @@ trait StdNames {
val Select: NameType = "Select"
val StringContext: NameType = "StringContext"
val This: NameType = "This"
+ val ThisType: NameType = "ThisType"
val Tree : NameType = "Tree"
val Tuple2: NameType = "Tuple2"
val TYPE_ : NameType = "TYPE"
@@ -570,6 +604,7 @@ trait StdNames {
val apply: NameType = "apply"
val applyDynamic: NameType = "applyDynamic"
val applyDynamicNamed: NameType = "applyDynamicNamed"
+ val applyImpl: NameType = "applyImpl"
val applyOrElse: NameType = "applyOrElse"
val args : NameType = "args"
val argv : NameType = "argv"
@@ -582,12 +617,19 @@ trait StdNames {
val array_length : NameType = "array_length"
val array_update : NameType = "array_update"
val arraycopy: NameType = "arraycopy"
+ val asTermSymbol: NameType = "asTermSymbol"
+ val asModuleSymbol: NameType = "asModuleSymbol"
+ val asMethodSymbol: NameType = "asMethodSymbol"
+ val asTypeSymbol: NameType = "asTypeSymbol"
+ val asClassSymbol: NameType = "asClassSymbol"
val asInstanceOf_ : NameType = "asInstanceOf"
val asInstanceOf_Ob : NameType = "$asInstanceOf"
val asTypeConstructor: NameType = "asTypeConstructor"
val assert_ : NameType = "assert"
val assume_ : NameType = "assume"
+ val basis : NameType = "basis"
val box: NameType = "box"
+ val build : NameType = "build"
val bytes: NameType = "bytes"
val canEqual_ : NameType = "canEqual"
val checkInitialized: NameType = "checkInitialized"
@@ -596,6 +638,7 @@ trait StdNames {
val concreteTypeTagToManifest: NameType = "concreteTypeTagToManifest"
val conforms: NameType = "conforms"
val copy: NameType = "copy"
+ val currentMirror: NameType = "currentMirror"
val definitions: NameType = "definitions"
val delayedInit: NameType = "delayedInit"
val delayedInitArg: NameType = "delayedInit$body"
@@ -617,6 +660,7 @@ trait StdNames {
val filter: NameType = "filter"
val finalize_ : NameType = if (forMSIL) "Finalize" else "finalize"
val find_ : NameType = "find"
+ val flagsFromBits : NameType = "flagsFromBits"
val flatMap: NameType = "flatMap"
val foreach: NameType = "foreach"
val genericArrayOps: NameType = "genericArrayOps"
@@ -627,6 +671,8 @@ trait StdNames {
val hash_ : NameType = "hash"
val head: NameType = "head"
val identity: NameType = "identity"
+ val implicitly: NameType = "implicitly"
+ val in: NameType = "in"
val info: NameType = "info"
val inlinedEquals: NameType = "inlinedEquals"
val isArray: NameType = "isArray"
@@ -650,7 +696,6 @@ trait StdNames {
val materializeArrayTag: NameType = "materializeArrayTag"
val materializeClassTag: NameType = "materializeClassTag"
val materializeConcreteTypeTag: NameType = "materializeConcreteTypeTag"
- val materializeErasureTag: NameType= "materializeErasureTag"
val materializeTypeTag: NameType = "materializeTypeTag"
val mirror : NameType = "mirror"
val moduleClass : NameType = "moduleClass"
@@ -679,8 +724,10 @@ trait StdNames {
val readResolve: NameType = "readResolve"
val reflect : NameType = "reflect"
val reify : NameType = "reify"
+ val rootMirror : NameType = "rootMirror"
val runOrElse: NameType = "runOrElse"
val runtime: NameType = "runtime"
+ val runtimeMirror: NameType = "runtimeMirror"
val sameElements: NameType = "sameElements"
val scala_ : NameType = "scala"
val selectDynamic: NameType = "selectDynamic"
@@ -693,13 +740,15 @@ trait StdNames {
val setSymbol: NameType = "setSymbol"
val setType: NameType = "setType"
val setTypeSignature: NameType = "setTypeSignature"
+ val splice: NameType = "splice"
val staticClass : NameType = "staticClass"
val staticModule : NameType = "staticModule"
val synchronized_ : NameType = "synchronized"
val tail: NameType = "tail"
val `then` : NameType = "then"
- val thisModuleType: NameType = "thisModuleType"
val this_ : NameType = "this"
+ val thisModuleType : NameType = "thisModuleType"
+ val thisPrefix : NameType = "thisPrefix"
val throw_ : NameType = "throw"
val toArray: NameType = "toArray"
val toList: NameType = "toList"
@@ -713,6 +762,7 @@ trait StdNames {
val unapply: NameType = "unapply"
val unapplySeq: NameType = "unapplySeq"
val unbox: NameType = "unbox"
+ val universe: NameType = "universe"
val update: NameType = "update"
val updateDynamic: NameType = "updateDynamic"
val value: NameType = "value"
@@ -757,90 +807,10 @@ trait StdNames {
// overlap with the above, but not for these two.
val toCharacter: NameType = "toCharacter"
val toInteger: NameType = "toInteger"
- }
-
- object tpnme extends TypeNames with AbsTypeNames { }
-
- /** For fully qualified type names.
- */
- object fulltpnme extends TypeNames {
- val RuntimeNothing: NameType = "scala.runtime.Nothing$"
- val RuntimeNull: NameType = "scala.runtime.Null$"
- }
-
- /** Java binary names, like scala/runtime/Nothing$.
- */
- object binarynme {
- def toBinary(name: Name) = name mapName (_.replace('.', '/'))
-
- val RuntimeNothing = toBinary(fulltpnme.RuntimeNothing).toTypeName
- val RuntimeNull = toBinary(fulltpnme.RuntimeNull).toTypeName
- }
-
- val javanme = nme.javaKeywords
-
- object nme extends TermNames with AbsTermNames {
-
- /** Translate a String into a list of simple TypeNames and TermNames.
- * In all segments before the last, type/term is determined by whether
- * the following separator char is '.' or '#'. In the last segment,
- * the argument "assumeTerm" determines it. Examples:
- *
- * package foo {
- * object Lorax { object Wog ; class Wog }
- * class Lorax { object Zax ; class Zax }
- * }
- *
- * f("foo.Lorax", true) == List("foo": Term, "Lorax": Term) // object Lorax
- * f("foo.Lorax", false) == List("foo": Term, "Lorax": Type) // class Lorax
- * f("Lorax.Wog", true) == List("Lorax": Term, "Wog": Term) // object Wog
- * f("Lorax.Wog", false) == List("Lorax": Term, "Wog": Type) // class Wog
- * f("Lorax#Zax", true) == List("Lorax": Type, "Zax": Term) // object Zax
- * f("Lorax#Zax", false) == List("Lorax": Type, "Zax": Type) // class Zax
- *
- * Note that in actual scala syntax you cannot refer to object Zax without an
- * instance of Lorax, so Lorax#Zax could only mean the type. One might think
- * that Lorax#Zax.type would work, but this is not accepted by the parser.
- * For the purposes of referencing that object, the syntax is allowed.
- */
- def segments(name: String, assumeTerm: Boolean): List[Name] = {
- def mkName(str: String, term: Boolean): Name =
- if (term) newTermName(str) else newTypeName(str)
-
- name.indexWhere(ch => ch == '.' || ch == '#') match {
- // it's the last segment: the parameter tells us whether type or term
- case -1 => if (name == "") scala.Nil else scala.List(mkName(name, assumeTerm))
- // otherwise, we can tell based on whether '#' or '.' is the following char.
- case idx =>
- val (simple, div, rest) = (name take idx, name charAt idx, newTermName(name) drop (idx + 1))
- mkName(simple, div == '.') :: segments(rest, assumeTerm)
- }
- }
-
- def newBitmapName(bitmapPrefix: Name, n: Int) = bitmapPrefix append ("" + n)
-
- val BITMAP_NORMAL: NameType = BITMAP_PREFIX + "" // initialization bitmap for public/protected lazy vals
- val BITMAP_TRANSIENT: NameType = BITMAP_PREFIX + "trans$" // initialization bitmap for transient lazy vals
- val BITMAP_CHECKINIT: NameType = BITMAP_PREFIX + "init$" // initialization bitmap for checkinit values
- val BITMAP_CHECKINIT_TRANSIENT: NameType = BITMAP_PREFIX + "inittrans$" // initialization bitmap for transient checkinit values
def newLazyValSlowComputeName(lzyValName: Name) = lzyValName append LAZY_SLOW_SUFFIX
- def isModuleVarName(name: Name): Boolean =
- stripAnonNumberSuffix(name) endsWith MODULE_VAR_SUFFIX
-
- def moduleVarName(name: TermName): TermName =
- newTermNameCached("" + name + MODULE_VAR_SUFFIX)
-
- val ROOTPKG: TermName = "_root_"
- val EQEQ_LOCAL_VAR: TermName = "eqEqTemp$"
-
- def getCause = sn.GetCause
- def getClass_ = sn.GetClass
- def getComponentType = sn.GetComponentType
- def getMethod_ = sn.GetMethod
- def invoke_ = sn.Invoke
-
+ // ASCII names for operators
val ADD = encode("+")
val AND = encode("&")
val ASR = encode(">>")
@@ -906,9 +876,6 @@ trait StdNames {
val testLessThan: NameType = "testLessThan"
val testNotEqual: NameType = "testNotEqual"
- val isBoxedNumberOrBoolean: NameType = "isBoxedNumberOrBoolean"
- val isBoxedNumber: NameType = "isBoxedNumber"
-
def toUnaryName(name: TermName): TermName = name match {
case raw.MINUS => UNARY_-
case raw.PLUS => UNARY_+
@@ -958,6 +925,90 @@ trait StdNames {
case _ => NO_NAME
}
+ /** Translate a String into a list of simple TypeNames and TermNames.
+ * In all segments before the last, type/term is determined by whether
+ * the following separator char is '.' or '#'. In the last segment,
+ * the argument "assumeTerm" determines it. Examples:
+ *
+ * package foo {
+ * object Lorax { object Wog ; class Wog }
+ * class Lorax { object Zax ; class Zax }
+ * }
+ *
+ * f("foo.Lorax", true) == List("foo": Term, "Lorax": Term) // object Lorax
+ * f("foo.Lorax", false) == List("foo": Term, "Lorax": Type) // class Lorax
+ * f("Lorax.Wog", true) == List("Lorax": Term, "Wog": Term) // object Wog
+ * f("Lorax.Wog", false) == List("Lorax": Term, "Wog": Type) // class Wog
+ * f("Lorax#Zax", true) == List("Lorax": Type, "Zax": Term) // object Zax
+ * f("Lorax#Zax", false) == List("Lorax": Type, "Zax": Type) // class Zax
+ *
+ * Note that in actual scala syntax you cannot refer to object Zax without an
+ * instance of Lorax, so Lorax#Zax could only mean the type. One might think
+ * that Lorax#Zax.type would work, but this is not accepted by the parser.
+ * For the purposes of referencing that object, the syntax is allowed.
+ */
+ def segments(name: String, assumeTerm: Boolean): List[Name] = {
+ def mkName(str: String, term: Boolean): Name =
+ if (term) newTermName(str) else newTypeName(str)
+
+ name.indexWhere(ch => ch == '.' || ch == '#') match {
+ // it's the last segment: the parameter tells us whether type or term
+ case -1 => if (name == "") scala.Nil else scala.List(mkName(name, assumeTerm))
+ // otherwise, we can tell based on whether '#' or '.' is the following char.
+ case idx =>
+ val (simple, div, rest) = (name take idx, name charAt idx, newTermName(name) drop (idx + 1))
+ mkName(simple, div == '.') :: segments(rest, assumeTerm)
+ }
+ }
+
+ def newBitmapName(bitmapPrefix: Name, n: Int) = bitmapPrefix append ("" + n)
+
+ val BITMAP_NORMAL: NameType = BITMAP_PREFIX + "" // initialization bitmap for public/protected lazy vals
+ val BITMAP_TRANSIENT: NameType = BITMAP_PREFIX + "trans$" // initialization bitmap for transient lazy vals
+ val BITMAP_CHECKINIT: NameType = BITMAP_PREFIX + "init$" // initialization bitmap for checkinit values
+ val BITMAP_CHECKINIT_TRANSIENT: NameType = BITMAP_PREFIX + "inittrans$" // initialization bitmap for transient checkinit values
+ }
+
+ object tpnme extends TypeNames { }
+
+ /** For fully qualified type names.
+ */
+ object fulltpnme extends TypeNames {
+ val RuntimeNothing: NameType = "scala.runtime.Nothing$"
+ val RuntimeNull: NameType = "scala.runtime.Null$"
+ val JavaLangEnum: NameType = "java.lang.Enum"
+ }
+
+ /** Java binary names, like scala/runtime/Nothing$.
+ */
+ object binarynme {
+ def toBinary(name: Name) = name mapName (_.replace('.', '/'))
+
+ val RuntimeNothing = toBinary(fulltpnme.RuntimeNothing).toTypeName
+ val RuntimeNull = toBinary(fulltpnme.RuntimeNull).toTypeName
+ }
+
+ val javanme = nme.javaKeywords
+
+ // [Eugene++ to Martin] had to move a lot of stuff from here to TermNames to satisfy the contract
+ // why do we even have stuff in object nme? cf. object tpnme
+ object nme extends TermNames {
+
+ def isModuleVarName(name: Name): Boolean =
+ stripAnonNumberSuffix(name) endsWith MODULE_VAR_SUFFIX
+
+ def moduleVarName(name: TermName): TermName =
+ newTermNameCached("" + name + MODULE_VAR_SUFFIX)
+
+ def getCause = sn.GetCause
+ def getClass_ = sn.GetClass
+ def getComponentType = sn.GetComponentType
+ def getMethod_ = sn.GetMethod
+ def invoke_ = sn.Invoke
+
+ val isBoxedNumberOrBoolean: NameType = "isBoxedNumberOrBoolean"
+ val isBoxedNumber: NameType = "isBoxedNumber"
+
val reflPolyCacheName: NameType = "reflPoly$Cache"
val reflClassCacheName: NameType = "reflClass$Cache"
val reflParamsCacheName: NameType = "reflParams$Cache"
@@ -973,32 +1024,6 @@ trait StdNames {
)
def isReflectionCacheName(name: Name) = reflectionCacheNames exists (name startsWith _)
- @switch def productAccessorName(j: Int): TermName = j match {
- case 1 => nme._1
- case 2 => nme._2
- case 3 => nme._3
- case 4 => nme._4
- case 5 => nme._5
- case 6 => nme._6
- case 7 => nme._7
- case 8 => nme._8
- case 9 => nme._9
- case 10 => nme._10
- case 11 => nme._11
- case 12 => nme._12
- case 13 => nme._13
- case 14 => nme._14
- case 15 => nme._15
- case 16 => nme._16
- case 17 => nme._17
- case 18 => nme._18
- case 19 => nme._19
- case 20 => nme._20
- case 21 => nme._21
- case 22 => nme._22
- case _ => newTermName("_" + j)
- }
-
@deprecated("Use a method in tpnme", "2.10.0") def dropSingletonName(name: Name): TypeName = tpnme.dropSingletonName(name)
@deprecated("Use a method in tpnme", "2.10.0") def singletonName(name: Name): TypeName = tpnme.singletonName(name)
@deprecated("Use a method in tpnme", "2.10.0") def implClassName(name: Name): TypeName = tpnme.implClassName(name)
@@ -1028,6 +1053,7 @@ trait StdNames {
val ForName : TermName
val GetCause : TermName
val GetClass : TermName
+ val GetClassLoader : TermName
val GetComponentType : TermName
val GetMethod : TermName
val Invoke : TermName
@@ -1117,6 +1143,7 @@ trait StdNames {
final val ForName: TermName = newTermName("forName")
final val GetCause: TermName = newTermName("getCause")
final val GetClass: TermName = newTermName("getClass")
+ final val GetClassLoader: TermName = newTermName("getClassLoader")
final val GetComponentType: TermName = newTermName("getComponentType")
final val GetMethod: TermName = newTermName("getMethod")
final val Invoke: TermName = newTermName("invoke")
@@ -1155,6 +1182,7 @@ trait StdNames {
final val ForName: TermName = newTermName("GetType")
final val GetCause: TermName = newTermName("InnerException") /* System.Reflection.TargetInvocationException.InnerException */
final val GetClass: TermName = newTermName("GetType")
+ final lazy val GetClassLoader: TermName = throw new UnsupportedOperationException("Scala reflection is not supported on this platform");
final val GetComponentType: TermName = newTermName("GetElementType")
final val GetMethod: TermName = newTermName("GetMethod")
final val Invoke: TermName = newTermName("Invoke")
diff --git a/src/compiler/scala/reflect/internal/SymbolTable.scala b/src/compiler/scala/reflect/internal/SymbolTable.scala
index ddd6c43031..cf6db7d438 100644
--- a/src/compiler/scala/reflect/internal/SymbolTable.scala
+++ b/src/compiler/scala/reflect/internal/SymbolTable.scala
@@ -10,15 +10,16 @@ import scala.collection.{ mutable, immutable }
import util._
import scala.tools.nsc.util.WeakHashSet
-abstract class SymbolTable extends api.Universe
+abstract class SymbolTable extends makro.Universe
with Collections
with Names
with Symbols
- with FreeVars
with Types
with Kinds
with ExistentialsAndSkolems
+ with FlagSets
with Scopes
+ with Mirrors
with Definitions
with Constants
with BaseTypeSeqs
@@ -33,12 +34,15 @@ abstract class SymbolTable extends api.Universe
with TypeDebugging
with Importers
with Required
- with TreeBuildUtil
- with FrontEnds
with CapturedVariables
with StdAttachments
+ with StdCreators
+ with BuildUtils
{
- def rootLoader: LazyType
+
+ val gen = new TreeGen { val global: SymbolTable.this.type = SymbolTable.this }
+ val treeBuild = gen
+
def log(msg: => AnyRef): Unit
def abort(msg: String): Nothing = throw new FatalError(supplementErrorMessage(msg))
@@ -110,6 +114,9 @@ abstract class SymbolTable extends api.Universe
*/
def missingHook(owner: Symbol, name: Name): Symbol = NoSymbol
+ /** Returns the mirror that loaded given symbol */
+ def mirrorThatLoaded(sym: Symbol): Mirror
+
/** A period is an ordinal number for a phase in a run.
* Phases in later runs have higher periods than phases in earlier runs.
* Later phases have higher periods than earlier phases in the same run.
@@ -295,7 +302,6 @@ abstract class SymbolTable extends api.Universe
def clearAll() = {
debuglog("Clearing " + caches.size + " caches.")
-
caches foreach { ref =>
val cache = ref.get()
if (cache == null)
@@ -321,8 +327,7 @@ abstract class SymbolTable extends api.Universe
/** The phase which has given index as identifier. */
val phaseWithId: Array[Phase]
- /** Is this symbol table part of reflexive mirror? In this case
- * operations need to be made thread safe.
+ /** Is this symbol table a part of a compiler universe?
*/
- def inReflexiveMirror = false
+ def isCompilerUniverse = false
}
diff --git a/src/compiler/scala/reflect/internal/Symbols.scala b/src/compiler/scala/reflect/internal/Symbols.scala
index b32b955631..7305cdaf16 100644
--- a/src/compiler/scala/reflect/internal/Symbols.scala
+++ b/src/compiler/scala/reflect/internal/Symbols.scala
@@ -10,7 +10,6 @@ import scala.collection.{ mutable, immutable }
import scala.collection.mutable.ListBuffer
import util.Statistics._
import Flags._
-import api.Modifier
trait Symbols extends api.Symbols { self: SymbolTable =>
import definitions._
@@ -47,20 +46,20 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
/** Create a new free term. Its owner is NoSymbol.
*/
- def newFreeTermSymbol(name: TermName, info: Type, value: => Any, flags: Long = 0L, origin: String): FreeTerm =
- new FreeTerm(name, value, origin) initFlags flags setInfo info
+ def newFreeTermSymbol(name: TermName, info: Type, value: => Any, flags: Long = 0L, origin: String): FreeTermSymbol =
+ new FreeTermSymbol(name, value, origin) initFlags flags setInfo info
/** Create a new free type. Its owner is NoSymbol.
*/
- def newFreeTypeSymbol(name: TypeName, info: Type, value: => Any, flags: Long = 0L, origin: String): FreeType =
- new FreeType(name, value, origin) initFlags flags setInfo info
+ def newFreeTypeSymbol(name: TypeName, info: Type, value: => Any, flags: Long = 0L, origin: String): FreeTypeSymbol =
+ new FreeTypeSymbol(name, value, origin) initFlags flags setInfo info
/** The original owner of a class. Used by the backend to generate
* EnclosingMethod attributes.
*/
val originalOwner = perRunCaches.newMap[Symbol, Symbol]()
- abstract class AbsSymbolImpl extends AbsSymbol {
+ abstract class SymbolContextApiImpl extends SymbolContextApi {
this: Symbol =>
def kind: String = kindString
@@ -71,8 +70,6 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
case n: TypeName => if (isClass) newClassSymbol(n, pos, newFlags) else newNonClassSymbol(n, pos, newFlags)
}
- def enclosingClass: Symbol = enclClass
- def enclosingMethod: Symbol = enclMethod
def thisPrefix: Type = thisType
def selfType: Type = typeOfThis
def typeSignature: Type = info
@@ -83,6 +80,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
def asTypeConstructor: Type = typeConstructor
def setInternalFlags(flag: Long): this.type = { setFlag(flag); this }
def setTypeSignature(tpe: Type): this.type = { setInfo(tpe); this }
+ def getAnnotations: List[AnnotationInfo] = { initialize; annotations }
def setAnnotations(annots: AnnotationInfo*): this.type = { setAnnotations(annots.toList); this }
private def lastElemType(ts: Seq[Type]): Type = ts.last.normalize.typeArgs.head
@@ -155,7 +153,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
/** The class for all symbols */
abstract class Symbol protected[Symbols] (initOwner: Symbol, initPos: Position, initName: Name)
- extends AbsSymbolImpl
+ extends SymbolContextApiImpl
with HasFlags
with Annotatable[Symbol] {
@@ -164,7 +162,6 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
// TODO - don't allow names to be renamed in this unstructured a fashion.
// Rename as little as possible. Enforce invariants on all renames.
- type NameType >: Null <: Name
type TypeOfClonedSymbol >: Null <: Symbol { type NameType = Symbol.this.NameType }
// Abstract here so TypeSymbol and TermSymbol can have a private[this] field
@@ -183,6 +180,8 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
private var rawpos = initPos
val id = nextId() // identity displayed when -uniqid
+ //assert(id != 3390, initName)
+
private[this] var _validTo: Period = NoPeriod
if (traceSymbolActivity)
@@ -236,19 +235,6 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
)
)
- /** !!! 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 modifiers: Set[Modifier] =
- Modifier.values filter hasModifier
-
// ------ creators -------------------------------------------------------------------
final def newValue(name: TermName, pos: Position = NoPosition, newFlags: Long = 0L): TermSymbol =
@@ -263,6 +249,8 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
newTermSymbol(nme.localDummyName(this), pos) setInfo NoType
final def newMethod(name: TermName, pos: Position = NoPosition, newFlags: Long = 0L): MethodSymbol =
createMethodSymbol(name, pos, METHOD | newFlags)
+ final def newMethodSymbol(name: TermName, pos: Position = NoPosition, newFlags: Long = 0L): MethodSymbol =
+ createMethodSymbol(name, pos, METHOD | newFlags)
final def newLabel(name: TermName, pos: Position = NoPosition): MethodSymbol =
newMethod(name, pos, LABEL)
@@ -302,6 +290,16 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
final def newModuleSymbol(name: TermName, pos: Position = NoPosition, newFlags: Long = 0L): ModuleSymbol =
newTermSymbol(name, pos, newFlags).asInstanceOf[ModuleSymbol]
+ final def newModuleAndClassSymbol(name: Name, pos: Position, flags: FlagSet): (ModuleSymbol, ClassSymbol) = {
+ val m = newModuleSymbol(name, pos, flags | MODULE)
+ val c = newModuleClass(name.toTypeName, pos, m getFlag ModuleToClassFlags)
+ connectModuleToClass(m, c)
+ (m, c)
+ }
+
+ final def newPackageSymbol(name: TermName, pos: Position = NoPosition, newFlags: Long = 0L): ModuleSymbol =
+ newTermSymbol(name, pos, newFlags).asInstanceOf[ModuleSymbol]
+
final def newModuleClassSymbol(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): ModuleClassSymbol =
newClassSymbol(name, pos, newFlags).asInstanceOf[ModuleClassSymbol]
@@ -349,6 +347,11 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
final def newTypeParameter(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): TypeSymbol =
newAbstractType(name, pos, PARAM | newFlags)
+// is defined in SymbolCreations
+// final def newTypeSymbol(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): TypeSymbol =
+// (if ((newFlags & DEFERRED) != 0) new AbstractTypeSymbol(this, pos, name)
+// else new AbstractTypeSymbol(this, pos, name)) setFlag newFlags
+
/** Symbol of an existential type T forSome { ... }
*/
final def newExistential(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): TypeSymbol =
@@ -445,18 +448,6 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
case x: TermName => newErrorValue(x)
}
- /** To overcome the crazy challenge of more specific types appearing
- * in incoming positions. Don't need this much.
- */
- def asTypeSymbol: TypeSymbol = this match {
- case x: TypeSymbol => x
- case x => throw new FatalError(this + " is not a TypeSymbol")
- }
- def asTermSymbol: TermSymbol = this match {
- case x: TermSymbol => x
- case x => throw new FatalError(this + " is not a TermSymbol")
- }
-
@deprecated("Use the other signature", "2.10.0")
def newClass(pos: Position, name: TypeName): Symbol = newClass(name, pos)
@deprecated("Use the other signature", "2.10.0")
@@ -526,19 +517,6 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
// ----- tests ----------------------------------------------------------------------
- /** All symbols are one of three categories: TermSymbol, TypeSymbol, or NoSymbol.
- * There is only one NoSymbol.
- */
- def isTerm = false
- def isType = false
-
- /** TypeSymbols fall into four named direct subclasses:
- * - ClassSymbol
- * - AliasTypeSymbol
- * - AbstractTypeSymbol
- * - TypeSkolem
- */
- def isClass = false
def isAliasType = false
def isAbstractType = false
def isSkolem = false
@@ -580,7 +558,6 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
def isTypeParameterOrSkolem = false
def isTypeSkolem = false
def isTypeMacro = false
- def isFreeType = false
/** Qualities of Terms, always false for TypeSymbols.
*/
@@ -593,7 +570,6 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
def isGetter = false
def isLocalDummy = false
def isMixinConstructor = false
- def isModule = false
def isOverloaded = false
def isSetter = false
def isSetterParameter = false
@@ -602,20 +578,17 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
def isVariable = false
override def hasDefault = false
def isTermMacro = false
- def isFreeTerm = false
/** Qualities of MethodSymbols, always false for TypeSymbols
* and other TermSymbols.
*/
def isCaseAccessorMethod = false
def isLiftedMethod = false
- def isMethod = false
def isSourceMethod = false
def isVarargsMethod = false
override def isLabel = false
/** Package/package object tests */
- def isPackage = false
def isPackageClass = false
def isPackageObject = false
def isPackageObjectClass = false
@@ -916,7 +889,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
final def isInitialized: Boolean =
validTo != NoPeriod
- // [Eugene] is this correct?
+ // [Eugene] todo. needs to be reviewed and [only then] rewritten without explicit returns
/** Determines whether this symbol can be loaded by subsequent reflective compilation */
final def isLocatable: Boolean = {
if (this == NoSymbol) return false
@@ -976,7 +949,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
if (originalOwner contains this) ()
else originalOwner(this) = rawowner
}
- assert(!inReflexiveMirror, "owner_= is not thread-safe; cannot be run in reflexive code")
+ assert(isCompilerUniverse, "owner_= is not thread-safe; cannot be run in reflexive code")
if (traceSymbolActivity)
traceSymbols.recordNewSymbolOwner(this, owner)
_rawowner = owner
@@ -1103,8 +1076,8 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
protected def createModuleSymbol(name: TermName, pos: Position, newFlags: Long): ModuleSymbol =
new ModuleSymbol(this, pos, name) initFlags newFlags
- protected def createPackageSymbol(name: TermName, pos: Position, newFlags: Long): PackageSymbol =
- new PackageSymbol(this, pos, name) initFlags newFlags
+ protected def createPackageSymbol(name: TermName, pos: Position, newFlags: Long): ModuleSymbol =
+ new ModuleSymbol(this, pos, name) initFlags newFlags
protected def createValueParameterSymbol(name: TermName, pos: Position, newFlags: Long): TermSymbol =
new TermSymbol(this, pos, name) initFlags newFlags
@@ -1157,10 +1130,10 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
*/
def accessBoundary(base: Symbol): Symbol = {
if (hasFlag(PRIVATE) || isLocal) owner
- else if (hasAllFlags(PROTECTED | STATIC | JAVA)) RootClass
+ else if (hasAllFlags(PROTECTED | STATIC | JAVA)) enclosingRootClass
else if (hasAccessBoundary && !phase.erasedTypes) privateWithin
else if (hasFlag(PROTECTED)) base
- else RootClass
+ else enclosingRootClass
}
def isLessAccessibleThan(other: Symbol): Boolean = {
@@ -1335,7 +1308,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
// adapt to new run in fsc.
private def adaptInfos(infos: TypeHistory): TypeHistory = {
- assert(!inReflexiveMirror)
+ assert(isCompilerUniverse)
if (infos == null || runId(infos.validFrom) == currentRunId) {
infos
} else {
@@ -1370,7 +1343,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
/** Was symbol's type updated during given phase? */
final def isUpdatedAt(pid: Phase#Id): Boolean = {
- assert(!inReflexiveMirror)
+ assert(isCompilerUniverse)
var infos = this.infos
while ((infos ne null) && phaseId(infos.validFrom) != pid + 1) infos = infos.prev
infos ne null
@@ -1378,7 +1351,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
/** Was symbol's type updated during given phase? */
final def hasTypeAt(pid: Phase#Id): Boolean = {
- assert(!inReflexiveMirror)
+ assert(isCompilerUniverse)
var infos = this.infos
while ((infos ne null) && phaseId(infos.validFrom) > pid) infos = infos.prev
infos ne null
@@ -1527,13 +1500,8 @@ 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] = {
- // Necessary for reflection, see SI-5423
- if (inReflexiveMirror)
- initialize
-
+ def annotations: List[AnnotationInfo] =
_annotations
- }
def setAnnotations(annots: List[AnnotationInfo]): this.type = {
_annotations = annots
@@ -1619,6 +1587,8 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
result
}
+ @inline final def map(f: Symbol => Symbol): Symbol = if (this eq NoSymbol) this else f(this)
+
// ------ cloneing -------------------------------------------------------------------
/** A clone of this symbol. */
@@ -1766,15 +1736,30 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
/** All directly or indirectly inherited classes. */
def ancestors: List[Symbol] = info.baseClasses drop 1
+ @inline final def enclosingSuchThat(p: Symbol => Boolean): Symbol = {
+ var sym = this
+ while (sym != NoSymbol && !p(sym))
+ sym = sym.owner
+ sym
+ }
+
/** The package class containing this symbol, or NoSymbol if there
- * is not one. */
+ * is not one.
+ * TODO: formulate as enclosingSuchThat, after making sure
+ * we can start with current symbol rather than onwner.
+ * TODO: Also harmonize with enclClass, enclMethod etc.
+ */
def enclosingPackageClass: Symbol = {
- var packSym = this.owner
- while (packSym != NoSymbol && !packSym.isPackageClass)
- packSym = packSym.owner
- packSym
+ var sym = this.owner
+ while (sym != NoSymbol && !sym.isPackageClass)
+ sym = sym.owner
+ sym
}
+ /** The package class containing this symbol, or NoSymbol if there
+ * is not one. */
+ def enclosingRootClass: Symbol = enclosingSuchThat(_.isRoot)
+
/** The package containing this symbol, or NoSymbol if there
* is not one. */
def enclosingPackage: Symbol = enclosingPackageClass.companionModule
@@ -2167,8 +2152,8 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
private def symbolKind: SymbolKind = {
var kind =
if (isTermMacro) ("macro method", "macro method", "MAC")
- else if (isInstanceOf[FreeTerm]) ("free term", "free term", "FTE")
- else if (isInstanceOf[FreeType]) ("free type", "free type", "FTY")
+ else if (isInstanceOf[FreeTermSymbol]) ("free term", "free term", "FTE")
+ else if (isInstanceOf[FreeTypeSymbol]) ("free type", "free type", "FTY")
else if (isPackage) ("package", "package", "PK")
else if (isPackageClass) ("package class", "package", "PKC")
else if (isPackageObject) ("package object", "package", "PKO")
@@ -2327,6 +2312,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
"val " + tpnme.dropSingletonName(name) + ": " + dropSingletonType(info.bounds.hi)
else defString
}
+ implicit val SymbolTag = ClassTag[Symbol](classOf[Symbol])
/** A class for term symbols */
class TermSymbol protected[Symbols] (initOwner: Symbol, initPos: Position, initName: TermName)
@@ -2334,7 +2320,6 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
private[this] var _referenced: Symbol = NoSymbol
privateWithin = NoSymbol
- final type NameType = TermName
type TypeOfClonedSymbol = TermSymbol
private[this] var _rawname: TermName = initName
@@ -2349,8 +2334,6 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
}
final def asNameType(n: Name) = n.toTermName
- final override def isTerm = true
-
/** Term symbols with the exception of static parts of Java classes and packages.
*/
override def isValue = !(isModule && hasFlag(PACKAGE | JAVA))
@@ -2496,6 +2479,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
cook(sym2)
}
}
+ implicit val TermSymbolTag = ClassTag[TermSymbol](classOf[TermSymbol])
/** A class for module symbols */
class ModuleSymbol protected[Symbols] (initOwner: Symbol, initPos: Position, initName: TermName)
@@ -2505,7 +2489,6 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
override def associatedFile = moduleClass.associatedFile
override def associatedFile_=(f: AbstractFileType) { moduleClass.associatedFile = f }
- override def isModule = true
override def moduleClass = referenced
override def companionClass =
flatOwnerInfo.decl(name.toTypeName).suchThat(_ isCoDefinedWith this)
@@ -2524,11 +2507,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
else rawname
)
}
-
- class PackageSymbol protected[Symbols] (owner0: Symbol, pos0: Position, name0: TermName)
- extends ModuleSymbol(owner0, pos0, name0) with PackageSymbolApi {
- override def isPackage = true
- }
+ implicit val ModuleSymbolTag = ClassTag[ModuleSymbol](classOf[ModuleSymbol])
/** A class for method symbols */
class MethodSymbol protected[Symbols] (initOwner: Symbol, initPos: Position, initName: TermName)
@@ -2538,7 +2517,6 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
private[this] var mtpeResult: Type = _
private[this] var mtpeInfo: Type = _
- override def isMethod = true
override def isLabel = this hasFlag LABEL
override def isVarargsMethod = this hasFlag VARARGS
override def isLiftedMethod = this hasFlag LIFTED
@@ -2566,6 +2544,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
res
}
}
+ implicit val MethodSymbolTag = ClassTag[MethodSymbol](classOf[MethodSymbol])
class AliasTypeSymbol protected[Symbols] (initOwner: Symbol, initPos: Position, initName: TypeName)
extends TypeSymbol(initOwner, initPos, initName) {
@@ -2593,7 +2572,6 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
privateWithin = NoSymbol
private[this] var _rawname: TypeName = initName
- final type NameType = TypeName
type TypeOfClonedSymbol >: Null <: TypeSymbol
// cloneSymbolImpl still abstract in TypeSymbol.
@@ -2601,7 +2579,6 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
def name = _rawname
final def asNameType(n: Name) = n.toTypeName
- final override def isType = true
override def isNonClassType = true
override def isTypeMacro = hasFlag(MACRO)
@@ -2737,6 +2714,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
incCounter(typeSymbolCount)
}
+ implicit val TypeSymbolTag = ClassTag[TypeSymbol](classOf[TypeSymbol])
/** A class for type parameters viewed from inside their scopes
*
@@ -2808,7 +2786,6 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
case _ => super.resolveOverloadedFlag(flag)
}
- final override def isClass = true
final override def isNonClassType = false
final override def isAbstractType = false
final override def isAliasType = false
@@ -2953,6 +2930,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
incCounter(classSymbolCount)
}
+ implicit val ClassSymbolTag = ClassTag[ClassSymbol](classOf[ClassSymbol])
/** A class for module class symbols
* Note: Not all module classes are of this type; when unpickled, we get
@@ -3048,15 +3026,15 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
trait FreeSymbol extends Symbol {
def origin: String
}
- class FreeTerm(name0: TermName, value0: => Any, val origin: String) extends TermSymbol(NoSymbol, NoPosition, name0) with FreeSymbol {
+ class FreeTermSymbol(name0: TermName, value0: => Any, val origin: String) extends TermSymbol(NoSymbol, NoPosition, name0) with FreeSymbol with FreeTermSymbolApi {
def value = value0
- override def isFreeTerm = true
}
+ implicit val FreeTermSymbolTag = ClassTag[FreeTermSymbol](classOf[FreeTermSymbol])
- class FreeType(name0: TypeName, value0: => Any, val origin: String) extends TypeSkolem(NoSymbol, NoPosition, name0, NoSymbol) with FreeSymbol {
+ class FreeTypeSymbol(name0: TypeName, value0: => Any, val origin: String) extends TypeSkolem(NoSymbol, NoPosition, name0, NoSymbol) with FreeSymbol with FreeTypeSymbolApi {
def value = value0
- override def isFreeType = true
}
+ implicit val FreeTypeSymbolTag = ClassTag[FreeTypeSymbol](classOf[FreeTypeSymbol])
/** An object representing a missing symbol */
class NoSymbol protected[Symbols]() extends Symbol(null, NoPosition, nme.NO_NAME) {
@@ -3101,7 +3079,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
override def existentialBound: Type = NoType
override def rawInfo: Type = NoType
protected def doCookJavaRawInfo() {}
- override def accessBoundary(base: Symbol): Symbol = RootClass
+ override def accessBoundary(base: Symbol): Symbol = enclosingRootClass
def cloneSymbolImpl(owner: Symbol, newFlags: Long) = abort("NoSymbol.clone()")
override def originalEnclosingMethod = this
diff --git a/src/compiler/scala/reflect/internal/TreeBuildUtil.scala b/src/compiler/scala/reflect/internal/TreeBuildUtil.scala
deleted file mode 100644
index d4d4652e91..0000000000
--- a/src/compiler/scala/reflect/internal/TreeBuildUtil.scala
+++ /dev/null
@@ -1,66 +0,0 @@
-package scala.reflect
-package internal
-
-import Flags._
-
-trait TreeBuildUtil extends api.TreeBuildUtil { self: SymbolTable =>
-
- // ``staticClass'' and ``staticModule'' rely on ClassLoaders
- // which are implementation-specific for different Universes
-
- def staticClassIfDefined(fullName: String): Symbol =
- try staticClass(fullName)
- catch { case _: MissingRequirementError => NoSymbol }
-
- def staticModuleIfDefined(fullName: String): Symbol =
- try staticModule(fullName)
- catch { case _: MissingRequirementError => NoSymbol }
-
- def thisModuleType(fullname: String) = staticModule(fullname).moduleClass.thisType
-
- def selectType(owner: Symbol, name: String): Symbol =
- owner.info.decl(newTypeName(name)) orElse {
- MissingRequirementError.notFound("type %s in %s".format(name, owner.fullName))
- }
-
- def selectTypeIfDefined(owner: Symbol, name: String): Symbol =
- try selectType(owner, name)
- catch { case _: MissingRequirementError => NoSymbol }
-
-// try getModule(fullname.toTermName)
-// catch { case _: MissingRequirementError => NoSymbol }
-
- def selectTerm(owner: Symbol, name: String): Symbol = {
- val sym = owner.info.decl(newTermName(name))
- val result =
- if (sym.isOverloaded) sym suchThat (!_.isMethod)
- else sym
- result orElse {
- MissingRequirementError.notFound("term %s in %s".format(name, owner.fullName))
- }
- }
-
- def selectTermIfDefined(owner: Symbol, name: String): Symbol =
- try selectTerm(owner, name)
- catch { case _: MissingRequirementError => NoSymbol }
-
- def selectOverloadedMethod(owner: Symbol, name: String, index: Int): Symbol =
- owner.info.decl(newTermName(name)).alternatives(index) orElse {
- MissingRequirementError.notFound("overloaded method %s #%d in %s".format(name, index, owner.fullName))
- }
-
- def selectOverloadedMethodIfDefined(owner: Symbol, name: String, index: Int): Symbol =
- try selectOverloadedMethod(owner, name, index)
- catch { case _: MissingRequirementError => NoSymbol }
-
- def newFreeTerm(name: String, info: Type, value: => Any, flags: Long = 0L, origin: String = null) = newFreeTermSymbol(newTermName(name), info, value, flags, origin)
-
- def newFreeType(name: String, info: Type, value: => Any, flags: Long = 0L, origin: String = null) = newFreeTypeSymbol(newTypeName(name), info, value, (if (flags == 0L) PARAM else flags) | DEFERRED, origin)
-
- def newFreeExistential(name: String, info: Type, value: => Any, flags: Long = 0L, origin: String = null) = newFreeTypeSymbol(newTypeName(name), info, value, (if (flags == 0L) EXISTENTIAL else flags) | DEFERRED, origin)
-
- def modifiersFromInternalFlags(flags: Long, privateWithin: Name, annotations: List[Tree]): Modifiers =
- Modifiers(flags, privateWithin, annotations)
-
- val gen: TreeGen { val global: TreeBuildUtil.this.type }
-} \ No newline at end of file
diff --git a/src/compiler/scala/reflect/internal/TreeGen.scala b/src/compiler/scala/reflect/internal/TreeGen.scala
index f2f9842595..c3a6fce164 100644
--- a/src/compiler/scala/reflect/internal/TreeGen.scala
+++ b/src/compiler/scala/reflect/internal/TreeGen.scala
@@ -1,7 +1,7 @@
package scala.reflect
package internal
-abstract class TreeGen extends api.AbsTreeGen {
+abstract class TreeGen extends makro.TreeBuilder {
val global: SymbolTable
import global._
@@ -269,4 +269,12 @@ abstract class TreeGen extends api.AbsTreeGen {
// tree1 OR tree2
def mkOr(tree1: Tree, tree2: Tree): Tree =
Apply(Select(tree1, Boolean_or), List(tree2))
+
+ def mkBasisUniverseRef: Tree =
+ mkAttributedRef(ReflectBasis) setType singleType(ReflectBasis.owner.thisPrefix, ReflectBasis)
+
+ def mkRuntimeUniverseRef: Tree = {
+ assert(ReflectRuntimeUniverse != NoSymbol)
+ mkAttributedRef(ReflectRuntimeUniverse) setType singleType(ReflectRuntimeUniverse.owner.thisPrefix, ReflectRuntimeUniverse)
+ }
}
diff --git a/src/compiler/scala/reflect/internal/TreeInfo.scala b/src/compiler/scala/reflect/internal/TreeInfo.scala
index 1528061adb..fc6e31ce1b 100644
--- a/src/compiler/scala/reflect/internal/TreeInfo.scala
+++ b/src/compiler/scala/reflect/internal/TreeInfo.scala
@@ -587,25 +587,7 @@ abstract class TreeInfo {
object TreeSplice {
def unapply(tree: Tree): Option[Tree] = tree match {
- case Select(splicee, _) if tree.symbol == ExprEval || tree.symbol == ExprValue =>
- Some(splicee)
- case _ =>
- None
- }
- }
-
- object EvalSplice {
- def unapply(tree: Tree): Option[Tree] = tree match {
- case Select(splicee, _) if tree.symbol == ExprEval =>
- Some(splicee)
- case _ =>
- None
- }
- }
-
- object ValueSplice {
- def unapply(tree: Tree): Option[Tree] = tree match {
- case Select(splicee, _) if tree.symbol == ExprValue =>
+ case Select(splicee, _) if tree.symbol == ExprSplice =>
Some(splicee)
case _ =>
None
@@ -634,7 +616,7 @@ abstract class TreeInfo {
object InlineableTreeSplice {
def unapply(tree: Tree): Option[(Tree, List[Tree], Tree, Tree, Symbol)] = tree match {
- case select @ Select(ReifiedTree(splicee, symbolTable, tree, tpe), _) if select.symbol == ExprEval || select.symbol == ExprValue =>
+ case select @ Select(ReifiedTree(splicee, symbolTable, tree, tpe), _) if select.symbol == ExprSplice =>
Some(splicee, symbolTable, tree, tpe, select.symbol)
case _ =>
None
@@ -643,7 +625,7 @@ abstract class TreeInfo {
object InlinedTreeSplice {
def unapply(tree: Tree): Option[(Tree, List[Tree], Tree, Tree)] = tree match {
- case Select(ReifiedTree(splicee, symbolTable, tree, tpe), name) if name == ExprTree.name =>
+ case Select(ReifiedTree(splicee, symbolTable, tree, tpe), name) if name == nme.tree =>
Some(splicee, symbolTable, tree, tpe)
case _ =>
None
@@ -661,7 +643,7 @@ abstract class TreeInfo {
object InlinedTypeSplice {
def unapply(tree: Tree): Option[(Tree, List[Tree], Tree)] = tree match {
- case Select(ReifiedType(splicee, symbolTable, tpe), name) if name == TypeTagTpe.name =>
+ case Select(ReifiedType(splicee, symbolTable, tpe), name) if name == nme.tpe =>
Some(splicee, symbolTable, tpe)
case _ =>
None
@@ -680,11 +662,9 @@ abstract class TreeInfo {
}
object FreeTermDef {
- lazy val newFreeTermMethod = getMember(getRequiredClass("scala.reflect.api.TreeBuildUtil"), nme.newFreeTerm)
-
def unapply(tree: Tree): Option[(Tree, TermName, Tree, Long, String)] = tree match {
case ValDef(_, name, _, Apply(Select(mrRef @ Ident(_), newFreeTerm), List(_, _, binding, Literal(Constant(flags: Long)), Literal(Constant(origin: String)))))
- if mrRef.name == nme.MIRROR_SHORT && newFreeTerm == newFreeTermMethod.name =>
+ if mrRef.name == nme.MIRROR_SHORT && newFreeTerm == nme.newFreeTerm =>
Some(mrRef, name, binding, flags, origin)
case _ =>
None
@@ -692,12 +672,9 @@ abstract class TreeInfo {
}
object FreeTypeDef {
- lazy val newFreeExistentialMethod = getMember(getRequiredClass("scala.reflect.api.TreeBuildUtil"), nme.newFreeType)
- lazy val newFreeTypeMethod = getMember(getRequiredClass("scala.reflect.api.TreeBuildUtil"), nme.newFreeExistential)
-
def unapply(tree: Tree): Option[(Tree, TermName, Tree, Long, String)] = tree match {
case ValDef(_, name, _, Apply(Select(mrRef1 @ Ident(_), newFreeType), List(_, _, value, Literal(Constant(flags: Long)), Literal(Constant(origin: String)))))
- if mrRef1.name == nme.MIRROR_SHORT && (newFreeType == newFreeTypeMethod.name || newFreeType == newFreeExistentialMethod.name) =>
+ if mrRef1.name == nme.MIRROR_SHORT && (newFreeType == nme.newFreeType || newFreeType == nme.newFreeExistential) =>
value match {
case Apply(TypeApply(Select(Select(mrRef2 @ Ident(_), typeTag), apply), List(binding)), List(Literal(Constant(null)), _))
if mrRef2.name == nme.MIRROR_SHORT && typeTag == nme.TypeTag && apply == nme.apply =>
diff --git a/src/compiler/scala/reflect/internal/TreePrinters.scala b/src/compiler/scala/reflect/internal/TreePrinters.scala
index e5a98c6b4e..6d035c8b9d 100644
--- a/src/compiler/scala/reflect/internal/TreePrinters.scala
+++ b/src/compiler/scala/reflect/internal/TreePrinters.scala
@@ -3,6 +3,8 @@
* @author Martin Odersky
*/
+// [Eugene++ to Martin] we need to unify this prettyprinter with NodePrinters
+
package scala.reflect
package internal
@@ -169,7 +171,7 @@ trait TreePrinters extends api.TreePrinters { self: SymbolTable =>
}
def printAnnotations(tree: Tree) {
- if (inReflexiveMirror && tree.symbol != null && tree.symbol != NoSymbol)
+ if (!isCompilerUniverse && tree.symbol != null && tree.symbol != NoSymbol)
// [Eugene++] todo. this is not 100% correct, but is necessary for sane printing
// the problem is that getting annotations doesn't automatically initialize the symbol
// so we might easily print something as if it doesn't have annotations, whereas it does
@@ -453,7 +455,7 @@ trait TreePrinters extends api.TreePrinters { self: SymbolTable =>
/** Hook for extensions */
def xprintTree(treePrinter: TreePrinter, tree: Tree) =
- treePrinter.print(tree.printingPrefix+tree.productIterator.mkString("(", ", ", ")"))
+ treePrinter.print(tree.productPrefix+tree.productIterator.mkString("(", ", ", ")"))
def newTreePrinter(writer: PrintWriter): TreePrinter = new TreePrinter(writer)
def newTreePrinter(stream: OutputStream): TreePrinter = newTreePrinter(new PrintWriter(stream))
diff --git a/src/compiler/scala/reflect/internal/Trees.scala b/src/compiler/scala/reflect/internal/Trees.scala
index 3e7f23800c..11d0790100 100644
--- a/src/compiler/scala/reflect/internal/Trees.scala
+++ b/src/compiler/scala/reflect/internal/Trees.scala
@@ -7,10 +7,808 @@ package scala.reflect
package internal
import Flags._
-import api.Modifier
+import base.Attachments
+import collection.mutable.{ListBuffer, LinkedHashSet}
trait Trees extends api.Trees { self: SymbolTable =>
+ private[scala] var nodeCount = 0
+
+ abstract class Tree extends TreeContextApiImpl with Product {
+ val id = nodeCount // TODO: add to attachment?
+ nodeCount += 1
+
+ @inline final def pos: Position = rawatt.pos
+ def pos_=(pos: Position): Unit = rawatt = (rawatt withPos pos)
+ def setPos(newpos: Position): this.type = { pos = newpos; this }
+
+ private var rawatt: Attachments { type Pos = Position } = NoPosition
+ def attachments = rawatt
+ def addAttachment(attachment: Any): this.type = { rawatt = rawatt.add(attachment); this }
+ def removeAttachment[T: ClassTag]: this.type = { rawatt = rawatt.remove[T]; this }
+
+ private[this] var rawtpe: Type = _
+ @inline final def tpe = rawtpe
+ def tpe_=(t: Type) = rawtpe = t
+ def setType(tp: Type): this.type = { rawtpe = tp; this }
+ def defineType(tp: Type): this.type = setType(tp)
+
+ def symbol: Symbol = null
+ def symbol_=(sym: Symbol) { throw new UnsupportedOperationException("symbol_= inapplicable for " + this) }
+ def setSymbol(sym: Symbol): this.type = { symbol = sym; this }
+ def hasSymbol = false
+
+ def isDef = false
+
+ def isEmpty = false
+
+ /** The canonical way to test if a Tree represents a term.
+ */
+ def isTerm: Boolean = this match {
+ case _: TermTree => true
+ case Bind(name, _) => name.isTermName
+ case Select(_, name) => name.isTermName
+ case Ident(name) => name.isTermName
+ case Annotated(_, arg) => arg.isTerm
+ case _ => false
+ }
+
+ /** The canonical way to test if a Tree represents a type.
+ */
+ def isType: Boolean = this match {
+ case _: TypTree => true
+ case Bind(name, _) => name.isTypeName
+ case Select(_, name) => name.isTypeName
+ case Ident(name) => name.isTypeName
+ case Annotated(_, arg) => arg.isType
+ case _ => false
+ }
+
+ private[scala] def copyAttrs(tree: Tree): this.type = {
+ rawatt = tree.rawatt
+ tpe = tree.tpe
+ if (hasSymbol) symbol = tree.symbol
+ this
+ }
+
+ override def hashCode(): Int = System.identityHashCode(this)
+ override def equals(that: Any) = this eq that.asInstanceOf[AnyRef]
+
+ override def duplicate: this.type =
+ (duplicator transform this).asInstanceOf[this.type]
+ }
+
+ abstract class TreeContextApiImpl extends TreeContextApi { this: Tree =>
+
+ override def orElse(alt: => Tree) = if (!isEmpty) this else alt
+
+ override def foreach(f: Tree => Unit) { new ForeachTreeTraverser(f).traverse(this) }
+
+ override def withFilter(f: Tree => Boolean): List[Tree] = {
+ val ft = new FilterTreeTraverser(f)
+ ft.traverse(this)
+ ft.hits.toList
+ }
+
+ override def filter(f: Tree => Boolean): List[Tree] = withFilter(f)
+
+ override def collect[T](pf: PartialFunction[Tree, T]): List[T] = {
+ val ctt = new CollectTreeTraverser[T](pf)
+ ctt.traverse(this)
+ ctt.results.toList
+ }
+
+ override def find(p: Tree => Boolean): Option[Tree] = {
+ val ft = new FindTreeTraverser(p)
+ ft.traverse(this)
+ ft.result
+ }
+
+ override def exists(p: Tree => Boolean): Boolean = !find(p).isEmpty
+
+ override def forAll(p: Tree => Boolean): Boolean = find(!p(_)).isEmpty
+
+ override def equalsStructure(that : Tree) = correspondsStructure(that)(_ eq _)
+
+ def correspondsStructure(that: Tree)(f: (Tree,Tree) => Boolean): Boolean =
+ f(this, that) || ((productArity == that.productArity) && {
+ def equals0(this0: Any, that0: Any): Boolean = (this0, that0) match {
+ case (x: Tree, y: Tree) => f(x, y) || (x correspondsStructure y)(f)
+ case (xs: List[_], ys: List[_]) => (xs corresponds ys)(equals0)
+ case _ => this0 == that0
+ }
+ def compareOriginals() = (this, that) match {
+ case (x: TypeTree, y: TypeTree) if x.original != null && y.original != null =>
+ (x.original correspondsStructure y.original)(f)
+ case _ =>
+ true
+ }
+
+ (productIterator zip that.productIterator forall { case (x, y) => equals0(x, y) }) && compareOriginals()
+ })
+
+ override def children: List[Tree] = {
+ def subtrees(x: Any): List[Tree] = x match {
+ case EmptyTree => Nil
+ case t: Tree => List(t)
+ case xs: List[_] => xs flatMap subtrees
+ case _ => Nil
+ }
+ productIterator.toList flatMap subtrees
+ }
+
+ override def freeTerms: List[FreeTermSymbol] = freeSyms[FreeTermSymbol](_.isFreeTerm, _.termSymbol)
+ override def freeTypes: List[FreeTypeSymbol] = freeSyms[FreeTypeSymbol](_.isFreeType, _.typeSymbol)
+
+ private def freeSyms[S <: Symbol](isFree: Symbol => Boolean, symOfType: Type => Symbol): List[S] = {
+ val s = collection.mutable.LinkedHashSet[S]()
+ def addIfFree(sym: Symbol): Unit = if (sym != null && isFree(sym)) s += sym.asInstanceOf[S]
+ for (t <- this) {
+ addIfFree(t.symbol)
+ if (t.tpe != null) {
+ for (tp <- t.tpe) {
+ addIfFree(symOfType(tp))
+ }
+ }
+ }
+ s.toList
+ }
+
+ override def substituteSymbols(from: List[Symbol], to: List[Symbol]): Tree =
+ new TreeSymSubstituter(from, to)(this)
+
+ override def substituteTypes(from: List[Symbol], to: List[Type]): Tree =
+ new TreeTypeSubstituter(from, to)(this)
+
+ override def substituteThis(clazz: Symbol, to: Tree): Tree =
+ new ThisSubstituter(clazz, to) transform this
+
+ def hasSymbolWhich(f: Symbol => Boolean) =
+ hasSymbol && symbol != null && f(symbol)
+
+ def isErroneous = (tpe ne null) && tpe.isErroneous
+ def isTyped = (tpe ne null) && !tpe.isErroneous
+
+ /** Sets the tree's type to the result of the given function.
+ * If the type is null, it remains null - the function is not called.
+ */
+ def modifyType(f: Type => Type): Tree =
+ if (tpe eq null) this
+ else this setType f(tpe)
+
+ /** If `pf` is defined for a given subtree, call super.traverse(pf(tree)),
+ * otherwise super.traverse(tree).
+ */
+ def foreachPartial(pf: PartialFunction[Tree, Tree]) {
+ new ForeachPartialTreeTraverser(pf).traverse(this)
+ }
+
+ def changeOwner(pairs: (Symbol, Symbol)*): Tree = {
+ pairs.foldLeft(this) { case (t, (oldOwner, newOwner)) =>
+ new ChangeOwnerTraverser(oldOwner, newOwner) apply t
+ }
+ }
+
+ def shallowDuplicate: Tree = new ShallowDuplicator(this) transform this
+ def shortClass: String = (getClass.getName split "[.$]").last
+
+ def isErrorTyped = (tpe ne null) && tpe.isError
+
+ /** When you want to know a little more than the class, but a lot
+ * less than the whole tree.
+ */
+ def summaryString: String = this match {
+ case Literal(const) => "Literal(" + const + ")"
+ case Ident(name) => "Ident(%s)".format(name.decode)
+ case Select(qual, name) => "Select(%s, %s)".format(qual.summaryString, name.decode)
+ case t: NameTree => t.name.longString
+ case t =>
+ t.shortClass + (
+ if (t.symbol != null && t.symbol != NoSymbol) "(" + t.symbol + ")"
+ else ""
+ )
+ }
+ }
+
+ trait TermTree extends Tree with TermTreeApi
+
+ trait TypTree extends Tree with TypTreeApi
+
+ trait SymTree extends Tree with SymTreeContextApi {
+ override def hasSymbol = true
+ override var symbol: Symbol = NoSymbol
+ }
+
+ trait NameTree extends Tree with NameTreeApi {
+ def name: Name
+ }
+
+ trait RefTree extends SymTree with NameTree with RefTreeApi {
+ def qualifier: Tree // empty for Idents
+ def name: Name
+ }
+
+ abstract class DefTree extends SymTree with NameTree with DefTreeApi {
+ def name: Name
+ override def isDef = true
+ }
+
+ case object EmptyTree extends TermTree {
+ super.tpe_=(NoType)
+ override def tpe_=(t: Type) =
+ if (t != NoType) throw new UnsupportedOperationException("tpe_=("+t+") inapplicable for <empty>")
+ override def isEmpty = true
+ }
+
+ abstract class MemberDef extends DefTree with MemberDefApi {
+ def mods: Modifiers
+ def keyword: String = this match {
+ case TypeDef(_, _, _, _) => "type"
+ case ClassDef(mods, _, _, _) => if (mods hasFlag TRAIT) "trait" else "class"
+ case DefDef(_, _, _, _, _, _) => "def"
+ case ModuleDef(_, _, _) => "object"
+ case PackageDef(_, _) => "package"
+ case ValDef(mods, _, _, _) => if (mods hasFlag MUTABLE) "var" else "val"
+ case _ => ""
+ }
+ }
+
+ case class PackageDef(pid: RefTree, stats: List[Tree])
+ extends MemberDef with PackageDefApi {
+ def name = pid.name
+ def mods = NoMods
+ }
+ object PackageDef extends PackageDefExtractor
+
+ abstract class ImplDef extends MemberDef with ImplDefApi {
+ def impl: Template
+ }
+
+ case class ClassDef(mods: Modifiers, name: TypeName, tparams: List[TypeDef], impl: Template)
+ extends ImplDef with ClassDefApi
+ object ClassDef extends ClassDefExtractor
+
+ case class ModuleDef(mods: Modifiers, name: TermName, impl: Template)
+ extends ImplDef with ModuleDefApi
+ object ModuleDef extends ModuleDefExtractor
+
+ abstract class ValOrDefDef extends MemberDef with ValOrDefDefApi {
+ def name: Name
+ def tpt: Tree
+ def rhs: Tree
+ }
+
+ case class ValDef(mods: Modifiers, name: TermName, tpt: Tree, rhs: Tree) extends ValOrDefDef with ValDefApi
+ object ValDef extends ValDefExtractor
+
+ case class DefDef(mods: Modifiers, name: Name, tparams: List[TypeDef],
+ vparamss: List[List[ValDef]], tpt: Tree, rhs: Tree) extends ValOrDefDef with DefDefApi
+ object DefDef extends DefDefExtractor
+
+ case class TypeDef(mods: Modifiers, name: TypeName, tparams: List[TypeDef], rhs: Tree)
+ extends MemberDef with TypeDefApi
+ object TypeDef extends TypeDefExtractor
+
+ case class LabelDef(name: TermName, params: List[Ident], rhs: Tree)
+ extends DefTree with TermTree with LabelDefApi
+ object LabelDef extends LabelDefExtractor
+
+ case class ImportSelector(name: Name, namePos: Int, rename: Name, renamePos: Int) extends ImportSelectorApi
+ object ImportSelector extends ImportSelectorExtractor
+
+ case class Import(expr: Tree, selectors: List[ImportSelector])
+ extends SymTree with ImportApi
+ object Import extends ImportExtractor
+
+ case class Template(parents: List[Tree], self: ValDef, body: List[Tree])
+ extends SymTree with TemplateApi
+ object Template extends TemplateExtractor
+
+ case class Block(stats: List[Tree], expr: Tree)
+ extends TermTree with BlockApi
+ object Block extends BlockExtractor
+
+ case class CaseDef(pat: Tree, guard: Tree, body: Tree)
+ extends Tree with CaseDefApi
+ object CaseDef extends CaseDefExtractor
+
+ case class Alternative(trees: List[Tree])
+ extends TermTree with AlternativeApi
+ object Alternative extends AlternativeExtractor
+
+ case class Star(elem: Tree)
+ extends TermTree with StarApi
+ object Star extends StarExtractor
+
+ case class Bind(name: Name, body: Tree)
+ extends DefTree with BindApi
+ object Bind extends BindExtractor
+
+ case class UnApply(fun: Tree, args: List[Tree])
+ extends TermTree with UnApplyApi
+ object UnApply extends UnApplyExtractor
+
+ case class ArrayValue(elemtpt: Tree, elems: List[Tree])
+ extends TermTree with ArrayValueApi
+ object ArrayValue extends ArrayValueExtractor
+
+ case class Function(vparams: List[ValDef], body: Tree)
+ extends TermTree with SymTree with FunctionApi
+ object Function extends FunctionExtractor
+
+ case class Assign(lhs: Tree, rhs: Tree)
+ extends TermTree with AssignApi
+ object Assign extends AssignExtractor
+
+ case class AssignOrNamedArg(lhs: Tree, rhs: Tree)
+ extends TermTree with AssignOrNamedArgApi
+ object AssignOrNamedArg extends AssignOrNamedArgExtractor
+
+ case class If(cond: Tree, thenp: Tree, elsep: Tree)
+ extends TermTree with IfApi
+ object If extends IfExtractor
+
+ case class Match(selector: Tree, cases: List[CaseDef])
+ extends TermTree with MatchApi
+ object Match extends MatchExtractor
+
+ case class Return(expr: Tree)
+ extends TermTree with SymTree with ReturnApi
+ object Return extends ReturnExtractor
+
+ case class Try(block: Tree, catches: List[CaseDef], finalizer: Tree)
+ extends TermTree with TryApi
+ object Try extends TryExtractor
+
+ case class Throw(expr: Tree)
+ extends TermTree with ThrowApi
+ object Throw extends ThrowExtractor
+
+ case class New(tpt: Tree) extends TermTree with NewApi
+ object New extends NewExtractor
+
+ case class Typed(expr: Tree, tpt: Tree)
+ extends TermTree with TypedApi
+ object Typed extends TypedExtractor
+
+ abstract class GenericApply extends TermTree with GenericApplyApi {
+ val fun: Tree
+ val args: List[Tree]
+ }
+
+ case class TypeApply(fun: Tree, args: List[Tree])
+ extends GenericApply with TypeApplyApi {
+ override def symbol: Symbol = fun.symbol
+ override def symbol_=(sym: Symbol) { fun.symbol = sym }
+ }
+ object TypeApply extends TypeApplyExtractor
+
+ case class Apply(fun: Tree, args: List[Tree])
+ extends GenericApply with ApplyApi {
+ override def symbol: Symbol = fun.symbol
+ override def symbol_=(sym: Symbol) { fun.symbol = sym }
+ }
+ object Apply extends ApplyExtractor
+
+ // TODO remove this class, add a tree attachment to Apply to track whether implicits were involved
+ // copying trees will all too easily forget to distinguish subclasses
+ class ApplyToImplicitArgs(fun: Tree, args: List[Tree]) extends Apply(fun, args)
+
+ // TODO remove this class, add a tree attachment to Apply to track whether implicits were involved
+ // copying trees will all too easily forget to distinguish subclasses
+ class ApplyImplicitView(fun: Tree, args: List[Tree]) extends Apply(fun, args)
+
+ def ApplyConstructor(tpt: Tree, args: List[Tree]) = Apply(Select(New(tpt), nme.CONSTRUCTOR), args)
+
+ case class ApplyDynamic(qual: Tree, args: List[Tree])
+ extends TermTree with SymTree with ApplyDynamicApi
+ object ApplyDynamic extends ApplyDynamicExtractor
+
+ case class Super(qual: Tree, mix: TypeName) extends TermTree with SuperApi {
+ override def symbol: Symbol = qual.symbol
+ override def symbol_=(sym: Symbol) { qual.symbol = sym }
+ }
+ object Super extends SuperExtractor
+
+ case class This(qual: TypeName)
+ extends TermTree with SymTree with ThisApi
+ object This extends ThisExtractor
+
+ case class Select(qualifier: Tree, name: Name)
+ extends RefTree with SelectApi
+ object Select extends SelectExtractor
+
+ case class Ident(name: Name) extends RefTree with IdentContextApi {
+ def qualifier: Tree = EmptyTree
+ def isBackquoted = this.attachments.get[BackquotedIdentifierAttachment.type].isDefined
+ }
+ object Ident extends IdentExtractor
+
+ case class ReferenceToBoxed(ident: Ident) extends TermTree with ReferenceToBoxedApi {
+ override def symbol: Symbol = ident.symbol
+ override def symbol_=(sym: Symbol) { ident.symbol = sym }
+ }
+ object ReferenceToBoxed extends ReferenceToBoxedExtractor
+
+ case class Literal(value: Constant)
+ extends TermTree with LiteralApi {
+ assert(value ne null)
+ }
+ object Literal extends LiteralExtractor
+
+// @deprecated("will be removed and then be re-introduced with changed semantics, use Literal(Constant(x)) instead")
+// def Literal(x: Any) = new Literal(Constant(x))
+
+ case class Annotated(annot: Tree, arg: Tree) extends Tree with AnnotatedApi
+ object Annotated extends AnnotatedExtractor
+
+ case class SingletonTypeTree(ref: Tree)
+ extends TypTree with SingletonTypeTreeApi
+ object SingletonTypeTree extends SingletonTypeTreeExtractor
+
+ case class SelectFromTypeTree(qualifier: Tree, name: TypeName)
+ extends TypTree with RefTree with SelectFromTypeTreeApi
+ object SelectFromTypeTree extends SelectFromTypeTreeExtractor
+
+ case class CompoundTypeTree(templ: Template)
+ extends TypTree with CompoundTypeTreeApi
+ object CompoundTypeTree extends CompoundTypeTreeExtractor
+
+ case class AppliedTypeTree(tpt: Tree, args: List[Tree])
+ extends TypTree with AppliedTypeTreeApi {
+ override def symbol: Symbol = tpt.symbol
+ override def symbol_=(sym: Symbol) { tpt.symbol = sym }
+ }
+ object AppliedTypeTree extends AppliedTypeTreeExtractor
+
+ case class TypeBoundsTree(lo: Tree, hi: Tree)
+ extends TypTree with TypeBoundsTreeApi
+ object TypeBoundsTree extends TypeBoundsTreeExtractor
+
+ case class ExistentialTypeTree(tpt: Tree, whereClauses: List[Tree])
+ extends TypTree with ExistentialTypeTreeApi
+ object ExistentialTypeTree extends ExistentialTypeTreeExtractor
+
+ case class TypeTree() extends TypTree with TypeTreeContextApi {
+ private var orig: Tree = null
+ private[scala] var wasEmpty: Boolean = false
+
+ override def symbol = if (tpe == null) null else tpe.typeSymbol
+ override def isEmpty = (tpe eq null) || tpe == NoType
+
+ def original: Tree = orig
+ def setOriginal(tree: Tree): this.type = {
+ def followOriginal(t: Tree): Tree = t match {
+ case tt: TypeTree => followOriginal(tt.original)
+ case t => t
+ }
+
+ orig = followOriginal(tree); setPos(tree.pos);
+ this
+ }
+
+ override def defineType(tp: Type): this.type = {
+ wasEmpty = isEmpty
+ setType(tp)
+ }
+ }
+ object TypeTree extends TypeTreeExtractor
+
+ def TypeTree(tp: Type): TypeTree = TypeTree() setType tp
+
+ class StrictTreeCopier extends TreeCopierOps {
+ def ClassDef(tree: Tree, mods: Modifiers, name: Name, tparams: List[TypeDef], impl: Template) =
+ new ClassDef(mods, name.toTypeName, tparams, impl).copyAttrs(tree)
+ def PackageDef(tree: Tree, pid: RefTree, stats: List[Tree]) =
+ new PackageDef(pid, stats).copyAttrs(tree)
+ def ModuleDef(tree: Tree, mods: Modifiers, name: Name, impl: Template) =
+ new ModuleDef(mods, name.toTermName, impl).copyAttrs(tree)
+ def ValDef(tree: Tree, mods: Modifiers, name: Name, tpt: Tree, rhs: Tree) =
+ new ValDef(mods, name.toTermName, tpt, rhs).copyAttrs(tree)
+ def DefDef(tree: Tree, mods: Modifiers, name: Name, tparams: List[TypeDef], vparamss: List[List[ValDef]], tpt: Tree, rhs: Tree) =
+ new DefDef(mods, name.toTermName, tparams, vparamss, tpt, rhs).copyAttrs(tree)
+ def TypeDef(tree: Tree, mods: Modifiers, name: Name, tparams: List[TypeDef], rhs: Tree) =
+ new TypeDef(mods, name.toTypeName, tparams, rhs).copyAttrs(tree)
+ def LabelDef(tree: Tree, name: Name, params: List[Ident], rhs: Tree) =
+ new LabelDef(name.toTermName, params, rhs).copyAttrs(tree)
+ def Import(tree: Tree, expr: Tree, selectors: List[ImportSelector]) =
+ new Import(expr, selectors).copyAttrs(tree)
+ def Template(tree: Tree, parents: List[Tree], self: ValDef, body: List[Tree]) =
+ new Template(parents, self, body).copyAttrs(tree)
+ def Block(tree: Tree, stats: List[Tree], expr: Tree) =
+ new Block(stats, expr).copyAttrs(tree)
+ def CaseDef(tree: Tree, pat: Tree, guard: Tree, body: Tree) =
+ new CaseDef(pat, guard, body).copyAttrs(tree)
+ def Alternative(tree: Tree, trees: List[Tree]) =
+ new Alternative(trees).copyAttrs(tree)
+ def Star(tree: Tree, elem: Tree) =
+ new Star(elem).copyAttrs(tree)
+ def Bind(tree: Tree, name: Name, body: Tree) =
+ new Bind(name, body).copyAttrs(tree)
+ def UnApply(tree: Tree, fun: Tree, args: List[Tree]) =
+ new UnApply(fun, args).copyAttrs(tree)
+ def ArrayValue(tree: Tree, elemtpt: Tree, trees: List[Tree]) =
+ new ArrayValue(elemtpt, trees).copyAttrs(tree)
+ def Function(tree: Tree, vparams: List[ValDef], body: Tree) =
+ new Function(vparams, body).copyAttrs(tree)
+ def Assign(tree: Tree, lhs: Tree, rhs: Tree) =
+ new Assign(lhs, rhs).copyAttrs(tree)
+ def AssignOrNamedArg(tree: Tree, lhs: Tree, rhs: Tree) =
+ new AssignOrNamedArg(lhs, rhs).copyAttrs(tree)
+ def If(tree: Tree, cond: Tree, thenp: Tree, elsep: Tree) =
+ new If(cond, thenp, elsep).copyAttrs(tree)
+ def Match(tree: Tree, selector: Tree, cases: List[CaseDef]) =
+ new Match(selector, cases).copyAttrs(tree)
+ def Return(tree: Tree, expr: Tree) =
+ new Return(expr).copyAttrs(tree)
+ def Try(tree: Tree, block: Tree, catches: List[CaseDef], finalizer: Tree) =
+ new Try(block, catches, finalizer).copyAttrs(tree)
+ def Throw(tree: Tree, expr: Tree) =
+ new Throw(expr).copyAttrs(tree)
+ def New(tree: Tree, tpt: Tree) =
+ new New(tpt).copyAttrs(tree)
+ def Typed(tree: Tree, expr: Tree, tpt: Tree) =
+ new Typed(expr, tpt).copyAttrs(tree)
+ def TypeApply(tree: Tree, fun: Tree, args: List[Tree]) =
+ new TypeApply(fun, args).copyAttrs(tree)
+ def Apply(tree: Tree, fun: Tree, args: List[Tree]) =
+ (tree match { // TODO: use a tree attachment to track whether this is an apply to implicit args or a view
+ case _: ApplyToImplicitArgs => new ApplyToImplicitArgs(fun, args)
+ case _: ApplyImplicitView => new ApplyImplicitView(fun, args)
+ // TODO: ApplyConstructor ???
+ case _ => new Apply(fun, args)
+ }).copyAttrs(tree)
+ def ApplyDynamic(tree: Tree, qual: Tree, args: List[Tree]) =
+ new ApplyDynamic(qual, args).copyAttrs(tree)
+ def Super(tree: Tree, qual: Tree, mix: TypeName) =
+ new Super(qual, mix).copyAttrs(tree)
+ def This(tree: Tree, qual: Name) =
+ new This(qual.toTypeName).copyAttrs(tree)
+ def Select(tree: Tree, qualifier: Tree, selector: Name) =
+ new Select(qualifier, selector).copyAttrs(tree)
+ def Ident(tree: Tree, name: Name) =
+ new Ident(name) copyAttrs tree
+ def ReferenceToBoxed(tree: Tree, idt: Ident) =
+ new ReferenceToBoxed(idt).copyAttrs(tree)
+ def Literal(tree: Tree, value: Constant) =
+ new Literal(value).copyAttrs(tree)
+ def TypeTree(tree: Tree) =
+ new TypeTree().copyAttrs(tree)
+ def Annotated(tree: Tree, annot: Tree, arg: Tree) =
+ new Annotated(annot, arg).copyAttrs(tree)
+ def SingletonTypeTree(tree: Tree, ref: Tree) =
+ new SingletonTypeTree(ref).copyAttrs(tree)
+ def SelectFromTypeTree(tree: Tree, qualifier: Tree, selector: Name) =
+ new SelectFromTypeTree(qualifier, selector.toTypeName).copyAttrs(tree)
+ def CompoundTypeTree(tree: Tree, templ: Template) =
+ new CompoundTypeTree(templ).copyAttrs(tree)
+ def AppliedTypeTree(tree: Tree, tpt: Tree, args: List[Tree]) =
+ new AppliedTypeTree(tpt, args).copyAttrs(tree)
+ def TypeBoundsTree(tree: Tree, lo: Tree, hi: Tree) =
+ new TypeBoundsTree(lo, hi).copyAttrs(tree)
+ def ExistentialTypeTree(tree: Tree, tpt: Tree, whereClauses: List[Tree]) =
+ new ExistentialTypeTree(tpt, whereClauses).copyAttrs(tree)
+ }
+
+ class LazyTreeCopier extends TreeCopierOps {
+ val treeCopy: TreeCopier = newStrictTreeCopier
+ def ClassDef(tree: Tree, mods: Modifiers, name: Name, tparams: List[TypeDef], impl: Template) = tree match {
+ case t @ ClassDef(mods0, name0, tparams0, impl0)
+ if (mods0 == mods) && (name0 == name) && (tparams0 == tparams) && (impl0 == impl) => t
+ case _ => treeCopy.ClassDef(tree, mods, name, tparams, impl)
+ }
+ def PackageDef(tree: Tree, pid: RefTree, stats: List[Tree]) = tree match {
+ case t @ PackageDef(pid0, stats0)
+ if (pid0 == pid) && (stats0 == stats) => t
+ case _ => treeCopy.PackageDef(tree, pid, stats)
+ }
+ def ModuleDef(tree: Tree, mods: Modifiers, name: Name, impl: Template) = tree match {
+ case t @ ModuleDef(mods0, name0, impl0)
+ if (mods0 == mods) && (name0 == name) && (impl0 == impl) => t
+ case _ => treeCopy.ModuleDef(tree, mods, name, impl)
+ }
+ def ValDef(tree: Tree, mods: Modifiers, name: Name, tpt: Tree, rhs: Tree) = tree match {
+ case t @ ValDef(mods0, name0, tpt0, rhs0)
+ if (mods0 == mods) && (name0 == name) && (tpt0 == tpt) && (rhs0 == rhs) => t
+ case _ => treeCopy.ValDef(tree, mods, name, tpt, rhs)
+ }
+ def DefDef(tree: Tree, mods: Modifiers, name: Name, tparams: List[TypeDef], vparamss: List[List[ValDef]], tpt: Tree, rhs: Tree) = tree match {
+ case t @ DefDef(mods0, name0, tparams0, vparamss0, tpt0, rhs0)
+ if (mods0 == mods) && (name0 == name) && (tparams0 == tparams) &&
+ (vparamss0 == vparamss) && (tpt0 == tpt) && (rhs == rhs0) => t
+ case _ => treeCopy.DefDef(tree, mods, name, tparams, vparamss, tpt, rhs)
+ }
+ def TypeDef(tree: Tree, mods: Modifiers, name: Name, tparams: List[TypeDef], rhs: Tree) = tree match {
+ case t @ TypeDef(mods0, name0, tparams0, rhs0)
+ if (mods0 == mods) && (name0 == name) && (tparams0 == tparams) && (rhs0 == rhs) => t
+ case _ => treeCopy.TypeDef(tree, mods, name, tparams, rhs)
+ }
+ def LabelDef(tree: Tree, name: Name, params: List[Ident], rhs: Tree) = tree match {
+ case t @ LabelDef(name0, params0, rhs0)
+ if (name0 == name) && (params0 == params) && (rhs0 == rhs) => t
+ case _ => treeCopy.LabelDef(tree, name, params, rhs)
+ }
+ def Import(tree: Tree, expr: Tree, selectors: List[ImportSelector]) = tree match {
+ case t @ Import(expr0, selectors0)
+ if (expr0 == expr) && (selectors0 == selectors) => t
+ case _ => treeCopy.Import(tree, expr, selectors)
+ }
+ def Template(tree: Tree, parents: List[Tree], self: ValDef, body: List[Tree]) = tree match {
+ case t @ Template(parents0, self0, body0)
+ if (parents0 == parents) && (self0 == self) && (body0 == body) => t
+ case _ => treeCopy.Template(tree, parents, self, body)
+ }
+ def Block(tree: Tree, stats: List[Tree], expr: Tree) = tree match {
+ case t @ Block(stats0, expr0)
+ if ((stats0 == stats) && (expr0 == expr)) => t
+ case _ => treeCopy.Block(tree, stats, expr)
+ }
+ def CaseDef(tree: Tree, pat: Tree, guard: Tree, body: Tree) = tree match {
+ case t @ CaseDef(pat0, guard0, body0)
+ if (pat0 == pat) && (guard0 == guard) && (body0 == body) => t
+ case _ => treeCopy.CaseDef(tree, pat, guard, body)
+ }
+ def Alternative(tree: Tree, trees: List[Tree]) = tree match {
+ case t @ Alternative(trees0)
+ if trees0 == trees => t
+ case _ => treeCopy.Alternative(tree, trees)
+ }
+ def Star(tree: Tree, elem: Tree) = tree match {
+ case t @ Star(elem0)
+ if elem0 == elem => t
+ case _ => treeCopy.Star(tree, elem)
+ }
+ def Bind(tree: Tree, name: Name, body: Tree) = tree match {
+ case t @ Bind(name0, body0)
+ if (name0 == name) && (body0 == body) => t
+ case _ => treeCopy.Bind(tree, name, body)
+ }
+ def UnApply(tree: Tree, fun: Tree, args: List[Tree]) = tree match {
+ case t @ UnApply(fun0, args0)
+ if (fun0 == fun) && (args0 == args) => t
+ case _ => treeCopy.UnApply(tree, fun, args)
+ }
+ def ArrayValue(tree: Tree, elemtpt: Tree, trees: List[Tree]) = tree match {
+ case t @ ArrayValue(elemtpt0, trees0)
+ if (elemtpt0 == elemtpt) && (trees0 == trees) => t
+ case _ => treeCopy.ArrayValue(tree, elemtpt, trees)
+ }
+ def Function(tree: Tree, vparams: List[ValDef], body: Tree) = tree match {
+ case t @ Function(vparams0, body0)
+ if (vparams0 == vparams) && (body0 == body) => t
+ case _ => treeCopy.Function(tree, vparams, body)
+ }
+ def Assign(tree: Tree, lhs: Tree, rhs: Tree) = tree match {
+ case t @ Assign(lhs0, rhs0)
+ if (lhs0 == lhs) && (rhs0 == rhs) => t
+ case _ => treeCopy.Assign(tree, lhs, rhs)
+ }
+ def AssignOrNamedArg(tree: Tree, lhs: Tree, rhs: Tree) = tree match {
+ case t @ AssignOrNamedArg(lhs0, rhs0)
+ if (lhs0 == lhs) && (rhs0 == rhs) => t
+ case _ => treeCopy.AssignOrNamedArg(tree, lhs, rhs)
+ }
+ def If(tree: Tree, cond: Tree, thenp: Tree, elsep: Tree) = tree match {
+ case t @ If(cond0, thenp0, elsep0)
+ if (cond0 == cond) && (thenp0 == thenp) && (elsep0 == elsep) => t
+ case _ => treeCopy.If(tree, cond, thenp, elsep)
+ }
+ def Match(tree: Tree, selector: Tree, cases: List[CaseDef]) = tree match {
+ case t @ Match(selector0, cases0)
+ if (selector0 == selector) && (cases0 == cases) => t
+ case _ => treeCopy.Match(tree, selector, cases)
+ }
+ def Return(tree: Tree, expr: Tree) = tree match {
+ case t @ Return(expr0)
+ if expr0 == expr => t
+ case _ => treeCopy.Return(tree, expr)
+ }
+ def Try(tree: Tree, block: Tree, catches: List[CaseDef], finalizer: Tree) = tree match {
+ case t @ Try(block0, catches0, finalizer0)
+ if (block0 == block) && (catches0 == catches) && (finalizer0 == finalizer) => t
+ case _ => treeCopy.Try(tree, block, catches, finalizer)
+ }
+ def Throw(tree: Tree, expr: Tree) = tree match {
+ case t @ Throw(expr0)
+ if expr0 == expr => t
+ case _ => treeCopy.Throw(tree, expr)
+ }
+ def New(tree: Tree, tpt: Tree) = tree match {
+ case t @ New(tpt0)
+ if tpt0 == tpt => t
+ case _ => treeCopy.New(tree, tpt)
+ }
+ def Typed(tree: Tree, expr: Tree, tpt: Tree) = tree match {
+ case t @ Typed(expr0, tpt0)
+ if (expr0 == expr) && (tpt0 == tpt) => t
+ case _ => treeCopy.Typed(tree, expr, tpt)
+ }
+ def TypeApply(tree: Tree, fun: Tree, args: List[Tree]) = tree match {
+ case t @ TypeApply(fun0, args0)
+ if (fun0 == fun) && (args0 == args) => t
+ case _ => treeCopy.TypeApply(tree, fun, args)
+ }
+ def Apply(tree: Tree, fun: Tree, args: List[Tree]) = tree match {
+ case t @ Apply(fun0, args0)
+ if (fun0 == fun) && (args0 == args) => t
+ case _ => treeCopy.Apply(tree, fun, args)
+ }
+ def ApplyDynamic(tree: Tree, qual: Tree, args: List[Tree]) = tree match {
+ case t @ ApplyDynamic(qual0, args0)
+ if (qual0 == qual) && (args0 == args) => t
+ case _ => treeCopy.ApplyDynamic(tree, qual, args)
+ }
+ def Super(tree: Tree, qual: Tree, mix: TypeName) = tree match {
+ case t @ Super(qual0, mix0)
+ if (qual0 == qual) && (mix0 == mix) => t
+ case _ => treeCopy.Super(tree, qual, mix)
+ }
+ def This(tree: Tree, qual: Name) = tree match {
+ case t @ This(qual0)
+ if qual0 == qual => t
+ case _ => treeCopy.This(tree, qual)
+ }
+ def Select(tree: Tree, qualifier: Tree, selector: Name) = tree match {
+ case t @ Select(qualifier0, selector0)
+ if (qualifier0 == qualifier) && (selector0 == selector) => t
+ case _ => treeCopy.Select(tree, qualifier, selector)
+ }
+ def Ident(tree: Tree, name: Name) = tree match {
+ case t @ Ident(name0)
+ if name0 == name => t
+ case _ => treeCopy.Ident(tree, name)
+ }
+ def ReferenceToBoxed(tree: Tree, idt: Ident) = tree match {
+ case t @ ReferenceToBoxed(idt0)
+ if (idt0 == idt) => t
+ case _ => this.treeCopy.ReferenceToBoxed(tree, idt)
+ }
+ def Literal(tree: Tree, value: Constant) = tree match {
+ case t @ Literal(value0)
+ if value0 == value => t
+ case _ => treeCopy.Literal(tree, value)
+ }
+ def TypeTree(tree: Tree) = tree match {
+ case t @ TypeTree() => t
+ case _ => treeCopy.TypeTree(tree)
+ }
+ def Annotated(tree: Tree, annot: Tree, arg: Tree) = tree match {
+ case t @ Annotated(annot0, arg0)
+ if (annot0==annot) => t
+ case _ => treeCopy.Annotated(tree, annot, arg)
+ }
+ def SingletonTypeTree(tree: Tree, ref: Tree) = tree match {
+ case t @ SingletonTypeTree(ref0)
+ if ref0 == ref => t
+ case _ => treeCopy.SingletonTypeTree(tree, ref)
+ }
+ def SelectFromTypeTree(tree: Tree, qualifier: Tree, selector: Name) = tree match {
+ case t @ SelectFromTypeTree(qualifier0, selector0)
+ if (qualifier0 == qualifier) && (selector0 == selector) => t
+ case _ => treeCopy.SelectFromTypeTree(tree, qualifier, selector)
+ }
+ def CompoundTypeTree(tree: Tree, templ: Template) = tree match {
+ case t @ CompoundTypeTree(templ0)
+ if templ0 == templ => t
+ case _ => treeCopy.CompoundTypeTree(tree, templ)
+ }
+ def AppliedTypeTree(tree: Tree, tpt: Tree, args: List[Tree]) = tree match {
+ case t @ AppliedTypeTree(tpt0, args0)
+ if (tpt0 == tpt) && (args0 == args) => t
+ case _ => treeCopy.AppliedTypeTree(tree, tpt, args)
+ }
+ def TypeBoundsTree(tree: Tree, lo: Tree, hi: Tree) = tree match {
+ case t @ TypeBoundsTree(lo0, hi0)
+ if (lo0 == lo) && (hi0 == hi) => t
+ case _ => treeCopy.TypeBoundsTree(tree, lo, hi)
+ }
+ def ExistentialTypeTree(tree: Tree, tpt: Tree, whereClauses: List[Tree]) = tree match {
+ case t @ ExistentialTypeTree(tpt0, whereClauses0)
+ if (tpt0 == tpt) && (whereClauses0 == whereClauses) => t
+ case _ => treeCopy.ExistentialTypeTree(tree, tpt, whereClauses)
+ }
+ }
+
// Belongs in TreeInfo but then I can't reach it from TreePrinters.
def isReferenceToScalaMember(t: Tree, Id: Name) = t match {
case Ident(Id) => true
@@ -33,7 +831,7 @@ trait Trees extends api.Trees { self: SymbolTable =>
*/
case class Modifiers(flags: Long,
privateWithin: Name,
- annotations: List[Tree]) extends AbsModifiers with HasFlags {
+ annotations: List[Tree]) extends ModifiersApi with HasFlags {
var positions: Map[Long, Position] = Map()
@@ -79,82 +877,15 @@ trait Trees extends api.Trees { self: SymbolTable =>
def withPosition(flag: Long, position: Position) =
copy() setPositions positions + (flag -> position)
- override def hasModifier(mod: Modifier) =
- hasFlag(flagOfModifier(mod))
- 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
override def toString = "Modifiers(%s, %s, %s)".format(flagString, annotations mkString ", ", positions)
}
- def Modifiers(flags: Long, privateWithin: Name): Modifiers = Modifiers(flags, privateWithin, List())
- def Modifiers(flags: Long): Modifiers = Modifiers(flags, tpnme.EMPTY)
+ object Modifiers extends ModifiersCreator
- def Modifiers(mods: Set[Modifier],
- privateWithin: Name,
- annotations: List[Tree]): Modifiers = {
- val flagSet = mods map flagOfModifier
- Modifiers((0L /: flagSet)(_ | _), privateWithin, annotations)
- }
-
- lazy val NoMods = Modifiers(0)
-
- // --- extension methods --------------------------------------------------------
-
- implicit class TreeOps(tree: Tree) {
- def isErroneous = (tree.tpe ne null) && tree.tpe.isErroneous
- def isTyped = (tree.tpe ne null) && !tree.tpe.isErroneous
-
- /** Sets the tree's type to the result of the given function.
- * If the type is null, it remains null - the function is not called.
- */
- def modifyType(f: Type => Type): Tree =
- if (tree.tpe eq null) tree
- else tree setType f(tree.tpe)
-
- /** If `pf` is defined for a given subtree, call super.traverse(pf(tree)),
- * otherwise super.traverse(tree).
- */
- def foreachPartial(pf: PartialFunction[Tree, Tree]) {
- new ForeachPartialTreeTraverser(pf).traverse(tree)
- }
-
- def changeOwner(pairs: (Symbol, Symbol)*): Tree = {
- pairs.foldLeft(tree) { case (t, (oldOwner, newOwner)) =>
- new ChangeOwnerTraverser(oldOwner, newOwner) apply t
- }
- }
-
- def substTreeSyms(pairs: (Symbol, Symbol)*): Tree =
- substTreeSyms(pairs.map(_._1).toList, pairs.map(_._2).toList)
-
- def substTreeSyms(from: List[Symbol], to: List[Symbol]): Tree =
- new TreeSymSubstituter(from, to)(tree)
-
- def substTreeThis(clazz: Symbol, to: Tree): Tree = new ThisSubstituter(clazz, to) transform tree
-
- def shallowDuplicate: Tree = new ShallowDuplicator(tree) transform tree
- def shortClass: String = tree.getClass.getName split "[.$]" last
-
- def isErrorTyped = (tree.tpe ne null) && tree.tpe.isError
-
- /** When you want to know a little more than the class, but a lot
- * less than the whole tree.
- */
- def summaryString: String = tree match {
- case Literal(const) => "Literal(" + const + ")"
- case Ident(name) => "Ident(%s)".format(name.decode)
- case Select(qual, name) => "Select(%s, %s)".format(qual.summaryString, name.decode)
- case t: NameTree => t.name.longString
- case t =>
- t.shortClass + (
- if (t.symbol != null && t.symbol != NoSymbol) "(" + t.symbol + ")"
- else ""
- )
- }
- }
+ implicit val ModifiersTag = ClassTag[Modifiers](classOf[Modifiers])
// ---- values and creators ---------------------------------------
@@ -251,14 +982,19 @@ trait Trees extends api.Trees { self: SymbolTable =>
* A `New(t, as)` is expanded to: `(new t).<init>(as)`
*/
def New(tpt: Tree, argss: List[List[Tree]]): Tree = argss match {
- case Nil => new ApplyConstructor(tpt, Nil)
- case xs :: rest => rest.foldLeft(new ApplyConstructor(tpt, xs): Tree)(Apply)
+ case Nil => ApplyConstructor(tpt, Nil)
+ case xs :: rest => {
+ def mkApply(fun: Tree, args: List[Tree]) = Apply(fun, args)
+ rest.foldLeft(ApplyConstructor(tpt, xs): Tree)(mkApply)
+ // [Eugene++] no longer compiles after I moved the `Apply` case class here
+ // rest.foldLeft(ApplyConstructor(tpt, xs): Tree)(Apply)
+ }
}
/** 0-1 argument list new, based on a type.
*/
def New(tpe: Type, args: Tree*): Tree =
- new ApplyConstructor(TypeTree(tpe), args.toList)
+ ApplyConstructor(TypeTree(tpe), args.toList)
def New(sym: Symbol, args: Tree*): Tree =
New(sym.tpe, args: _*)
@@ -292,20 +1028,244 @@ trait Trees extends api.Trees { self: SymbolTable =>
}
}
- // --- specific traversers and transformers
- // todo. move these into scala.reflect.api
-
- protected[scala] def duplicateTree(tree: Tree): Tree = duplicator transform tree
+ // --- generic traversers and transformers
+
+ override protected def itraverse(traverser: Traverser, tree: Tree): Unit = {
+ import traverser._
+ tree match {
+ case EmptyTree =>
+ ;
+ case PackageDef(pid, stats) =>
+ traverse(pid)
+ atOwner(mclass(tree.symbol)) {
+ traverseTrees(stats)
+ }
+ case ClassDef(mods, name, tparams, impl) =>
+ atOwner(tree.symbol) {
+ traverseTrees(mods.annotations); traverseTrees(tparams); traverse(impl)
+ }
+ case ModuleDef(mods, name, impl) =>
+ atOwner(mclass(tree.symbol)) {
+ traverseTrees(mods.annotations); traverse(impl)
+ }
+ case ValDef(mods, name, tpt, rhs) =>
+ atOwner(tree.symbol) {
+ traverseTrees(mods.annotations); traverse(tpt); traverse(rhs)
+ }
+ case DefDef(mods, name, tparams, vparamss, tpt, rhs) =>
+ atOwner(tree.symbol) {
+ traverseTrees(mods.annotations); traverseTrees(tparams); traverseTreess(vparamss); traverse(tpt); traverse(rhs)
+ }
+ case TypeDef(mods, name, tparams, rhs) =>
+ atOwner(tree.symbol) {
+ traverseTrees(mods.annotations); traverseTrees(tparams); traverse(rhs)
+ }
+ case LabelDef(name, params, rhs) =>
+ traverseTrees(params); traverse(rhs)
+ case Import(expr, selectors) =>
+ traverse(expr)
+ case Annotated(annot, arg) =>
+ traverse(annot); traverse(arg)
+ case Template(parents, self, body) =>
+ traverseTrees(parents)
+ if (!self.isEmpty) traverse(self)
+ traverseStats(body, tree.symbol)
+ case Block(stats, expr) =>
+ traverseTrees(stats); traverse(expr)
+ case CaseDef(pat, guard, body) =>
+ traverse(pat); traverse(guard); traverse(body)
+ case Alternative(trees) =>
+ traverseTrees(trees)
+ case Star(elem) =>
+ traverse(elem)
+ case Bind(name, body) =>
+ traverse(body)
+ case UnApply(fun, args) =>
+ traverse(fun); traverseTrees(args)
+ case ArrayValue(elemtpt, trees) =>
+ traverse(elemtpt); traverseTrees(trees)
+ case Function(vparams, body) =>
+ atOwner(tree.symbol) {
+ traverseTrees(vparams); traverse(body)
+ }
+ case Assign(lhs, rhs) =>
+ traverse(lhs); traverse(rhs)
+ case AssignOrNamedArg(lhs, rhs) =>
+ traverse(lhs); traverse(rhs)
+ case If(cond, thenp, elsep) =>
+ traverse(cond); traverse(thenp); traverse(elsep)
+ case Match(selector, cases) =>
+ traverse(selector); traverseTrees(cases)
+ case Return(expr) =>
+ traverse(expr)
+ case Try(block, catches, finalizer) =>
+ traverse(block); traverseTrees(catches); traverse(finalizer)
+ case Throw(expr) =>
+ traverse(expr)
+ case New(tpt) =>
+ traverse(tpt)
+ case Typed(expr, tpt) =>
+ traverse(expr); traverse(tpt)
+ case TypeApply(fun, args) =>
+ traverse(fun); traverseTrees(args)
+ case Apply(fun, args) =>
+ traverse(fun); traverseTrees(args)
+ case ApplyDynamic(qual, args) =>
+ traverse(qual); traverseTrees(args)
+ case Super(qual, _) =>
+ traverse(qual)
+ case This(_) =>
+ ;
+ case Select(qualifier, selector) =>
+ traverse(qualifier)
+ case Ident(_) =>
+ ;
+ case ReferenceToBoxed(idt) =>
+ traverse(idt)
+ case Literal(_) =>
+ ;
+ case TypeTree() =>
+ ;
+ case SingletonTypeTree(ref) =>
+ traverse(ref)
+ case SelectFromTypeTree(qualifier, selector) =>
+ traverse(qualifier)
+ case CompoundTypeTree(templ) =>
+ traverse(templ)
+ case AppliedTypeTree(tpt, args) =>
+ traverse(tpt); traverseTrees(args)
+ case TypeBoundsTree(lo, hi) =>
+ traverse(lo); traverse(hi)
+ case ExistentialTypeTree(tpt, whereClauses) =>
+ traverse(tpt); traverseTrees(whereClauses)
+ case _ => xtraverse(traverser, tree)
+ }
+ }
- private lazy val duplicator = new Transformer {
- override val treeCopy = newStrictTreeCopier
- override def transform(t: Tree) = {
- val t1 = super.transform(t)
- if ((t1 ne t) && t1.pos.isRange) t1 setPos t.pos.focus
- t1
+ override protected def itransform(transformer: Transformer, tree: Tree): Tree = {
+ import transformer._
+ val treeCopy = transformer.treeCopy
+ tree match {
+ case EmptyTree =>
+ tree
+ case PackageDef(pid, stats) =>
+ treeCopy.PackageDef(
+ tree, transform(pid).asInstanceOf[RefTree],
+ atOwner(mclass(tree.symbol)) {
+ transformStats(stats, currentOwner)
+ }
+ )
+ case ClassDef(mods, name, tparams, impl) =>
+ atOwner(tree.symbol) {
+ treeCopy.ClassDef(tree, transformModifiers(mods), name,
+ transformTypeDefs(tparams), transformTemplate(impl))
+ }
+ case ModuleDef(mods, name, impl) =>
+ atOwner(mclass(tree.symbol)) {
+ treeCopy.ModuleDef(tree, transformModifiers(mods),
+ name, transformTemplate(impl))
+ }
+ case ValDef(mods, name, tpt, rhs) =>
+ atOwner(tree.symbol) {
+ treeCopy.ValDef(tree, transformModifiers(mods),
+ name, transform(tpt), transform(rhs))
+ }
+ case DefDef(mods, name, tparams, vparamss, tpt, rhs) =>
+ atOwner(tree.symbol) {
+ treeCopy.DefDef(tree, transformModifiers(mods), name,
+ transformTypeDefs(tparams), transformValDefss(vparamss),
+ transform(tpt), transform(rhs))
+ }
+ case TypeDef(mods, name, tparams, rhs) =>
+ atOwner(tree.symbol) {
+ treeCopy.TypeDef(tree, transformModifiers(mods), name,
+ transformTypeDefs(tparams), transform(rhs))
+ }
+ case LabelDef(name, params, rhs) =>
+ treeCopy.LabelDef(tree, name, transformIdents(params), transform(rhs)) //bq: Martin, once, atOwner(...) works, also change `LamdaLifter.proxy'
+ case Import(expr, selectors) =>
+ treeCopy.Import(tree, transform(expr), selectors)
+ case Template(parents, self, body) =>
+ treeCopy.Template(tree, transformTrees(parents), transformValDef(self), transformStats(body, tree.symbol))
+ case Block(stats, expr) =>
+ treeCopy.Block(tree, transformStats(stats, currentOwner), transform(expr))
+ case CaseDef(pat, guard, body) =>
+ treeCopy.CaseDef(tree, transform(pat), transform(guard), transform(body))
+ case Alternative(trees) =>
+ treeCopy.Alternative(tree, transformTrees(trees))
+ case Star(elem) =>
+ treeCopy.Star(tree, transform(elem))
+ case Bind(name, body) =>
+ treeCopy.Bind(tree, name, transform(body))
+ case UnApply(fun, args) =>
+ treeCopy.UnApply(tree, fun, transformTrees(args)) // bq: see test/.../unapplyContexts2.scala
+ case ArrayValue(elemtpt, trees) =>
+ treeCopy.ArrayValue(tree, transform(elemtpt), transformTrees(trees))
+ case Function(vparams, body) =>
+ atOwner(tree.symbol) {
+ treeCopy.Function(tree, transformValDefs(vparams), transform(body))
+ }
+ case Assign(lhs, rhs) =>
+ treeCopy.Assign(tree, transform(lhs), transform(rhs))
+ case AssignOrNamedArg(lhs, rhs) =>
+ treeCopy.AssignOrNamedArg(tree, transform(lhs), transform(rhs))
+ case If(cond, thenp, elsep) =>
+ treeCopy.If(tree, transform(cond), transform(thenp), transform(elsep))
+ case Match(selector, cases) =>
+ treeCopy.Match(tree, transform(selector), transformCaseDefs(cases))
+ case Return(expr) =>
+ treeCopy.Return(tree, transform(expr))
+ case Try(block, catches, finalizer) =>
+ treeCopy.Try(tree, transform(block), transformCaseDefs(catches), transform(finalizer))
+ case Throw(expr) =>
+ treeCopy.Throw(tree, transform(expr))
+ case New(tpt) =>
+ treeCopy.New(tree, transform(tpt))
+ case Typed(expr, tpt) =>
+ treeCopy.Typed(tree, transform(expr), transform(tpt))
+ case TypeApply(fun, args) =>
+ treeCopy.TypeApply(tree, transform(fun), transformTrees(args))
+ case Apply(fun, args) =>
+ treeCopy.Apply(tree, transform(fun), transformTrees(args))
+ case ApplyDynamic(qual, args) =>
+ treeCopy.ApplyDynamic(tree, transform(qual), transformTrees(args))
+ case Super(qual, mix) =>
+ treeCopy.Super(tree, transform(qual), mix)
+ case This(qual) =>
+ treeCopy.This(tree, qual)
+ case Select(qualifier, selector) =>
+ treeCopy.Select(tree, transform(qualifier), selector)
+ case Ident(name) =>
+ treeCopy.Ident(tree, name)
+ case ReferenceToBoxed(idt) =>
+ treeCopy.ReferenceToBoxed(tree, transform(idt) match { case idt1: Ident => idt1 })
+ case Literal(value) =>
+ treeCopy.Literal(tree, value)
+ case TypeTree() =>
+ treeCopy.TypeTree(tree)
+ case Annotated(annot, arg) =>
+ treeCopy.Annotated(tree, transform(annot), transform(arg))
+ case SingletonTypeTree(ref) =>
+ treeCopy.SingletonTypeTree(tree, transform(ref))
+ case SelectFromTypeTree(qualifier, selector) =>
+ treeCopy.SelectFromTypeTree(tree, transform(qualifier), selector)
+ case CompoundTypeTree(templ) =>
+ treeCopy.CompoundTypeTree(tree, transformTemplate(templ))
+ case AppliedTypeTree(tpt, args) =>
+ treeCopy.AppliedTypeTree(tree, transform(tpt), transformTrees(args))
+ case TypeBoundsTree(lo, hi) =>
+ treeCopy.TypeBoundsTree(tree, transform(lo), transform(hi))
+ case ExistentialTypeTree(tpt, whereClauses) =>
+ treeCopy.ExistentialTypeTree(tree, transform(tpt), transformTrees(whereClauses))
+ case _ =>
+ xtransform(transformer, tree)
}
}
+ private def mclass(sym: Symbol) = sym map (_.asModuleSymbol.moduleClass)
+
+ // --- specific traversers and transformers
+
class ForeachPartialTreeTraverser(pf: PartialFunction[Tree, Tree]) extends Traverser {
override def traverse(tree: Tree) {
val t = if (pf isDefinedAt tree) pf(tree) else tree
@@ -432,4 +1392,201 @@ trait Trees extends api.Trees { self: SymbolTable =>
def apply[T <: Tree](tree: T): T = transform(tree).asInstanceOf[T]
override def toString() = "TreeSymSubstituter/" + substituterString("Symbol", "Symbol", from, to)
}
+
+
+ class ForeachTreeTraverser(f: Tree => Unit) extends Traverser {
+ override def traverse(t: Tree) {
+ f(t)
+ super.traverse(t)
+ }
+ }
+
+ class FilterTreeTraverser(p: Tree => Boolean) extends Traverser {
+ val hits = new ListBuffer[Tree]
+ override def traverse(t: Tree) {
+ if (p(t)) hits += t
+ super.traverse(t)
+ }
+ }
+
+ class CollectTreeTraverser[T](pf: PartialFunction[Tree, T]) extends Traverser {
+ val results = new ListBuffer[T]
+ override def traverse(t: Tree) {
+ if (pf.isDefinedAt(t)) results += pf(t)
+ super.traverse(t)
+ }
+ }
+
+ class FindTreeTraverser(p: Tree => Boolean) extends Traverser {
+ var result: Option[Tree] = None
+ override def traverse(t: Tree) {
+ if (result.isEmpty) {
+ if (p(t)) result = Some(t)
+ super.traverse(t)
+ }
+ }
+ }
+
+ private lazy val duplicator = new Transformer {
+ override val treeCopy = newStrictTreeCopier
+ override def transform(t: Tree) = {
+ val t1 = super.transform(t)
+ if ((t1 ne t) && t1.pos.isRange) t1 setPos t.pos.focus
+ t1
+ }
+ }
+
+ // ------ copiers -------------------------------------------
+
+ def copyDefDef(tree: Tree)(
+ mods: Modifiers = null,
+ name: Name = null,
+ tparams: List[TypeDef] = null,
+ vparamss: List[List[ValDef]] = null,
+ tpt: Tree = null,
+ rhs: Tree = null
+ ): DefDef = tree match {
+ case DefDef(mods0, name0, tparams0, vparamss0, tpt0, rhs0) =>
+ treeCopy.DefDef(tree,
+ if (mods eq null) mods0 else mods,
+ if (name eq null) name0 else name,
+ if (tparams eq null) tparams0 else tparams,
+ if (vparamss eq null) vparamss0 else vparamss,
+ if (tpt eq null) tpt0 else tpt,
+ if (rhs eq null) rhs0 else rhs
+ )
+ case t =>
+ sys.error("Not a DefDef: " + t + "/" + t.getClass)
+ }
+ def copyValDef(tree: Tree)(
+ mods: Modifiers = null,
+ name: Name = null,
+ tpt: Tree = null,
+ rhs: Tree = null
+ ): ValDef = tree match {
+ case ValDef(mods0, name0, tpt0, rhs0) =>
+ treeCopy.ValDef(tree,
+ if (mods eq null) mods0 else mods,
+ if (name eq null) name0 else name,
+ if (tpt eq null) tpt0 else tpt,
+ if (rhs eq null) rhs0 else rhs
+ )
+ case t =>
+ sys.error("Not a ValDef: " + t + "/" + t.getClass)
+ }
+ def copyClassDef(tree: Tree)(
+ mods: Modifiers = null,
+ name: Name = null,
+ tparams: List[TypeDef] = null,
+ impl: Template = null
+ ): ClassDef = tree match {
+ case ClassDef(mods0, name0, tparams0, impl0) =>
+ treeCopy.ClassDef(tree,
+ if (mods eq null) mods0 else mods,
+ if (name eq null) name0 else name,
+ if (tparams eq null) tparams0 else tparams,
+ if (impl eq null) impl0 else impl
+ )
+ case t =>
+ sys.error("Not a ClassDef: " + t + "/" + t.getClass)
+ }
+
+ def deriveDefDef(ddef: Tree)(applyToRhs: Tree => Tree): DefDef = ddef match {
+ case DefDef(mods0, name0, tparams0, vparamss0, tpt0, rhs0) =>
+ treeCopy.DefDef(ddef, mods0, name0, tparams0, vparamss0, tpt0, applyToRhs(rhs0))
+ case t =>
+ sys.error("Not a DefDef: " + t + "/" + t.getClass)
+ }
+ def deriveValDef(vdef: Tree)(applyToRhs: Tree => Tree): ValDef = vdef match {
+ case ValDef(mods0, name0, tpt0, rhs0) =>
+ treeCopy.ValDef(vdef, mods0, name0, tpt0, applyToRhs(rhs0))
+ case t =>
+ sys.error("Not a ValDef: " + t + "/" + t.getClass)
+ }
+ def deriveTemplate(templ: Tree)(applyToBody: List[Tree] => List[Tree]): Template = templ match {
+ case Template(parents0, self0, body0) =>
+ treeCopy.Template(templ, parents0, self0, applyToBody(body0))
+ case t =>
+ sys.error("Not a Template: " + t + "/" + t.getClass)
+ }
+ def deriveClassDef(cdef: Tree)(applyToImpl: Template => Template): ClassDef = cdef match {
+ case ClassDef(mods0, name0, tparams0, impl0) =>
+ treeCopy.ClassDef(cdef, mods0, name0, tparams0, applyToImpl(impl0))
+ case t =>
+ sys.error("Not a ClassDef: " + t + "/" + t.getClass)
+ }
+ def deriveModuleDef(mdef: Tree)(applyToImpl: Template => Template): ModuleDef = mdef match {
+ case ModuleDef(mods0, name0, impl0) =>
+ treeCopy.ModuleDef(mdef, mods0, name0, applyToImpl(impl0))
+ case t =>
+ sys.error("Not a ModuleDef: " + t + "/" + t.getClass)
+ }
+ def deriveCaseDef(cdef: Tree)(applyToBody: Tree => Tree): CaseDef = cdef match {
+ case CaseDef(pat0, guard0, body0) =>
+ treeCopy.CaseDef(cdef, pat0, guard0, applyToBody(body0))
+ case t =>
+ sys.error("Not a CaseDef: " + t + "/" + t.getClass)
+ }
+ def deriveLabelDef(ldef: Tree)(applyToRhs: Tree => Tree): LabelDef = ldef match {
+ case LabelDef(name0, params0, rhs0) =>
+ treeCopy.LabelDef(ldef, name0, params0, applyToRhs(rhs0))
+ case t =>
+ sys.error("Not a LabelDef: " + t + "/" + t.getClass)
+ }
+
+ implicit val TreeTag = ClassTag[Tree](classOf[Tree])
+ implicit val TermTreeTag = ClassTag[TermTree](classOf[TermTree])
+ implicit val TypTreeTag = ClassTag[TypTree](classOf[TypTree])
+ implicit val SymTreeTag = ClassTag[SymTree](classOf[SymTree])
+ implicit val NameTreeTag = ClassTag[NameTree](classOf[NameTree])
+ implicit val RefTreeTag = ClassTag[RefTree](classOf[RefTree])
+ implicit val DefTreeTag = ClassTag[DefTree](classOf[DefTree])
+ implicit val MemberDefTag = ClassTag[MemberDef](classOf[MemberDef])
+ implicit val PackageDefTag = ClassTag[PackageDef](classOf[PackageDef])
+ implicit val ImplDefTag = ClassTag[ImplDef](classOf[ImplDef])
+ implicit val ClassDefTag = ClassTag[ClassDef](classOf[ClassDef])
+ implicit val ModuleDefTag = ClassTag[ModuleDef](classOf[ModuleDef])
+ implicit val ValOrDefDefTag = ClassTag[ValOrDefDef](classOf[ValOrDefDef])
+ implicit val ValDefTag = ClassTag[ValDef](classOf[ValDef])
+ implicit val DefDefTag = ClassTag[DefDef](classOf[DefDef])
+ implicit val TypeDefTag = ClassTag[TypeDef](classOf[TypeDef])
+ implicit val LabelDefTag = ClassTag[LabelDef](classOf[LabelDef])
+ implicit val ImportSelectorTag = ClassTag[ImportSelector](classOf[ImportSelector])
+ implicit val ImportTag = ClassTag[Import](classOf[Import])
+ implicit val TemplateTag = ClassTag[Template](classOf[Template])
+ implicit val BlockTag = ClassTag[Block](classOf[Block])
+ implicit val CaseDefTag = ClassTag[CaseDef](classOf[CaseDef])
+ implicit val AlternativeTag = ClassTag[Alternative](classOf[Alternative])
+ implicit val StarTag = ClassTag[Star](classOf[Star])
+ implicit val BindTag = ClassTag[Bind](classOf[Bind])
+ implicit val UnApplyTag = ClassTag[UnApply](classOf[UnApply])
+ implicit val ArrayValueTag = ClassTag[ArrayValue](classOf[ArrayValue])
+ implicit val FunctionTag = ClassTag[Function](classOf[Function])
+ implicit val AssignTag = ClassTag[Assign](classOf[Assign])
+ implicit val AssignOrNamedArgTag = ClassTag[AssignOrNamedArg](classOf[AssignOrNamedArg])
+ implicit val IfTag = ClassTag[If](classOf[If])
+ implicit val MatchTag = ClassTag[Match](classOf[Match])
+ implicit val ReturnTag = ClassTag[Return](classOf[Return])
+ implicit val TryTag = ClassTag[Try](classOf[Try])
+ implicit val ThrowTag = ClassTag[Throw](classOf[Throw])
+ implicit val NewTag = ClassTag[New](classOf[New])
+ implicit val TypedTag = ClassTag[Typed](classOf[Typed])
+ implicit val GenericApplyTag = ClassTag[GenericApply](classOf[GenericApply])
+ implicit val TypeApplyTag = ClassTag[TypeApply](classOf[TypeApply])
+ implicit val ApplyTag = ClassTag[Apply](classOf[Apply])
+ implicit val ApplyDynamicTag = ClassTag[ApplyDynamic](classOf[ApplyDynamic])
+ implicit val SuperTag = ClassTag[Super](classOf[Super])
+ implicit val ThisTag = ClassTag[This](classOf[This])
+ implicit val SelectTag = ClassTag[Select](classOf[Select])
+ implicit val IdentTag = ClassTag[Ident](classOf[Ident])
+ implicit val ReferenceToBoxedTag = ClassTag[ReferenceToBoxed](classOf[ReferenceToBoxed])
+ implicit val LiteralTag = ClassTag[Literal](classOf[Literal])
+ implicit val AnnotatedTag = ClassTag[Annotated](classOf[Annotated])
+ implicit val SingletonTypeTreeTag = ClassTag[SingletonTypeTree](classOf[SingletonTypeTree])
+ implicit val SelectFromTypeTreeTag = ClassTag[SelectFromTypeTree](classOf[SelectFromTypeTree])
+ implicit val CompoundTypeTreeTag = ClassTag[CompoundTypeTree](classOf[CompoundTypeTree])
+ implicit val AppliedTypeTreeTag = ClassTag[AppliedTypeTree](classOf[AppliedTypeTree])
+ implicit val TypeBoundsTreeTag = ClassTag[TypeBoundsTree](classOf[TypeBoundsTree])
+ implicit val ExistentialTypeTreeTag = ClassTag[ExistentialTypeTree](classOf[ExistentialTypeTree])
+ implicit val TypeTreeTag = ClassTag[TypeTree](classOf[TypeTree])
}
diff --git a/src/compiler/scala/reflect/internal/Types.scala b/src/compiler/scala/reflect/internal/Types.scala
index a839e44182..ce7a697439 100644
--- a/src/compiler/scala/reflect/internal/Types.scala
+++ b/src/compiler/scala/reflect/internal/Types.scala
@@ -260,7 +260,7 @@ trait Types extends api.Types { self: SymbolTable =>
}
}
- abstract class AbsTypeImpl extends AbsType { this: Type =>
+ abstract class TypeApiImpl extends TypeApi { this: Type =>
def declaration(name: Name): Symbol = decl(name)
def nonPrivateDeclaration(name: Name): Symbol = nonPrivateDecl(name)
def declarations = decls
@@ -268,7 +268,7 @@ trait Types extends api.Types { self: SymbolTable =>
def erasure = this match {
case ConstantType(value) => widen.erasure // [Eugene to Martin] constant types are unaffected by erasure. weird.
case _ =>
- var result = transformedType(this)
+ var result: Type = transformedType(this)
result = result.normalize match { // necessary to deal with erasures of HK types, typeConstructor won't work
case PolyType(undets, underlying) => existentialAbstraction(undets, underlying) // we don't want undets in the result
case _ => result
@@ -282,6 +282,7 @@ trait Types extends api.Types { self: SymbolTable =>
})
result
}
+ def substituteSymbols(from: List[Symbol], to: List[Symbol]): Type = substSym(from, to)
def substituteTypes(from: List[Symbol], to: List[Type]): Type = subst(from, to)
// [Eugene] to be discussed and refactored
@@ -315,7 +316,7 @@ trait Types extends api.Types { self: SymbolTable =>
}
/** The base class for all types */
- abstract class Type extends AbsTypeImpl with Annotatable[Type] {
+ abstract class Type extends TypeApiImpl with Annotatable[Type] {
/** Types for which asSeenFrom always is the identity, no matter what
* prefix or owner.
*/
@@ -1243,7 +1244,7 @@ trait Types extends api.Types { self: SymbolTable =>
* type is created: a MethodType with parameters typed as
* BoundedWildcardTypes.
*/
- case class BoundedWildcardType(override val bounds: TypeBounds) extends Type {
+ case class BoundedWildcardType(override val bounds: TypeBounds) extends Type with BoundedWildcardTypeApi {
override def isWildcard = true
override def safeToString: String = "?" + bounds
override def kind = "BoundedWildcardType"
@@ -1271,7 +1272,7 @@ trait Types extends api.Types { self: SymbolTable =>
/** A class for this-types of the form <sym>.this.type
*/
- abstract case class ThisType(sym: Symbol) extends SingletonType {
+ abstract case class ThisType(sym: Symbol) extends SingletonType with ThisTypeApi {
assert(sym.isClass)
//assert(sym.isClass && !sym.isModuleClass || sym.isRoot, sym)
override def isTrivial: Boolean = sym.isPackageClass
@@ -1306,7 +1307,7 @@ trait Types extends api.Types { self: SymbolTable =>
/** A class for singleton types of the form `<prefix>.<sym.name>.type`.
* Cannot be created directly; one should always use `singleType` for creation.
*/
- abstract case class SingleType(pre: Type, sym: Symbol) extends SingletonType {
+ abstract case class SingleType(pre: Type, sym: Symbol) extends SingletonType with SingleTypeApi {
override val isTrivial: Boolean = pre.isTrivial
override def isGround = sym.isPackageClass || pre.isGround
@@ -1366,13 +1367,13 @@ trait Types extends api.Types { self: SymbolTable =>
tpe.underlyingPeriod = currentPeriod
if (!isValid(period)) {
// [Eugene to Paul] needs review
- tpe.underlyingCache = if (tpe.sym == NoSymbol) ThisType(RootClass) else tpe.pre.memberType(tpe.sym).resultType;
+ tpe.underlyingCache = if (tpe.sym == NoSymbol) ThisType(rootMirror.RootClass) else tpe.pre.memberType(tpe.sym).resultType;
assert(tpe.underlyingCache ne tpe, tpe)
}
}
}
- abstract case class SuperType(thistpe: Type, supertpe: Type) extends SingletonType {
+ abstract case class SuperType(thistpe: Type, supertpe: Type) extends SingletonType with SuperTypeApi {
override val isTrivial: Boolean = thistpe.isTrivial && supertpe.isTrivial
override def isNotNull = true;
override def typeSymbol = thistpe.typeSymbol
@@ -1394,7 +1395,7 @@ trait Types extends api.Types { self: SymbolTable =>
/** A class for the bounds of abstract types and type parameters
*/
- abstract case class TypeBounds(lo: Type, hi: Type) extends SubType {
+ abstract case class TypeBounds(lo: Type, hi: Type) extends SubType with TypeBoundsApi {
def supertype = hi
override val isTrivial: Boolean = lo.isTrivial && hi.isTrivial
override def bounds: TypeBounds = this
@@ -1600,7 +1601,7 @@ trait Types extends api.Types { self: SymbolTable =>
* one should always use `refinedType` for creation.
*/
case class RefinedType(override val parents: List[Type],
- override val decls: Scope) extends CompoundType {
+ override val decls: Scope) extends CompoundType with RefinedTypeApi {
override def isHigherKinded = (
parents.nonEmpty &&
@@ -1695,7 +1696,7 @@ trait Types extends api.Types { self: SymbolTable =>
case class ClassInfoType(
override val parents: List[Type],
override val decls: Scope,
- override val typeSymbol: Symbol) extends CompoundType
+ override val typeSymbol: Symbol) extends CompoundType with ClassInfoTypeApi
{
validateClassInfo(this)
@@ -1874,7 +1875,7 @@ trait Types extends api.Types { self: SymbolTable =>
*
* @param value ...
*/
- abstract case class ConstantType(value: Constant) extends SingletonType {
+ abstract case class ConstantType(value: Constant) extends SingletonType with ConstantTypeApi {
override def underlying: Type = value.tpe
assert(underlying.typeSymbol != UnitClass)
override def isTrivial: Boolean = true
@@ -2183,7 +2184,7 @@ trait Types extends api.Types { self: SymbolTable =>
*
* @M: a higher-kinded type is represented as a TypeRef with sym.typeParams.nonEmpty, but args.isEmpty
*/
- abstract case class TypeRef(pre: Type, sym: Symbol, args: List[Type]) extends Type {
+ abstract case class TypeRef(pre: Type, sym: Symbol, args: List[Type]) extends Type with TypeRefApi {
private[reflect] var parentsCache: List[Type] = _
private[reflect] var parentsPeriod = NoPeriod
private[reflect] var baseTypeSeqCache: BaseTypeSeq = _
@@ -2406,7 +2407,7 @@ trait Types extends api.Types { self: SymbolTable =>
* def m: Int NullaryMethodType(Int)
*/
case class MethodType(override val params: List[Symbol],
- override val resultType: Type) extends Type {
+ override val resultType: Type) extends Type with MethodTypeApi {
override def isTrivial: Boolean = isTrivial0 && (resultType eq resultType.withoutAnnotations)
private lazy val isTrivial0 =
resultType.isTrivial && params.forall{p => p.tpe.isTrivial && (
@@ -2462,7 +2463,7 @@ trait Types extends api.Types { self: SymbolTable =>
override def isJava = true
}
- case class NullaryMethodType(override val resultType: Type) extends Type {
+ case class NullaryMethodType(override val resultType: Type) extends Type with NullaryMethodTypeApi {
override def isTrivial = resultType.isTrivial && (resultType eq resultType.withoutAnnotations)
override def prefix: Type = resultType.prefix
override def narrow: Type = resultType.narrow
@@ -2496,7 +2497,7 @@ trait Types extends api.Types { self: SymbolTable =>
* A polytype is of kind * iff its resultType is a (nullary) method type.
*/
case class PolyType(override val typeParams: List[Symbol], override val resultType: Type)
- extends Type {
+ extends Type with PolyTypeApi {
//assert(!(typeParams contains NoSymbol), this)
assert(typeParams nonEmpty, this) // used to be a marker for nullary method type, illegal now (see @NullaryMethodType)
@@ -2556,7 +2557,7 @@ trait Types extends api.Types { self: SymbolTable =>
}
case class ExistentialType(quantified: List[Symbol],
- override val underlying: Type) extends RewrappingTypeProxy
+ override val underlying: Type) extends RewrappingTypeProxy with ExistentialTypeApi
{
override protected def rewrap(newtp: Type) = existentialAbstraction(quantified, newtp)
@@ -3177,7 +3178,7 @@ trait Types extends api.Types { self: SymbolTable =>
case class AnnotatedType(override val annotations: List[AnnotationInfo],
override val underlying: Type,
override val selfsym: Symbol)
- extends RewrappingTypeProxy {
+ extends RewrappingTypeProxy with AnnotatedTypeApi {
assert(!annotations.isEmpty, "" + underlying)
@@ -3250,7 +3251,7 @@ trait Types extends api.Types { self: SymbolTable =>
if (annots.isEmpty) underlying
else AnnotatedType(annots, underlying, selfsym)
- object AnnotatedType extends AnnotatedTypeExtractor { }
+ object AnnotatedType extends AnnotatedTypeExtractor
/** A class representing types with a name. When an application uses
* named arguments, the named argument types for calling isApplicable
@@ -3331,7 +3332,7 @@ trait Types extends api.Types { self: SymbolTable =>
if (phase.erasedTypes)
sym.tpe.resultType
else if (sym.isRootPackage)
- ThisType(RootClass)
+ ThisType(sym.moduleClass)
else {
var sym1 = rebind(pre, sym)
val pre1 = removeSuper(pre, sym1)
@@ -5053,6 +5054,13 @@ trait Types extends api.Types { self: SymbolTable =>
pre1 =:= pre2
}
+ private def isSubPre(pre1: Type, pre2: Type, sym: Symbol) =
+ if ((pre1 ne pre2) && (pre1 ne NoPrefix) && (pre2 ne NoPrefix) && pre1 <:< pre2) {
+ if (settings.debug.value) println(s"new isSubPre $sym: $pre1 <:< $pre2")
+ true
+ } else
+ false
+
private def equalSymsAndPrefixes(sym1: Symbol, pre1: Type, sym2: Symbol, pre2: Type): Boolean =
if (sym1 == sym2) sym1.hasPackageFlag || phase.erasedTypes || pre1 =:= pre2
else (sym1.name == sym2.name) && isUnifiable(pre1, pre2)
@@ -5215,9 +5223,9 @@ trait Types extends api.Types { self: SymbolTable =>
true
else if ((tp1 eq NoType) || (tp2 eq NoType))
false
- else if (tp1 eq NoPrefix)
+ else if (tp1 eq NoPrefix) // !! I do not see how this would be warranted by the spec
tp2.typeSymbol.isPackageClass
- else if (tp2 eq NoPrefix)
+ else if (tp2 eq NoPrefix) // !! I do not see how this would be warranted by the spec
tp1.typeSymbol.isPackageClass
else {
isSameType2(tp1, tp2) || {
@@ -5521,7 +5529,7 @@ trait Types extends api.Types { self: SymbolTable =>
private def isSubType2(tp1: Type, tp2: Type, depth: Int): Boolean = {
if ((tp1 eq tp2) || isErrorOrWildcard(tp1) || isErrorOrWildcard(tp2)) return true
if ((tp1 eq NoType) || (tp2 eq NoType)) return false
- if (tp1 eq NoPrefix) return (tp2 eq NoPrefix) || tp2.typeSymbol.isPackageClass
+ if (tp1 eq NoPrefix) return (tp2 eq NoPrefix) || tp2.typeSymbol.isPackageClass // !! I do not see how the "isPackageClass" would be warranted by the spec
if (tp2 eq NoPrefix) return tp1.typeSymbol.isPackageClass
if (isSingleType(tp1) && isSingleType(tp2) || isConstantType(tp1) && isConstantType(tp2)) return tp1 =:= tp2
if (tp1.isHigherKinded || tp2.isHigherKinded) return isHKSubType0(tp1, tp2, depth)
@@ -5542,7 +5550,9 @@ trait Types extends api.Types { self: SymbolTable =>
val pre2 = tr2.pre
(((if (sym1 == sym2) phase.erasedTypes || pre1 <:< pre2
else (sym1.name == sym2.name && !sym1.isModuleClass && !sym2.isModuleClass &&
- (isUnifiable(pre1, pre2) || isSameSpecializedSkolem(sym1, sym2, pre1, pre2)))) &&
+ (isUnifiable(pre1, pre2) ||
+ isSameSpecializedSkolem(sym1, sym2, pre1, pre2) ||
+ sym2.isAbstractType && isSubPre(pre1, pre2, sym2)))) &&
isSubArgs(tr1.args, tr2.args, sym1.typeParams))
||
sym2.isClass && {
@@ -6789,4 +6799,21 @@ trait Types extends api.Types { self: SymbolTable =>
tostringRecursions -= 1
}
+ implicit val AnnotatedTypeTag = ClassTag[AnnotatedType](classOf[AnnotatedType])
+ implicit val BoundedWildcardTypeTag = ClassTag[BoundedWildcardType](classOf[BoundedWildcardType])
+ implicit val ClassInfoTypeTag = ClassTag[ClassInfoType](classOf[ClassInfoType])
+ implicit val CompoundTypeTag = ClassTag[CompoundType](classOf[CompoundType])
+ implicit val ConstantTypeTag = ClassTag[ConstantType](classOf[ConstantType])
+ implicit val ExistentialTypeTag = ClassTag[ExistentialType](classOf[ExistentialType])
+ implicit val MethodTypeTag = ClassTag[MethodType](classOf[MethodType])
+ implicit val NullaryMethodTypeTag = ClassTag[NullaryMethodType](classOf[NullaryMethodType])
+ implicit val PolyTypeTag = ClassTag[PolyType](classOf[PolyType])
+ implicit val RefinedTypeTag = ClassTag[RefinedType](classOf[RefinedType])
+ implicit val SingletonTypeTag = ClassTag[SingletonType](classOf[SingletonType])
+ implicit val SingleTypeTag = ClassTag[SingleType](classOf[SingleType])
+ implicit val SuperTypeTag = ClassTag[SuperType](classOf[SuperType])
+ implicit val ThisTypeTag = ClassTag[ThisType](classOf[ThisType])
+ implicit val TypeBoundsTag = ClassTag[TypeBounds](classOf[TypeBounds])
+ implicit val TypeRefTag = ClassTag[TypeRef](classOf[TypeRef])
+ implicit val TypeTagg = ClassTag[Type](classOf[Type])
}
diff --git a/src/compiler/scala/reflect/internal/package.scala b/src/compiler/scala/reflect/internal/package.scala
new file mode 100644
index 0000000000..99b837152d
--- /dev/null
+++ b/src/compiler/scala/reflect/internal/package.scala
@@ -0,0 +1,6 @@
+package scala.reflect
+
+package object internal {
+
+ type MirrorOf[U <: base.Universe with Singleton] = base.MirrorOf[U]
+}
diff --git a/src/compiler/scala/reflect/internal/pickling/UnPickler.scala b/src/compiler/scala/reflect/internal/pickling/UnPickler.scala
index fd3fac1b37..bfccdd3988 100644
--- a/src/compiler/scala/reflect/internal/pickling/UnPickler.scala
+++ b/src/compiler/scala/reflect/internal/pickling/UnPickler.scala
@@ -53,6 +53,8 @@ abstract class UnPickler /*extends reflect.generic.UnPickler*/ {
checkVersion()
+ private val loadingMirror = mirrorThatLoaded(classRoot)
+
/** A map from entry numbers to array offsets */
private val index = createIndex
@@ -195,13 +197,13 @@ abstract class UnPickler /*extends reflect.generic.UnPickler*/ {
def readExtSymbol(): Symbol = {
val name = readNameRef()
- val owner = if (atEnd) definitions.RootClass else readSymbolRef()
+ val owner = if (atEnd) loadingMirror.RootClass else readSymbolRef()
def adjust(sym: Symbol) = if (tag == EXTref) sym else sym.moduleClass
def fromName(name: Name) = name.toTermName match {
- case nme.ROOT => definitions.RootClass
- case nme.ROOTPKG => definitions.RootPackage
+ case nme.ROOT => loadingMirror.RootClass
+ case nme.ROOTPKG => loadingMirror.RootPackage
case _ => adjust(owner.info.decl(name))
}
def nestedObjectSymbol: Symbol = {
@@ -447,7 +449,7 @@ abstract class UnPickler /*extends reflect.generic.UnPickler*/ {
private def readArrayAnnot() = {
readByte() // skip the `annotargarray` tag
val end = readNat() + readIndex
- until(end, () => readClassfileAnnotArg(readNat())).toArray(classfileAnnotArgTag)
+ until(end, () => readClassfileAnnotArg(readNat())).toArray(ClassfileAnnotArgTag)
}
protected def readClassfileAnnotArg(i: Int): ClassfileAnnotArg = bytes(index(i)) match {
case ANNOTINFO => NestedAnnotArg(at(i, readAnnotation))
@@ -816,9 +818,8 @@ abstract class UnPickler /*extends reflect.generic.UnPickler*/ {
throw new RuntimeException("malformed Scala signature of " + classRoot.name + " at " + readIndex + "; " + msg)
protected def errorMissingRequirement(name: Name, owner: Symbol): Symbol =
- missingHook(owner, name) orElse MissingRequirementError.notFound(
- "bad reference while unpickling %s: %s not found in %s".format(
- filename, name.longString, owner.tpe.widen)
+ missingHook(owner, name) orElse MissingRequirementError.signal(
+ s"bad reference while unpickling $filename: ${name.longString} not found in ${owner.tpe.widen}"
)
def inferMethodAlternative(fun: Tree, argtpes: List[Type], restpe: Type) {} // can't do it; need a compiler for that.
diff --git a/src/compiler/scala/reflect/internal/util/TraceSymbolActivity.scala b/src/compiler/scala/reflect/internal/util/TraceSymbolActivity.scala
index 1424226042..d8c53c0162 100644
--- a/src/compiler/scala/reflect/internal/util/TraceSymbolActivity.scala
+++ b/src/compiler/scala/reflect/internal/util/TraceSymbolActivity.scala
@@ -7,7 +7,7 @@ trait TraceSymbolActivity {
val global: SymbolTable
import global._
- if (traceSymbolActivity && !global.inReflexiveMirror)
+ if (traceSymbolActivity && global.isCompilerUniverse)
scala.sys addShutdownHook showAllSymbols()
private type Set[T] = scala.collection.immutable.Set[T]
diff --git a/src/compiler/scala/reflect/makro/runtime/AbortMacroException.scala b/src/compiler/scala/reflect/makro/runtime/AbortMacroException.scala
index d78eae9237..d0d40d6f42 100644
--- a/src/compiler/scala/reflect/makro/runtime/AbortMacroException.scala
+++ b/src/compiler/scala/reflect/makro/runtime/AbortMacroException.scala
@@ -1,6 +1,6 @@
package scala.reflect.makro
package runtime
-import scala.reflect.api.Position
+import scala.tools.nsc.util.Position
class AbortMacroException(val pos: Position, val msg: String) extends Throwable(msg)
diff --git a/src/compiler/scala/reflect/makro/runtime/Aliases.scala b/src/compiler/scala/reflect/makro/runtime/Aliases.scala
index a4f208ca34..30b015b201 100644
--- a/src/compiler/scala/reflect/makro/runtime/Aliases.scala
+++ b/src/compiler/scala/reflect/makro/runtime/Aliases.scala
@@ -9,13 +9,15 @@ trait Aliases {
override type Type = mirror.Type
override type Name = mirror.Name
override type Tree = mirror.Tree
- override type Position = mirror.Position
+ // override type Position = mirror.Position
override type Scope = mirror.Scope
override type Modifiers = mirror.Modifiers
override type Expr[+T] = mirror.Expr[T]
override type TypeTag[T] = mirror.TypeTag[T]
+ override type ConcreteTypeTag[T] = mirror.ConcreteTypeTag[T]
/** Creator/extractor objects for Expr and TypeTag values */
override val TypeTag = mirror.TypeTag
+ override val ConcreteTypeTag = mirror.ConcreteTypeTag
override val Expr = mirror.Expr
} \ No newline at end of file
diff --git a/src/compiler/scala/reflect/makro/runtime/Context.scala b/src/compiler/scala/reflect/makro/runtime/Context.scala
index ca02822788..6faf045d75 100644
--- a/src/compiler/scala/reflect/makro/runtime/Context.scala
+++ b/src/compiler/scala/reflect/makro/runtime/Context.scala
@@ -12,8 +12,9 @@ abstract class Context extends scala.reflect.makro.Context
with Reifiers
with FrontEnds
with Settings
- with Symbols
with Typers
+ with Exprs
+ with TypeTags
with Util
with Traces {
diff --git a/src/compiler/scala/reflect/makro/runtime/Exprs.scala b/src/compiler/scala/reflect/makro/runtime/Exprs.scala
new file mode 100644
index 0000000000..d47ff4e450
--- /dev/null
+++ b/src/compiler/scala/reflect/makro/runtime/Exprs.scala
@@ -0,0 +1,8 @@
+package scala.reflect.makro
+package runtime
+
+trait Exprs {
+ self: Context =>
+
+ def Expr[T: TypeTag](tree: Tree): Expr[T] = mirror.Expr[T](mirror.rootMirror, mirror.FixedMirrorTreeCreator(mirror.rootMirror, tree))
+}
diff --git a/src/compiler/scala/reflect/makro/runtime/FrontEnds.scala b/src/compiler/scala/reflect/makro/runtime/FrontEnds.scala
index 7cfa8e80f3..a21c8f90c9 100644
--- a/src/compiler/scala/reflect/makro/runtime/FrontEnds.scala
+++ b/src/compiler/scala/reflect/makro/runtime/FrontEnds.scala
@@ -1,11 +1,13 @@
package scala.reflect.makro
package runtime
-trait FrontEnds {
+trait FrontEnds extends scala.tools.reflect.FrontEnds {
self: Context =>
import mirror._
+ override type Position = mirror.Position
+
def frontEnd: FrontEnd = wrapReporter(mirror.reporter)
def setFrontEnd(frontEnd: FrontEnd): this.type = {
diff --git a/src/compiler/scala/reflect/makro/runtime/Reifiers.scala b/src/compiler/scala/reflect/makro/runtime/Reifiers.scala
index 1c5af4b752..fd683fd229 100644
--- a/src/compiler/scala/reflect/makro/runtime/Reifiers.scala
+++ b/src/compiler/scala/reflect/makro/runtime/Reifiers.scala
@@ -12,23 +12,17 @@ trait Reifiers {
import mirror._
import definitions._
- lazy val reflectMirrorPrefix: Tree = ReflectMirrorPrefix
+ lazy val reflectMirrorPrefix: Tree = ???
- def reifyTree(prefix: Tree, tree: Tree): Tree = {
- val result = scala.reflect.reify.`package`.reifyTree(mirror)(callsiteTyper, prefix, tree)
- logFreeVars(enclosingPosition, result)
- result
- }
+ def reifyTree(prefix: Tree, tree: Tree): Tree =
+ scala.reflect.reify.`package`.reifyTree(mirror)(callsiteTyper, prefix, tree)
- def reifyType(prefix: Tree, tpe: Type, dontSpliceAtTopLevel: Boolean = false, concrete: Boolean = false): Tree = {
- val result = scala.reflect.reify.`package`.reifyType(mirror)(callsiteTyper, prefix, tpe, dontSpliceAtTopLevel, concrete)
- logFreeVars(enclosingPosition, result)
- result
- }
+ def reifyType(prefix: Tree, tpe: Type, dontSpliceAtTopLevel: Boolean = false, concrete: Boolean = false): Tree =
+ scala.reflect.reify.`package`.reifyType(mirror)(callsiteTyper, prefix, tpe, dontSpliceAtTopLevel, concrete)
def reifyErasure(tpe: Type, concrete: Boolean = true): Tree =
scala.reflect.reify.`package`.reifyErasure(mirror)(callsiteTyper, tpe, concrete)
def unreifyTree(tree: Tree): Tree =
- Select(tree, definitions.ExprEval)
+ Select(tree, definitions.ExprSplice)
}
diff --git a/src/compiler/scala/reflect/makro/runtime/Symbols.scala b/src/compiler/scala/reflect/makro/runtime/Symbols.scala
deleted file mode 100644
index 6341523486..0000000000
--- a/src/compiler/scala/reflect/makro/runtime/Symbols.scala
+++ /dev/null
@@ -1,10 +0,0 @@
-package scala.reflect.makro
-package runtime
-
-trait Symbols {
- self: Context =>
-
- def isLocatable(sym: Symbol) = sym.isLocatable
-
- def isStatic(sym: Symbol) = sym.isStatic
-} \ No newline at end of file
diff --git a/src/compiler/scala/reflect/makro/runtime/TypeTags.scala b/src/compiler/scala/reflect/makro/runtime/TypeTags.scala
new file mode 100644
index 0000000000..a8e67da56a
--- /dev/null
+++ b/src/compiler/scala/reflect/makro/runtime/TypeTags.scala
@@ -0,0 +1,9 @@
+package scala.reflect.makro
+package runtime
+
+trait TypeTags {
+ self: Context =>
+
+ def TypeTag[T](tpe: Type): TypeTag[T] = mirror.TypeTag[T](mirror.rootMirror, mirror.FixedMirrorTypeCreator(mirror.rootMirror, tpe))
+ def ConcreteTypeTag[T](tpe: Type): ConcreteTypeTag[T] = mirror.ConcreteTypeTag[T](mirror.rootMirror, mirror.FixedMirrorTypeCreator(mirror.rootMirror, tpe))
+}
diff --git a/src/compiler/scala/reflect/reify/NodePrinters.scala b/src/compiler/scala/reflect/reify/NodePrinters.scala
index eaca9a4968..f0d0d0f5d4 100644
--- a/src/compiler/scala/reflect/reify/NodePrinters.scala
+++ b/src/compiler/scala/reflect/reify/NodePrinters.scala
@@ -18,94 +18,7 @@ trait NodePrinters { self: scala.tools.nsc.ast.NodePrinters =>
object reifiedNodeToString extends Function2[Tree, Tree, String] {
def apply(prefix: Tree, tree: Tree): String = {
- import scala.reflect.api.Modifier
- var modifierIsUsed = false
- var flagsAreUsed = false
-
- // @PP: I fervently hope this is a test case or something, not anything being
- // depended upon. Of more fragile code I cannot conceive.
- // @Eugene: This stuff is only needed to debug-print out reifications in human-readable format
- // Rolling a full-fledged, robust TreePrinter would be several times more code.
- val (List(mirror), reified) = (for (line <- (tree.toString.split(EOL).toList drop 1 dropRight 1)) yield {
- var s = line.trim
- s = s.replace("$mr.", "")
- s = s.replace(".apply", "")
- s = s.replace("scala.collection.immutable.", "")
- s = "List\\[List\\[.*?\\].*?\\]".r.replaceAllIn(s, "List")
- s = "List\\[.*?\\]".r.replaceAllIn(s, "List")
- s = s.replace("immutable.this.Nil", "List()")
- s = s.replace("modifiersFromInternalFlags", "Modifiers")
- s = s.replace("Modifiers(0L, newTypeName(\"\"), List())", "Modifiers()")
- s = """Modifiers\((\d+)[lL], newTypeName\("(.*?)"\), List\((.*?)\)\)""".r.replaceAllIn(s, m => {
- val buf = new collection.mutable.ListBuffer[String]
-
- val annotations = m.group(3)
- if (buf.nonEmpty || annotations.nonEmpty)
- buf.append("List(" + annotations + ")")
-
- val privateWithin = "" + m.group(2)
- if (buf.nonEmpty || privateWithin != "")
- buf.append("newTypeName(\"" + privateWithin + "\")")
-
- val flags = m.group(1).toLong
- val s_flags = Flags.modifiersOfFlags(flags) map (_.sourceString) mkString ", "
- if (buf.nonEmpty || s_flags != "") {
- modifierIsUsed = true
- buf.append("Set(" + s_flags + ")")
- }
-
- "Modifiers(" + buf.reverse.mkString(", ") + ")"
- })
- s = """setInternalFlags\((\d+)L\)""".r.replaceAllIn(s, m => {
- flagsAreUsed = true
- val flags = m.group(1).toLong
- val mods = Flags.modifiersOfFlags(flags) map (_.sourceString)
- "setInternalFlags(flagsOfModifiers(List(" + mods.mkString(", ") + ")))"
- })
-
- s
- }) splitAt 1
-
- val printout = collection.mutable.ListBuffer(mirror);
- printout += "import " + nme.MIRROR_SHORT + "._"
- if (modifierIsUsed) printout += "import scala.reflect.api.Modifier._"
- if (flagsAreUsed) printout += "import scala.reflect.internal.Flags._"
- val body = reified dropWhile (_.startsWith("val"))
- if (body.length > 0 && body(0).startsWith("Expr[")) {
- if (reified(0) startsWith "val") {
- printout += "val code = {"
- printout ++= (reified map (" " + _))
- printout += "}"
- printout += "mkToolBox().runExpr(code)"
- } else {
- printout += "val code = " + reified(0)
- printout ++= reified drop 1
- printout += "mkToolBox().runExpr(code)"
- }
- try {
- val prefix = Select(Select(Ident(definitions.ScalaPackage), newTermName("reflect")), newTermName("mirror"))
- val tree1 = new global.Transformer {
- override def transform(tree: Tree) = super.transform(tree match {
- case Block(ValDef(_, mr, _, _) :: Nil, expr) if mr == nme.MIRROR_SHORT => transform(expr)
- case Block(ValDef(_, mr, _, _) :: symbolTable, expr) if mr == nme.MIRROR_SHORT => transform(Block(symbolTable, expr))
- case Select(Ident(mr), name) if mr == nme.MIRROR_SHORT => Select(prefix, name)
- case tree => tree
- })
- }.transform(tree)
- val stringified = mkToolBox().runExpr(tree1).toString
- if (settings.Yreifydebug.value) printout += "*****************************"
- printout += stringified
- } catch {
- case ex: Throwable =>
-// val realex = ReflectionUtils.unwrapThrowable(ex)
-// val message = new java.io.StringWriter()
-// realex.printStackTrace(new java.io.PrintWriter(message))
-// println(message)
- }
- } else {
- printout ++= reified
- }
- printout mkString EOL
+ "temporarily disabled until reification is repaired"
}
}
} \ No newline at end of file
diff --git a/src/compiler/scala/reflect/reify/Taggers.scala b/src/compiler/scala/reflect/reify/Taggers.scala
index 5665c0948e..d0ef6fcdbf 100644
--- a/src/compiler/scala/reflect/reify/Taggers.scala
+++ b/src/compiler/scala/reflect/reify/Taggers.scala
@@ -21,8 +21,6 @@ abstract class Taggers {
UnitClass.asType -> newTermName("Unit"),
AnyClass.asType -> newTermName("Any"),
ObjectClass.asType -> newTermName("Object"),
- AnyValClass.asType -> newTermName("AnyVal"),
- AnyRefClass.asType -> newTermName("AnyRef"),
NothingClass.asType -> newTermName("Nothing"),
NullClass.asType -> newTermName("Null"),
StringClass.asType -> newTermName("String"))
@@ -32,9 +30,6 @@ abstract class Taggers {
def materializeArrayTag(prefix: Tree, tpe: Type): Tree =
materializeClassTag(prefix, tpe)
- def materializeErasureTag(prefix: Tree, tpe: Type, concrete: Boolean): Tree =
- if (concrete) materializeClassTag(prefix, tpe) else materializeTypeTag(prefix, tpe, concrete = false)
-
def materializeClassTag(prefix: Tree, tpe: Type): Tree =
materializeTag(prefix, tpe, ClassTagModule, {
val erasure = c.reifyErasure(tpe, concrete = true)
@@ -54,22 +49,12 @@ abstract class Taggers {
val ref = if (tagModule.owner.isPackageClass) Ident(tagModule) else Select(prefix, tagModule.name)
Select(ref, coreTags(coreTpe))
case _ =>
- val manifestInScope = nonSyntheticManifestInScope(tpe)
- if (manifestInScope.isEmpty) translatingReificationErrors(materializer)
- else gen.mkMethodCall(staticModule("scala.reflect.package"), newTermName("manifestToConcreteTypeTag"), List(tpe), List(manifestInScope))
+ translatingReificationErrors(materializer)
}
try c.typeCheck(result)
catch { case terr @ c.TypeError(pos, msg) => failTag(result, terr) }
}
- private def nonSyntheticManifestInScope(tpe: Type) = {
- val ManifestClass = staticClass("scala.reflect.Manifest")
- val ManifestModule = staticModule("scala.reflect.Manifest")
- val manifest = c.inferImplicitValue(appliedType(ManifestClass.asTypeConstructor, List(tpe)))
- val notOk = manifest.isEmpty || (manifest exists (sub => sub.symbol != null && (sub.symbol == ManifestModule || sub.symbol.owner == ManifestModule)))
- if (notOk) EmptyTree else manifest
- }
-
def materializeExpr(prefix: Tree, expr: Tree): Tree = {
val result = translatingReificationErrors(c.reifyTree(prefix, expr))
try c.typeCheck(result)
diff --git a/src/compiler/scala/reflect/reify/codegen/Symbols.scala b/src/compiler/scala/reflect/reify/codegen/Symbols.scala
index 21a08b7efb..5ab8a11efe 100644
--- a/src/compiler/scala/reflect/reify/codegen/Symbols.scala
+++ b/src/compiler/scala/reflect/reify/codegen/Symbols.scala
@@ -15,13 +15,13 @@ trait Symbols {
if (sym == NoSymbol)
mirrorSelect(nme.NoSymbol)
- else if (sym == RootPackage)
+ else if (sym == rootMirror.RootPackage)
Select(mirrorSelect(nme.definitions), nme.RootPackage)
- else if (sym == RootClass)
+ else if (sym == rootMirror.RootClass)
Select(mirrorSelect(nme.definitions), nme.RootClass)
- else if (sym == EmptyPackage)
+ else if (sym == rootMirror.EmptyPackage)
Select(mirrorSelect(nme.definitions), nme.EmptyPackage)
- else if (sym == EmptyPackageClass)
+ else if (sym == rootMirror.EmptyPackageClass)
Select(mirrorSelect(nme.definitions), nme.EmptyPackageClass)
else if (sym.isModuleClass)
Select(reify(sym.sourceModule), nme.moduleClass)
@@ -105,7 +105,7 @@ trait Symbols {
filledIn = false
newSymbolTable foreach {
case entry =>
- val att = entry.attachmentOpt[ReifyAttachment]
+ val att = entry.attachments.get[ReifyAttachment]
att match {
case Some(ReifyAttachment(sym)) =>
// don't duplicate reified symbols when merging inlined reifee
@@ -134,7 +134,7 @@ trait Symbols {
// todo. tried to declare a private class here to carry an attachment, but it's path-dependent
// so got troubles with exchanging free variables between nested and enclosing quasiquotes
// attaching just Symbol isn't good either, so we need to think of a principled solution
- val local = ValDef(NoMods, name, TypeTree(), reified) withAttachment ReifyAttachment(sym)
+ val local = ValDef(NoMods, name, TypeTree(), reified) addAttachment ReifyAttachment(sym)
localReifications += local
filledIn = false
locallyReified(sym) = Ident(name)
@@ -149,7 +149,7 @@ trait Symbols {
while (i < localReifications.length) {
// fillInSymbol might create new locallyReified symbols, that's why this is done iteratively
val reified = localReifications(i)
- val att = reified.attachmentOpt[ReifyAttachment]
+ val att = reified.attachments.get[ReifyAttachment]
att match {
case Some(ReifyAttachment(sym)) => fillIns += fillInSymbol(sym)
case other => // do nothing
diff --git a/src/compiler/scala/reflect/reify/codegen/Trees.scala b/src/compiler/scala/reflect/reify/codegen/Trees.scala
index c9f5fc5b8d..a4543d84c1 100644
--- a/src/compiler/scala/reflect/reify/codegen/Trees.scala
+++ b/src/compiler/scala/reflect/reify/codegen/Trees.scala
@@ -7,7 +7,6 @@ trait Trees {
import mirror._
import definitions._
import treeInfo._
- import scala.reflect.api.Modifier
// unfortunately, these are necessary to reify AnnotatedTypes
// I'd gladly got rid of them, but I don't fancy making a metaprogramming API that doesn't work with annotated types
@@ -106,7 +105,7 @@ trait Trees {
private def spliceTree(tree: Tree): Tree = {
tree match {
- case EvalSplice(splicee) =>
+ case TreeSplice(splicee) =>
if (reifyDebug) println("splicing eval " + tree)
// see ``Metalevels'' for more info about metalevel breaches
@@ -138,9 +137,6 @@ trait Trees {
}.transform(tree)
}
}
- case ValueSplice(splicee) =>
- // todo. implement this
- ???
case _ =>
EmptyTree
}
diff --git a/src/compiler/scala/reflect/runtime/AbstractFile.scala b/src/compiler/scala/reflect/runtime/AbstractFile.scala
index 414bba020b..0f88af1b0a 100644
--- a/src/compiler/scala/reflect/runtime/AbstractFile.scala
+++ b/src/compiler/scala/reflect/runtime/AbstractFile.scala
@@ -1,7 +1,7 @@
package scala.reflect
package runtime
-class AbstractFile(val jfile: java.io.File) extends api.RequiredFile {
+class AbstractFile(val jfile: java.io.File) extends internal.AbstractFileApi {
def path: String = jfile.getPath()
def canonicalPath: String = jfile.getCanonicalPath()
}
diff --git a/src/compiler/scala/reflect/runtime/ClassLoaders.scala b/src/compiler/scala/reflect/runtime/ClassLoaders.scala
deleted file mode 100644
index b73d57c04d..0000000000
--- a/src/compiler/scala/reflect/runtime/ClassLoaders.scala
+++ /dev/null
@@ -1,25 +0,0 @@
-package scala.reflect
-package runtime
-
-trait ClassLoaders extends internal.SymbolTable { self: SymbolTable =>
-
- def staticClass(fullname: String) =
- definitions.getRequiredClass(fullname)
-
- def staticModule(fullname: String) =
- definitions.getRequiredModule(fullname)
-
- /** If `owner` is a package class (but not the empty package) and `name` is a term name, make a new package
- * <owner>.<name>, otherwise return NoSymbol.
- * Exception: If owner is root and a java class with given name exists, create symbol in empty package instead.
- */
- override def missingHook(owner: Symbol, name: Name): Symbol =
- if (owner.isRoot && isJavaClass(name.toString))
- definitions.EmptyPackageClass.info decl name
- else if (name.isTermName && owner.hasPackageFlag && !owner.isEmptyPackageClass)
- makeScalaPackage(if (owner.isRoot) name.toString else owner.fullName+"."+name).sourceModule
- else {
- info("*** missing: "+name+"/"+name.isTermName+"/"+owner+"/"+owner.hasPackageFlag+"/"+owner.info.decls.getClass)
- super.missingHook(owner, name)
- }
-}
diff --git a/src/compiler/scala/reflect/runtime/ConversionUtil.scala b/src/compiler/scala/reflect/runtime/ConversionUtil.scala
deleted file mode 100644
index e45fc243c6..0000000000
--- a/src/compiler/scala/reflect/runtime/ConversionUtil.scala
+++ /dev/null
@@ -1,92 +0,0 @@
-package scala.reflect
-package runtime
-
-import java.lang.{Class => jClass, Package => jPackage}
-import java.lang.reflect.{
- Method => jMethod, Constructor => jConstructor, Modifier => jModifier, Field => jField,
- Member => jMember, Type => jType, TypeVariable => jTypeVariable, GenericDeclaration}
-import collection.mutable.HashMap
-
-trait ConversionUtil { self: SymbolTable =>
-
- /** A cache that maintains a bijection between Java reflection type `J`
- * and Scala reflection type `S`.
- */
- // todo. should be weak
- protected class TwoWayCache[J, S] {
-
- private val toScalaMap = new HashMap[J, S]
- private val toJavaMap = new HashMap[S, J]
-
- def enter(j: J, s: S) = synchronized {
- debugInfo("cached: "+j+"/"+s)
- toScalaMap(j) = s
- toJavaMap(s) = j
- }
-
- def toScala(key: J)(body: => S): S = synchronized {
- toScalaMap get key match {
- case Some(v) =>
- v
- case none =>
- val result = body
- enter(key, result)
- result
- }
- }
-
- def toJava(key: S)(body: => J): J = synchronized {
- toJavaMap get key match {
- case Some(v) =>
- v
- case none =>
- val result = body
- enter(result, key)
- result
- }
- }
-
- def toJavaOption(key: S)(body: => Option[J]): Option[J] = synchronized {
- toJavaMap get key match {
- case None =>
- val result = body
- for (value <- result) enter(value, key)
- result
- case some => some
- }
- }
- }
-
- protected val classCache = new TwoWayCache[jClass[_], Symbol]
- protected val packageCache = new TwoWayCache[Package, Symbol]
- protected val methodCache = new TwoWayCache[jMethod, Symbol]
- protected val constructorCache = new TwoWayCache[jConstructor[_], Symbol]
- protected val fieldCache = new TwoWayCache[jField, Symbol]
- protected val tparamCache = new TwoWayCache[jTypeVariable[_], Symbol]
-
- /** the type of this symbol after Scala -> Java transformsi in refChecks, uncurry, erasure
- */
- def transformedType(sym: Symbol): Type
-
- /** The Java class thaty given type compiles to */
- def typeToJavaClass(tpe: Type): jClass[_]
-
- /** Does method `meth` erase to Java method `jmeth`?
- * This is true if the Java method type is the same as the Scala method type after performing
- * all Scala-specific transformations in InfoTransformers. (to be done)
- */
- protected def erasesTo(meth: Symbol, jmeth: jMethod): Boolean = {
- val mtpe = transformedType(meth)
- (mtpe.paramTypes map typeToJavaClass) == jmeth.getParameterTypes.toList &&
- typeToJavaClass(mtpe.resultType) == jmeth.getReturnType
- }
-
- /** Does constructor `meth` erase to Java method `jconstr`?
- * This is true if the Java constructor type is the same as the Scala constructor type after performing
- * all Scala-specific transformations in InfoTransformers. (to be done)
- */
- protected def erasesTo(meth: Symbol, jconstr: jConstructor[_]): Boolean = {
- val mtpe = transformedType(meth)
- (mtpe.paramTypes map typeToJavaClass) == jconstr.getParameterTypes.toList
- }
-} \ No newline at end of file
diff --git a/src/compiler/scala/reflect/runtime/JavaMirrors.scala b/src/compiler/scala/reflect/runtime/JavaMirrors.scala
new file mode 100644
index 0000000000..a8120d220a
--- /dev/null
+++ b/src/compiler/scala/reflect/runtime/JavaMirrors.scala
@@ -0,0 +1,981 @@
+package scala.reflect
+package runtime
+
+import scala.ref.WeakReference
+import scala.collection.mutable.WeakHashMap
+
+import java.lang.{Class => jClass, Package => jPackage}
+import java.lang.reflect.{
+ Method => jMethod, Constructor => jConstructor, Modifier => jModifier, Field => jField,
+ Member => jMember, Type => jType, TypeVariable => jTypeVariable, Array => jArray,
+ GenericDeclaration, GenericArrayType, ParameterizedType, WildcardType, AnnotatedElement }
+import java.io.IOException
+import internal.MissingRequirementError
+import internal.pickling.ByteCodecs
+import internal.ClassfileConstants._
+import internal.pickling.UnPickler
+import collection.mutable.{ HashMap, ListBuffer }
+import internal.Flags._
+//import scala.tools.nsc.util.ScalaClassLoader
+//import scala.tools.nsc.util.ScalaClassLoader._
+import ReflectionUtils.{singletonInstance}
+import language.existentials
+
+trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse { self: SymbolTable =>
+
+ private lazy val mirrors = new WeakHashMap[ClassLoader, WeakReference[JavaMirror]]()
+
+ private def createMirror(owner: Symbol, cl: ClassLoader): Mirror = {
+ val jm = new JavaMirror(owner, cl)
+ mirrors(cl) = new WeakReference(jm)
+ jm.init()
+ jm
+ }
+
+ override type Mirror = JavaMirror
+
+ override lazy val rootMirror: Mirror = createMirror(NoSymbol, rootClassLoader)
+
+ // overriden by ReflectGlobal
+ def rootClassLoader: ClassLoader = this.getClass.getClassLoader
+
+ def init() = {
+ definitions.AnyValClass // force it.
+
+ // establish root association to avoid cyclic dependency errors later
+ rootMirror.classToScala(classOf[java.lang.Object]).initialize
+
+ // println("initializing definitions")
+ definitions.init()
+ }
+
+ def runtimeMirror(cl: ClassLoader): Mirror = mirrors get cl match {
+ case Some(WeakReference(m)) => m
+ case _ => createMirror(rootMirror.RootClass, cl)
+ }
+
+ /** The API of a mirror for a reflective universe */
+ class JavaMirror(owner: Symbol,
+ /** Class loader that is a mastermind behind the reflexive mirror */
+ val classLoader: ClassLoader
+ ) extends Roots(owner) with super.JavaMirror { wholemirror =>
+
+ val universe: self.type = self
+
+ import definitions._
+
+ /** The lazy type for root.
+ */
+ override lazy val rootLoader = new LazyType {
+ override def complete(sym: Symbol) = sym setInfo new LazyPackageType
+ }
+
+// ----------- Caching ------------------------------------------------------------------
+
+ // [Eugene++ to Martin] not weak? why?
+ private val classCache = new TwoWayCache[jClass[_], ClassSymbol]
+ private val packageCache = new TwoWayCache[Package, ModuleSymbol]
+ private val methodCache = new TwoWayCache[jMethod, MethodSymbol]
+ private val constructorCache = new TwoWayCache[jConstructor[_], MethodSymbol]
+ private val fieldCache = new TwoWayCache[jField, TermSymbol]
+ private val tparamCache = new TwoWayCache[jTypeVariable[_ <: GenericDeclaration], TypeSymbol]
+
+ def toScala[J: HasJavaClass, S](cache: TwoWayCache[J, S], key: J)(body: (JavaMirror, J) => S): S =
+ cache.toScala(key){
+ val jclazz = implicitly[HasJavaClass[J]] getClazz key
+ body(mirrorDefining(jclazz), key)
+ }
+
+ private implicit val classHasJavaClass: HasJavaClass[jClass[_]] =
+ new HasJavaClass(identity)
+ private implicit val methHasJavaClass: HasJavaClass[jMethod]
+ = new HasJavaClass(_.getDeclaringClass)
+ private implicit val fieldHasJavaClass: HasJavaClass[jField] =
+ new HasJavaClass(_.getDeclaringClass)
+ private implicit val constrHasJavaClass: HasJavaClass[jConstructor[_]] =
+ new HasJavaClass(_.getDeclaringClass)
+ private implicit val tparamHasJavaClass: HasJavaClass[jTypeVariable[_ <: GenericDeclaration]] =
+ new HasJavaClass ( (tparam: jTypeVariable[_ <: GenericDeclaration]) => {
+ tparam.getGenericDeclaration match {
+ case jclazz: jClass[_] => jclazz
+ case jmeth: jMethod => jmeth.getDeclaringClass
+ case jconstr: jConstructor[_] => jconstr.getDeclaringClass
+ }
+ })
+
+// ----------- Implementations of mirror operations and classes -------------------
+
+ def reflect(obj: Any): InstanceMirror =
+ new JavaInstanceMirror(obj.asInstanceOf[AnyRef])
+
+ def reflectClass(runtimeClass: RuntimeClass): ClassMirror =
+ new JavaClassMirror(classToScala(runtimeClass))
+
+ def reflectClass(fullName: String): ClassMirror =
+ reflectClass(java.lang.Class.forName(fullName))
+
+ def reflectModule(runtimeClass: RuntimeClass): ModuleMirror =
+ new JavaModuleMirror(classToScala(runtimeClass).companionModule.asModuleSymbol)
+
+ def reflectModule(fullName: String): ModuleMirror =
+ reflectModule(java.lang.Class.forName(fullName))
+
+ def runtimeClass(tpe: Type): RuntimeClass = typeToJavaClass(tpe)
+
+ def runtimeClass(cls: ClassSymbol): RuntimeClass = classToJava(cls)
+
+ private class JavaInstanceMirror(obj: AnyRef)
+ extends InstanceMirror {
+ def instance = obj
+ def reflectClass = wholemirror.reflectClass(obj.getClass)
+ def reflectField(field: TermSymbol): FieldMirror = new JavaFieldMirror(obj, field)
+ def reflectMethod(method: MethodSymbol): MethodMirror = new JavaMethodMirror(obj, method)
+ }
+
+ private class JavaFieldMirror(val receiver: AnyRef, val field: TermSymbol)
+ extends FieldMirror {
+ lazy val jfield = fieldToJava(field)
+ def get = jfield.get(receiver)
+ def set(value: Any) = jfield.set(receiver, value)
+ }
+
+ private class JavaMethodMirror(val receiver: AnyRef, val method: MethodSymbol)
+ extends MethodMirror {
+ lazy val jmeth = methodToJava(method)
+ def apply(args: Any*): Any =
+ if (method.owner == ArrayClass)
+ method.name match {
+ case nme.length => jArray.getLength(receiver)
+ case nme.apply => jArray.get(receiver, args(0).asInstanceOf[Int])
+ case nme.update => jArray.set(receiver, args(0).asInstanceOf[Int], args(1))
+ case _ => throw new Error(s"unexpected array method $method")
+ }
+ else
+ jmeth.invoke(receiver, args.asInstanceOf[Seq[AnyRef]]: _*)
+ }
+
+ private class JavaConstructorMirror(val method: MethodSymbol)
+ extends MethodMirror {
+ override val receiver = null
+ lazy val jconstr = constructorToJava(method)
+ def apply(args: Any*): Any = jconstr.newInstance(args.asInstanceOf[Seq[AnyRef]]: _*)
+ }
+
+
+ private abstract class JavaTemplateMirror
+ extends TemplateMirror {
+ def erasure: ClassSymbol
+ lazy val runtimeClass = classToJava(erasure)
+ lazy val signature = typeToScala(runtimeClass)
+ }
+
+ private class JavaClassMirror(val symbol: ClassSymbol)
+ extends JavaTemplateMirror with ClassMirror {
+ def erasure = symbol
+ def isStatic = false
+ def reflectConstructor(constructor: MethodSymbol) = new JavaConstructorMirror(constructor)
+ def companion: Option[ModuleMirror] = symbol.companionModule match {
+ case module: ModuleSymbol => Some(new JavaModuleMirror(module))
+ case _ => None
+ }
+ }
+
+ private class JavaModuleMirror(val symbol: ModuleSymbol)
+ extends JavaTemplateMirror with ModuleMirror {
+ def erasure = symbol.moduleClass.asClassSymbol
+ def isStatic = true
+ def instance = singletonInstance(classLoader, symbol.fullName)
+ def companion: Option[ClassMirror] = symbol.companionClass match {
+ case cls: ClassSymbol => Some(new JavaClassMirror(cls))
+ case _ => None
+ }
+ }
+
+// -------------------- Java to Scala -----------------------------------
+
+ /** Does method `meth` erase to Java method `jmeth`?
+ * This is true if the Java method type is the same as the Scala method type after performing
+ * all Scala-specific transformations in InfoTransformers. (to be done)
+ */
+ private def erasesTo(meth: Symbol, jmeth: jMethod): Boolean = {
+ val mtpe = transformedType(meth)
+ (mtpe.paramTypes map runtimeClass) == jmeth.getParameterTypes.toList &&
+ runtimeClass(mtpe.resultType) == jmeth.getReturnType
+ }
+
+ private def erasesTo(meth: Symbol, jconstr: jConstructor[_]): Boolean = {
+ val mtpe = transformedType(meth)
+ (mtpe.paramTypes map runtimeClass) == jconstr.getParameterTypes.toList &&
+ runtimeClass(mtpe.resultType) == jconstr.getDeclaringClass
+ }
+
+ def javaClass(path: String): jClass[_] =
+ Class.forName(path, true, classLoader)
+
+ /** Does `path` correspond to a Java class with that fully qualified name in the current class loader? */
+ def tryJavaClass(path: String): Option[jClass[_]] =
+ try {
+ Some(javaClass(path))
+ } catch {
+ case (_: ClassNotFoundException) | (_: NoClassDefFoundError) | (_: IncompatibleClassChangeError) =>
+ None
+ }
+
+ /** The mirror that corresponds to the classloader that original defined the given Java class */
+ def mirrorDefining(jclazz: jClass[_]): JavaMirror = {
+ val cl = jclazz.getClassLoader
+ if (cl == this.classLoader) this else runtimeMirror(cl)
+ }
+
+ private object unpickler extends UnPickler {
+ val global: self.type = self
+ }
+
+ /** how connected????
+ * Generate types for top-level Scala root class and root companion object
+ * from the pickled information stored in a corresponding Java class
+ * @param clazz The top-level Scala class for which info is unpickled
+ * @param module The top-level Scala companion object for which info is unpickled
+ * @param jclazz The Java class which contains the unpickled information in a
+ * ScalaSignature or ScalaLongSignature annotation.
+ */
+ def unpickleClass(clazz: Symbol, module: Symbol, jclazz: jClass[_]): Unit = {
+ def markAbsent(tpe: Type) = setAllInfos(clazz, module, tpe)
+ def handleError(ex: Exception) = {
+ markAbsent(ErrorType)
+ if (settings.debug.value) ex.printStackTrace()
+ val msg = ex.getMessage()
+ MissingRequirementError.signal(
+ (if (msg eq null) "reflection error while loading " + clazz.name
+ else "error while loading " + clazz.name) + ", " + msg)
+ }
+ // don't use classOf[scala.reflect.ScalaSignature] here, because it will use getClass.getClassLoader, not mirror's classLoader
+ // don't use asInstanceOf either because of the same reason (lol, I cannot believe I fell for it)
+ // don't use structural types to simplify reflective invocations because of the same reason
+ def loadAnnotation(name: String): Option[java.lang.annotation.Annotation] =
+ tryJavaClass(name) flatMap { annotClass =>
+ val anns = jclazz.getAnnotations
+ val result = anns find (_.annotationType == annotClass)
+ if (result.isEmpty && (anns exists (_.annotationType.getName == name)))
+ throw new ClassNotFoundException(
+ s"""Mirror classloader mismatch: $jclazz (loaded by ${ReflectionUtils.show(jclazz.getClassLoader)})
+ |is unrelated to the mirror's classloader: (${ReflectionUtils.show(classLoader)})""".stripMargin)
+ result
+ }
+ def loadBytes[T: ClassTag](name: String): Option[T] =
+ loadAnnotation(name) map { ssig =>
+ val bytesMethod = ssig.annotationType.getMethod("bytes")
+ bytesMethod.invoke(ssig).asInstanceOf[T]
+ }
+
+ try {
+ markAbsent(NoType)
+ loadBytes[String]("scala.reflect.ScalaSignature") match {
+ case Some(ssig) =>
+ info(s"unpickling Scala $clazz and $module, owner = ${clazz.owner}")
+ val bytes = ssig.getBytes
+ val len = ByteCodecs.decode(bytes)
+ unpickler.unpickle(bytes take len, 0, clazz, module, jclazz.getName)
+ case None =>
+ loadBytes[Array[String]]("scala.reflect.ScalaLongSignature") match {
+ case Some(slsig) =>
+ info(s"unpickling Scala $clazz and $module with long Scala signature")
+ val byteSegments = slsig map (_.getBytes)
+ val lens = byteSegments map ByteCodecs.decode
+ val bytes = Array.ofDim[Byte](lens.sum)
+ var len = 0
+ for ((bs, l) <- byteSegments zip lens) {
+ bs.copyToArray(bytes, len, l)
+ len += l
+ }
+ unpickler.unpickle(bytes, 0, clazz, module, jclazz.getName)
+ case None =>
+ // class does not have a Scala signature; it's a Java class
+ info("translating reflection info for Java " + jclazz) //debug
+ initClassModule(clazz, module, new FromJavaClassCompleter(clazz, module, jclazz))
+ }
+ }
+ } catch {
+ case ex: MissingRequirementError =>
+ handleError(ex)
+ case ex: IOException =>
+ handleError(ex)
+ }
+ }
+
+ /**
+ * A fresh Scala type parameter that corresponds to a Java type variable.
+ * The association between Scala type parameter and Java type variable is entered in the cache.
+ * @param jtvar The Java type variable
+ */
+ private def createTypeParameter(jtvar: jTypeVariable[_ <: GenericDeclaration]): TypeSymbol = {
+ val tparam = sOwner(jtvar).newTypeParameter(newTypeName(jtvar.getName))
+ .setInfo(new TypeParamCompleter(jtvar))
+ tparamCache enter (jtvar, tparam)
+ tparam
+ }
+
+ /**
+ * A completer that fills in the type of a Scala type parameter from the bounds of a Java type variable.
+ * @param jtvar The Java type variable
+ */
+ private class TypeParamCompleter(jtvar: jTypeVariable[_ <: GenericDeclaration]) extends LazyType {
+ override def load(sym: Symbol) = complete(sym)
+ override def complete(sym: Symbol) = {
+ sym setInfo TypeBounds.upper(glb(jtvar.getBounds.toList map typeToScala map objToAny))
+ }
+ }
+
+ /**
+ * Copy all annotations of Java annotated element `jann` over to Scala symbol `sym`.
+ * Pre: `sym` is already initialized with a concrete type.
+ * Note: If `sym` is a method or constructor, its parameter annotations are copied as well.
+ */
+ private def copyAnnotations(sym: Symbol, jann: AnnotatedElement) {
+ // to do: implement
+ }
+
+ /**
+ * A completer that fills in the types of a Scala class and its companion object
+ * by copying corresponding type info from a Java class. This completer is used
+ * to reflect classes in Scala that do not have a Scala pickle info, be it
+ * because they are local classes or have been compiled from Java sources.
+ * @param clazz The Scala class for which info is copied
+ * @param module The Scala companion object for which info is copied
+ * @param jclazz The Java class
+ */
+ private class FromJavaClassCompleter(clazz: Symbol, module: Symbol, jclazz: jClass[_]) extends LazyType {
+
+ /** used to avoid cycles while initializing classes */
+ private var parentsLevel = 0
+ private var pendingLoadActions: List[() => Unit] = Nil
+
+ override def load(sym: Symbol): Unit = {
+ debugInfo("completing from Java " + sym + "/" + clazz.fullName)//debug
+ assert(sym == clazz || (module != NoSymbol && (sym == module || sym == module.moduleClass)), sym)
+ val flags = toScalaClassFlags(jclazz.getModifiers)
+ clazz setFlag (flags | JAVA)
+ if (module != NoSymbol) {
+ module setFlag (flags & PRIVATE | JAVA)
+ module.moduleClass setFlag (flags & PRIVATE | JAVA)
+ }
+
+ copyAnnotations(clazz, jclazz)
+ // to do: annotations to set also for module?
+
+ clazz setInfo new LazyPolyType(jclazz.getTypeParameters.toList map createTypeParameter)
+ if (module != NoSymbol) {
+ module setInfo module.moduleClass.tpe
+ module.moduleClass setInfo new LazyPolyType(List())
+ }
+ }
+
+ override def complete(sym: Symbol): Unit = {
+ load(sym)
+ completeRest()
+ }
+
+ def completeRest(): Unit = self.synchronized {
+ val tparams = clazz.rawInfo.typeParams
+
+ val parents = try {
+ parentsLevel += 1
+ val jsuperclazz = jclazz.getGenericSuperclass
+ val superclazz = if (jsuperclazz == null) AnyClass.tpe else typeToScala(jsuperclazz)
+ superclazz :: (jclazz.getGenericInterfaces.toList map typeToScala)
+ } finally {
+ parentsLevel -= 1
+ }
+ clazz setInfo GenPolyType(tparams, new ClassInfoType(parents, newScope, clazz))
+ if (module != NoSymbol) {
+ module.moduleClass setInfo new ClassInfoType(List(), newScope, module.moduleClass)
+ }
+
+ def enter(sym: Symbol, mods: Int) =
+ (if (jModifier.isStatic(mods)) module.moduleClass else clazz).info.decls enter sym
+
+ for (jinner <- jclazz.getDeclaredClasses) {
+ enter(jclassAsScala(jinner, clazz), jinner.getModifiers)
+ }
+
+ pendingLoadActions = { () =>
+
+ for (jfield <- jclazz.getDeclaredFields)
+ enter(jfieldAsScala(jfield), jfield.getModifiers)
+
+ for (jmeth <- jclazz.getDeclaredMethods)
+ enter(jmethodAsScala(jmeth), jmeth.getModifiers)
+
+ for (jconstr <- jclazz.getConstructors)
+ enter(jconstrAsScala(jconstr), jconstr.getModifiers)
+
+ } :: pendingLoadActions
+
+ if (parentsLevel == 0) {
+ while (!pendingLoadActions.isEmpty) {
+ val item = pendingLoadActions.head
+ pendingLoadActions = pendingLoadActions.tail
+ item()
+ }
+ }
+ }
+
+ class LazyPolyType(override val typeParams: List[Symbol]) extends LazyType {
+ override def complete(sym: Symbol) {
+ completeRest()
+ }
+ }
+ }
+
+ /**
+ * If Java modifiers `mods` contain STATIC, return the module class
+ * of the companion module of `clazz`, otherwise the class `clazz` itself.
+ */
+ private def followStatic(clazz: Symbol, mods: Int) =
+ if (jModifier.isStatic(mods)) clazz.companionModule.moduleClass else clazz
+
+ implicit class RichClass(jclazz: jClass[_]) {
+ // [Eugene++] `jclazz.isLocalClass` doesn't work because of problems with `getSimpleName`
+ // java.lang.Error: sOwner(class Test$A$1) has failed
+ // Caused by: java.lang.InternalError: Malformed class name
+ // at java.lang.Class.getSimpleName(Class.java:1133)
+ // at java.lang.Class.isAnonymousClass(Class.java:1188)
+ // at java.lang.Class.isLocalClass(Class.java:1199)
+ // (see t5256c.scala for more details)
+ // hence we have to approximate by removing the `isAnonymousClass` check
+// def isLocalClass0: Boolean = jclazz.isLocalClass
+ def isLocalClass0: Boolean = jclazz.getEnclosingMethod != null || jclazz.getEnclosingConstructor != null
+ }
+
+ // [Eugene++] overflow from Paul's changes made concurrently with reflection refactoring
+ // https://github.com/scala/scala/commit/90d2bee45b25844f809f8c5300aefcb1bfe9e336
+ //
+ // /** Methods which need to be wrapped because they either are getSimpleName
+ // * or call getSimpleName:
+ // *
+ // * public String getSimpleName()
+ // * public boolean isAnonymousClass()
+ // * public boolean isLocalClass()
+ // * public boolean isMemberClass()
+ // * public String getCanonicalName()
+ // *
+ // * TODO - find all such calls and wrap them.
+ // * TODO - create mechanism to avoid the recurrence of unwrapped calls.
+ // */
+ // private def wrapClassCheck[T](alt: T)(body: => T): T =
+ // try body catch { case x: InternalError if x.getMessage == "Malformed class name" => alt }
+
+ // private def wrapIsLocalClass(clazz: jClass[_]): Boolean =
+ // wrapClassCheck(false)(clazz.isLocalClass)
+
+ // private def wrapGetSimpleName(clazz: jClass[_]): String =
+ // wrapClassCheck("")(clazz.getSimpleName)
+
+ /**
+ * The Scala owner of the Scala class corresponding to the Java class `jclazz`
+ */
+ private def sOwner(jclazz: jClass[_]): Symbol =
+ if (jclazz.isMemberClass) {
+ val jEnclosingClass = jclazz.getEnclosingClass
+ val sEnclosingClass = classToScala(jEnclosingClass)
+ followStatic(sEnclosingClass, jclazz.getModifiers)
+ } else if (jclazz.isLocalClass0) {
+ val jEnclosingMethod = jclazz.getEnclosingMethod
+ if (jEnclosingMethod != null) {
+ methodToScala(jEnclosingMethod)
+ } else {
+ val jEnclosingConstructor = jclazz.getEnclosingConstructor
+ constructorToScala(jEnclosingConstructor)
+ }
+ } else if (jclazz.isPrimitive || jclazz.isArray) {
+ ScalaPackageClass
+ } else if (jclazz.getPackage != null) {
+ val jPackage = jclazz.getPackage
+ packageToScala(jPackage).moduleClass
+ } else {
+ // @eb: a weird classloader might return a null package for something with a non-empty package name
+ // for example, http://groups.google.com/group/scala-internals/browse_thread/thread/7be09ff8f67a1e5c
+ // in that case we could invoke packageNameToScala(jPackageName) and, probably, be okay
+ // however, I think, it's better to blow up, since weirdness of the class loader might bite us elsewhere
+ // [martin] I think it's better to be forgiving here. Restoring packageNameToScala.
+ val jPackageName = jclazz.getName take jclazz.getName.lastIndexOf('.')
+ packageNameToScala(jPackageName).moduleClass
+ }
+
+ /**
+ * The Scala owner of the Scala symbol corresponding to the Java member `jmember`
+ */
+ private def sOwner(jmember: jMember): Symbol = {
+ followStatic(classToScala(jmember.getDeclaringClass), jmember.getModifiers)
+ }
+
+ /**
+ * The Scala owner of the Scala type parameter corresponding to the Java type variable `jtvar`
+ */
+ private def sOwner(jtvar: jTypeVariable[_ <: GenericDeclaration]): Symbol =
+ genericDeclarationToScala(jtvar.getGenericDeclaration)
+
+ /**
+ * Find declarations or definition in class `clazz` that maps to a Java
+ * entity with name `jname`. Because of name-mangling, this is more difficult
+ * than a simple name-based lookup via `decl`. If `decl` fails, members
+ * that start with the given name are searched instead.
+ */
+ private def lookup(clazz: Symbol, jname: String): Symbol = {
+ def approximateMatch(sym: Symbol, jstr: String): Boolean =
+ (sym.name.toString == jstr) ||
+ sym.isPrivate && nme.expandedName(sym.name.toTermName, sym.owner).toString == jstr
+
+ clazz.info.decl(newTermName(jname)) orElse {
+ (clazz.info.decls.iterator filter (approximateMatch(_, jname))).toList match {
+ case List() => NoSymbol
+ case List(sym) => sym
+ case alts => clazz.newOverloaded(alts.head.tpe.prefix, alts)
+ }
+ }
+ }
+
+ /**
+ * The Scala method corresponding to given Java method.
+ * @param jmeth The Java method
+ * @return A Scala method object that corresponds to `jmeth`.
+ */
+ def methodToScala(jmeth: jMethod): MethodSymbol =
+ toScala(methodCache, jmeth)(_ methodToScala1 _)
+
+ private def methodToScala1(jmeth: jMethod): MethodSymbol = {
+ val jOwner = jmeth.getDeclaringClass
+ val preOwner = classToScala(jOwner)
+ val owner = followStatic(preOwner, jmeth.getModifiers)
+ (lookup(owner, jmeth.getName) suchThat (erasesTo(_, jmeth)) orElse jmethodAsScala(jmeth))
+ .asMethodSymbol
+ }
+
+ /**
+ * The Scala constructor corresponding to given Java constructor.
+ * @param jconstr The Java constructor
+ * @return A Scala method object that corresponds to `jconstr`.
+ */
+ def constructorToScala(jconstr: jConstructor[_]): MethodSymbol =
+ toScala(constructorCache, jconstr)(_ constructorToScala1 _)
+
+ private def constructorToScala1(jconstr: jConstructor[_]): MethodSymbol = {
+ val owner = followStatic(classToScala(jconstr.getDeclaringClass), jconstr.getModifiers)
+ (lookup(owner, jconstr.getName) suchThat (erasesTo(_, jconstr)) orElse jconstrAsScala(jconstr))
+ .asMethodSymbol
+ }
+
+ /**
+ * The Scala field corresponding to given Java field.
+ * @param jfield The Java field
+ * @return A Scala field object that corresponds to `jfield`.
+ * // ??? should we return the getter instead?
+ */
+ def fieldToScala(jfield: jField): TermSymbol =
+ toScala(fieldCache, jfield)(_ fieldToScala1 _)
+
+ private def fieldToScala1(jfield: jField): TermSymbol = {
+ val owner = followStatic(classToScala(jfield.getDeclaringClass), jfield.getModifiers)
+ (lookup(owner, jfield.getName) suchThat (!_.isMethod) orElse jfieldAsScala(jfield))
+ .asTermSymbol
+ }
+
+ /**
+ * The Scala package corresponding to given Java package
+ */
+ def packageToScala(jpkg: jPackage): ModuleSymbol = packageCache.toScala(jpkg) {
+ makeScalaPackage(jpkg.getName)
+ }
+
+ /**
+ * The Scala package with given fully qualified name.
+ */
+ def packageNameToScala(fullname: String): ModuleSymbol = {
+ if (fullname == "") EmptyPackage
+ else {
+ val jpkg = jPackage.getPackage(fullname)
+ if (jpkg != null) packageToScala(jpkg) else makeScalaPackage(fullname)
+ }
+ }
+
+ /**
+ * The Scala package with given fully qualified name. Unlike `packageNameToScala`,
+ * this one bypasses the cache.
+ */
+ private[JavaMirrors] def makeScalaPackage(fullname: String): ModuleSymbol = {
+ val split = fullname lastIndexOf '.'
+ val ownerModule: ModuleSymbol =
+ if (split > 0) packageNameToScala(fullname take split) else this.RootPackage
+ val owner = ownerModule.moduleClass
+ val name = newTermName(fullname drop (split + 1))
+ val opkg = owner.info decl name
+ if (opkg.isPackage)
+ opkg.asModuleSymbol
+ else if (opkg == NoSymbol) {
+ val pkg = owner.newPackage(name)
+ pkg.moduleClass setInfo new LazyPackageType
+ pkg setInfoAndEnter pkg.moduleClass.tpe
+ info("made Scala "+pkg)
+ pkg
+ } else
+ throw new ReflectError(opkg+" is not a package")
+ }
+
+ private def scalaSimpleName(jclazz: jClass[_]): TypeName = {
+ val owner = sOwner(jclazz)
+ val enclosingClass = jclazz.getEnclosingClass
+ var prefix = if (enclosingClass != null) enclosingClass.getName else ""
+ val isObject = owner.isModuleClass && !owner.isPackageClass
+ if (isObject && !prefix.endsWith(nme.MODULE_SUFFIX_STRING)) prefix += nme.MODULE_SUFFIX_STRING
+ assert(jclazz.getName.startsWith(prefix))
+ var name = jclazz.getName.substring(prefix.length)
+ name = name.substring(name.lastIndexOf(".") + 1)
+ newTypeName(name)
+ }
+
+ /**
+ * The Scala class that corresponds to a given Java class.
+ * @param jclazz The Java class
+ * @return A Scala class symbol that reflects all elements of the Java class,
+ * in the form they appear in the Scala pickling info, or, if that is
+ * not available, wrapped from the Java reflection info.
+ */
+ def classToScala(jclazz: jClass[_]): ClassSymbol =
+ toScala(classCache, jclazz)(_ classToScala1 _)
+
+ private def classToScala1(jclazz: jClass[_]): ClassSymbol = {
+ val jname = newTypeName(jclazz.getName)
+ if (jname == fulltpnme.RuntimeNothing) NothingClass
+ else if (jname == fulltpnme.RuntimeNull) NullClass
+ else {
+ val owner = sOwner(jclazz)
+ val simpleName = scalaSimpleName(jclazz)
+
+ def lookupClass = {
+ def coreLookup(name: Name): Symbol =
+ owner.info.decl(name) orElse {
+ if (name.startsWith(nme.NAME_JOIN_STRING)) coreLookup(name drop 1) else NoSymbol
+ }
+ if (nme.isModuleName(simpleName))
+ coreLookup(nme.stripModuleSuffix(simpleName).toTermName) map (_.moduleClass)
+ else
+ coreLookup(simpleName)
+ }
+
+ val cls =
+ if (jclazz.isMemberClass && !nme.isImplClassName(jname))
+ lookupClass
+ else if (jclazz.isLocalClass0 || isInvalidClassName(jname))
+ // local classes and implementation classes not preserved by unpickling - treat as Java
+ jclassAsScala(jclazz)
+ else if (jclazz.isArray)
+ ArrayClass
+ else
+ javaTypeToValueClass(jclazz) orElse lookupClass
+
+ assert (cls.isType,
+ s"""${if (cls == NoSymbol) "not a type: symbol" else "no symbol could be"}
+ | loaded from $jclazz in $owner with name $simpleName and classloader $classLoader""".stripMargin)
+
+ cls.asClassSymbol
+ }
+ }
+
+ /**
+ * The Scala type parameter that corresponds to a given Java type parameter.
+ * @param jparam The Java type parameter
+ * @return A Scala type parameter symbol that has the same owner and name as the Java type parameter
+ */
+ def typeParamToScala(jparam: jTypeVariable[_ <: GenericDeclaration]): TypeSymbol =
+ toScala(tparamCache, jparam)(_ typeParamToScala1 _)
+
+ private def typeParamToScala1(jparam: jTypeVariable[_ <: GenericDeclaration]): TypeSymbol = {
+ val owner = genericDeclarationToScala(jparam.getGenericDeclaration)
+ owner.info match {
+ case PolyType(tparams, _) => tparams.find(_.name.toString == jparam.getName).get.asTypeSymbol
+ }
+ }
+
+ /**
+ * The Scala symbol that corresponds to a given Java generic declaration (class, method, or constructor)
+ */
+ def genericDeclarationToScala(jdecl: GenericDeclaration): Symbol = jdecl match {
+ case jclazz: jClass[_] => classToScala(jclazz)
+ case jmeth: jMethod => methodToScala(jmeth)
+ case jconstr: jConstructor[_] => constructorToScala(jconstr)
+ }
+
+ /**
+ * Given some Java type arguments, a corresponding list of Scala types, plus potentially
+ * some existentially bound type variables that represent wildcard arguments.
+ */
+ private def targsToScala(owner: Symbol, args: List[jType]): (List[Type], List[TypeSymbol]) = {
+ val tparams = new ListBuffer[TypeSymbol]
+ def targToScala(arg: jType): Type = arg match {
+ case jwild: WildcardType =>
+ val tparam = owner.newExistential(newTypeName("T$" + tparams.length))
+ .setInfo(TypeBounds(
+ lub(jwild.getLowerBounds.toList map typeToScala),
+ glb(jwild.getUpperBounds.toList map typeToScala map objToAny)))
+ tparams += tparam
+ typeRef(NoPrefix, tparam, List())
+ case _ =>
+ typeToScala(arg)
+ }
+ (args map targToScala, tparams.toList)
+ }
+
+ /**
+ * The Scala type that corresponds to given Java type
+ */
+ def typeToScala(jtpe: jType): Type = jtpe match {
+ case jclazz: jClass[_] =>
+ if (jclazz.isArray)
+ arrayType(typeToScala(jclazz.getComponentType))
+ else {
+ val clazz = classToScala(jclazz)
+ rawToExistential(typeRef(clazz.owner.thisType, clazz, List()))
+ }
+ case japplied: ParameterizedType =>
+ val (pre, sym) = typeToScala(japplied.getRawType) match {
+ case ExistentialType(tparams, TypeRef(pre, sym, _)) => (pre, sym)
+ case TypeRef(pre, sym, _) => (pre, sym)
+ }
+ val args0 = japplied.getActualTypeArguments
+ val (args, bounds) = targsToScala(pre.typeSymbol, args0.toList)
+ ExistentialType(bounds, typeRef(pre, sym, args))
+ case jarr: GenericArrayType =>
+ arrayType(typeToScala(jarr.getGenericComponentType))
+ case jtvar: jTypeVariable[_] =>
+ val tparam = typeParamToScala(jtvar)
+ typeRef(NoPrefix, tparam, List())
+ }
+
+ /**
+ * The Scala class that corresponds to given Java class without taking
+ * Scala pickling info into account.
+ * @param jclazz The Java class
+ * @return A Scala class symbol that wraps all reflection info of `jclazz`
+ */
+ private def jclassAsScala(jclazz: jClass[_]): Symbol = jclassAsScala(jclazz, sOwner(jclazz))
+
+ private def jclassAsScala(jclazz: jClass[_], owner: Symbol): ClassSymbol = {
+ val name = scalaSimpleName(jclazz)
+ val completer = (clazz: Symbol, module: Symbol) => new FromJavaClassCompleter(clazz, module, jclazz)
+ val (clazz, module) = createClassModule(owner, name, completer)
+ classCache enter (jclazz, clazz)
+ clazz
+ }
+
+ /**
+ * The Scala field that corresponds to given Java field without taking
+ * Scala pickling info into account.
+ * @param jfield The Java field
+ * @return A Scala value symbol that wraps all reflection info of `jfield`
+ */
+ private def jfieldAsScala(jfield: jField): TermSymbol =
+ toScala(fieldCache, jfield)(_ jfieldAsScala1 _)
+
+ private def jfieldAsScala1(jfield: jField): TermSymbol = {
+ val field = sOwner(jfield)
+ .newValue(newTermName(jfield.getName), NoPosition, toScalaFieldFlags(jfield.getModifiers))
+ .setInfo(typeToScala(jfield.getGenericType))
+ fieldCache enter (jfield, field)
+ copyAnnotations(field, jfield)
+ field
+ }
+
+ private def setMethType(meth: Symbol, tparams: List[Symbol], paramtpes: List[Type], restpe: Type) = {
+ meth setInfo GenPolyType(tparams, MethodType(meth.owner.newSyntheticValueParams(paramtpes map objToAny), restpe))
+ }
+
+ /**
+ * The Scala method that corresponds to given Java method without taking
+ * Scala pickling info into account.
+ * @param jmeth The Java method
+ * @return A Scala method symbol that wraps all reflection info of `jmethod`
+ */
+ private def jmethodAsScala(jmeth: jMethod): MethodSymbol =
+ toScala(methodCache, jmeth)(_ jmethodAsScala1 _)
+
+ private def jmethodAsScala1(jmeth: jMethod): MethodSymbol = {
+ val clazz = sOwner(jmeth)
+ val meth = clazz.newMethod(newTermName(jmeth.getName), NoPosition, toScalaMethodFlags(jmeth.getModifiers))
+ methodCache enter (jmeth, meth)
+ val tparams = jmeth.getTypeParameters.toList map createTypeParameter
+ val paramtpes = jmeth.getGenericParameterTypes.toList map typeToScala
+ val resulttpe = typeToScala(jmeth.getGenericReturnType)
+ setMethType(meth, tparams, paramtpes, resulttpe)
+ copyAnnotations(meth, jmeth)
+ if ((jmeth.getModifiers & JAVA_ACC_VARARGS) != 0) meth.setInfo(arrayToRepeated(meth.info))
+ meth
+ }
+
+ /**
+ * The Scala constructor that corresponds to given Java constructor without taking
+ * Scala pickling info into account.
+ * @param jconstr The Java constructor
+ * @return A Scala constructor symbol that wraps all reflection info of `jconstr`
+ */
+ private def jconstrAsScala(jconstr: jConstructor[_]): MethodSymbol =
+ toScala(constructorCache, jconstr)(_ jconstrAsScala1 _)
+
+ private def jconstrAsScala1(jconstr: jConstructor[_]): MethodSymbol = {
+ // [Martin] Note: I know there's a lot of duplication wrt jmethodAsScala, but don't think it's worth it to factor this out.
+ val clazz = sOwner(jconstr)
+ val constr = clazz.newConstructor(NoPosition, toScalaMethodFlags(jconstr.getModifiers))
+ constructorCache enter (jconstr, constr)
+ val tparams = jconstr.getTypeParameters.toList map createTypeParameter
+ val paramtpes = jconstr.getGenericParameterTypes.toList map typeToScala
+ setMethType(constr, tparams, paramtpes, clazz.tpe)
+ constr setInfo GenPolyType(tparams, MethodType(clazz.newSyntheticValueParams(paramtpes), clazz.tpe))
+ copyAnnotations(constr, jconstr)
+ constr
+ }
+
+// -------------------- Scala to Java -----------------------------------
+
+ /** Optionally, the Java package corresponding to a given Scala package, or None if no such Java package exists.
+ * @param pkg The Scala package
+ */
+ def packageToJavaOption(pkg: ModuleSymbol): Option[jPackage] = packageCache.toJavaOption(pkg) {
+ Option(jPackage.getPackage(pkg.fullName.toString))
+ }
+
+ /** The Java class corresponding to given Scala class.
+ * Note: This only works for
+ * - top-level classes
+ * - Scala classes that were generated via jclassToScala
+ * - classes that have a class owner that has a corresponding Java class
+ * @throws A `ClassNotFoundException` for all Scala classes not in one of these categories.
+ */
+ @throws(classOf[ClassNotFoundException])
+ def classToJava(clazz: ClassSymbol): jClass[_] = classCache.toJava(clazz) {
+ def noClass = throw new ClassNotFoundException("no Java class corresponding to "+clazz+" found")
+ //println("classToJava "+clazz+" "+clazz.owner+" "+clazz.owner.isPackageClass)//debug
+ if (clazz.isPrimitiveValueClass)
+ valueClassToJavaType(clazz)
+ else if (clazz == ArrayClass)
+ noClass
+ else if (clazz.owner.isPackageClass)
+ javaClass(clazz.javaClassName)
+ else if (clazz.owner.isClass)
+ classToJava(clazz.owner.asClassSymbol)
+ .getDeclaredClasses
+ .find(_.getSimpleName == clazz.name.toString)
+ .getOrElse(noClass)
+ else
+ noClass
+ }
+
+ private def expandedName(sym: Symbol): String =
+ if (sym.isPrivate) nme.expandedName(sym.name.toTermName, sym.owner).toString
+ else sym.name.toString
+
+ /** The Java field corresponding to a given Scala field.
+ * @param meth The Scala field.
+ */
+ def fieldToJava(fld: TermSymbol): jField = fieldCache.toJava(fld) {
+ val jclazz = classToJava(fld.owner.asClassSymbol)
+ try jclazz getDeclaredField fld.name.toString
+ catch {
+ case ex: NoSuchFieldException => jclazz getDeclaredField expandedName(fld)
+ }
+ }
+
+ /** The Java method corresponding to a given Scala method.
+ * @param meth The Scala method
+ */
+ def methodToJava(meth: MethodSymbol): jMethod = methodCache.toJava(meth) {
+ val jclazz = classToJava(meth.owner.asClassSymbol)
+ val paramClasses = transformedType(meth).paramTypes map typeToJavaClass
+ try jclazz getDeclaredMethod (meth.name.toString, paramClasses: _*)
+ catch {
+ case ex: NoSuchMethodException =>
+ jclazz getDeclaredMethod (expandedName(meth), paramClasses: _*)
+ }
+ }
+
+ /** The Java constructor corresponding to a given Scala constructor.
+ * @param constr The Scala constructor
+ */
+ def constructorToJava(constr: MethodSymbol): jConstructor[_] = constructorCache.toJava(constr) {
+ val jclazz = classToJava(constr.owner.asClassSymbol)
+ val paramClasses = transformedType(constr).paramTypes map typeToJavaClass
+ jclazz getConstructor (paramClasses: _*)
+ }
+
+ private def jArrayClass(elemClazz: jClass[_]): jClass[_] = {
+ jArray.newInstance(elemClazz, 0).getClass
+ }
+
+ /** The Java class that corresponds to given Scala type.
+ * Pre: Scala type is already transformed to Java level.
+ */
+ def typeToJavaClass(tpe: Type): jClass[_] = tpe match {
+ case ExistentialType(_, rtpe) => typeToJavaClass(rtpe)
+ case TypeRef(_, ArrayClass, List(elemtpe)) => jArrayClass(typeToJavaClass(elemtpe))
+ case TypeRef(_, sym: ClassSymbol, _) => classToJava(sym.asClassSymbol)
+ case _ => throw new NoClassDefFoundError("no Java class corresponding to "+tpe+" found")
+ }
+ }
+
+ /** Assert that packages have package scopes */
+ override def validateClassInfo(tp: ClassInfoType) {
+ assert(!tp.typeSymbol.isPackageClass || tp.decls.isInstanceOf[PackageScope])
+ }
+
+ override def newPackageScope(pkgClass: Symbol) = new PackageScope(pkgClass)
+
+ override def scopeTransform(owner: Symbol)(op: => Scope): Scope =
+ if (owner.isPackageClass) owner.info.decls else op
+
+ private lazy val rootToLoader = new WeakHashMap[Symbol, ClassLoader]
+
+ override def mirrorThatLoaded(sym: Symbol): Mirror = {
+ val root = sym.enclosingRootClass
+ def findLoader = {
+ val loaders = (mirrors collect { case (cl, ref) if ref.get.get.RootClass == root => cl })
+ assert(loaders.nonEmpty, sym)
+ loaders.head
+ }
+ mirrors(rootToLoader getOrElseUpdate(root, findLoader)).get.get
+ }
+
+ private def byName(sym: Symbol): (Name, Symbol) = sym.name -> sym
+
+ private lazy val phantomTypes: Map[Name, Symbol] =
+ Map(byName(definitions.AnyRefClass)) ++ (definitions.isPhantomClass map byName)
+
+ /** 1. If `owner` is a package class (but not the empty package) and `name` is a term name, make a new package
+ * <owner>.<name>, otherwise return NoSymbol.
+ * Exception: If owner is root and a java class with given name exists, create symbol in empty package instead
+ * 2. If `owner` is the scala package and `name` designates a phantom class, return
+ * the corresponding class symbol and enter it into this mirror's ScalaPackage.
+ */
+ override def missingHook(owner: Symbol, name: Name): Symbol = {
+ if (owner.hasPackageFlag) {
+ val mirror = mirrorThatLoaded(owner)
+ // [Eugene++] this makes toolbox tests pass, but it's a mere workaround for SI-5865
+// assert((owner.info decl name) == NoSymbol, s"already exists: $owner . $name")
+ if (owner.isRootSymbol && mirror.tryJavaClass(name.toString).isDefined)
+ return mirror.EmptyPackageClass.info decl name
+ if (name.isTermName && !owner.isEmptyPackageClass)
+ return mirror.makeScalaPackage(
+ if (owner.isRootSymbol) name.toString else owner.fullName+"."+name)
+ if (owner.name.toTermName == nme.scala_ && owner.owner.isRoot)
+ phantomTypes get name match {
+ case Some(tsym) =>
+ owner.info.decls enter tsym
+ return tsym
+ case None =>
+ }
+ }
+ info("*** missing: "+name+"/"+name.isTermName+"/"+owner+"/"+owner.hasPackageFlag+"/"+owner.info.decls.getClass)
+ super.missingHook(owner, name)
+ }
+}
+
+class ReflectError(msg: String) extends java.lang.Error(msg)
+
+class HasJavaClass[J](val getClazz: J => java.lang.Class[_])
diff --git a/src/compiler/scala/reflect/runtime/JavaToScala.scala b/src/compiler/scala/reflect/runtime/JavaToScala.scala
deleted file mode 100644
index e11f6140c9..0000000000
--- a/src/compiler/scala/reflect/runtime/JavaToScala.scala
+++ /dev/null
@@ -1,697 +0,0 @@
-package scala.reflect
-package runtime
-
-import java.lang.{ Class => jClass, Package => jPackage, ClassLoader => JClassLoader }
-import java.io.IOException
-import java.lang.reflect.{
- Method => jMethod,
- Constructor => jConstructor,
- Modifier => jModifier,
- Field => jField,
- Member => jMember,
- Type => jType,
- TypeVariable => jTypeVariable,
- GenericDeclaration,
- GenericArrayType,
- ParameterizedType,
- WildcardType,
- AnnotatedElement
-}
-import internal.MissingRequirementError
-import internal.pickling.ByteCodecs
-import internal.ClassfileConstants._
-import internal.pickling.UnPickler
-import collection.mutable.{ HashMap, ListBuffer }
-import internal.Flags._
-import scala.tools.nsc.util.ScalaClassLoader
-import scala.tools.nsc.util.ScalaClassLoader._
-
-trait JavaToScala extends ConversionUtil { self: SymbolTable =>
-
- import definitions._
-
- private object unpickler extends UnPickler {
- val global: JavaToScala.this.type = self
- }
-
- /** Defines the classloader that will be used for all class resolution activities in this mirror.
- * Is mutable, since sometimes we need to change it in flight (e.g. to make the default mirror work with REPL).
- *
- * If you want to have a mirror with non-standard class resolution, override this var
- * (or, even simpler, use the `mkMirror` function from `scala.reflect` package)
- *
- * Be careful, though, since fancy stuff might happen.
- * Here's one example:
- *
- * partest uses a URLClassLoader(urls, null) with custom classpath to run workers (in separate threads)
- * however it doesn't set the context classloader for them, so they inherit the system classloader
- * http://www.javaworld.com/javaworld/javaqa/2003-06/01-qa-0606-load.html
- *
- * Once upon a time, scala.reflect.mirror was loaded using getClass.getClassLoader,
- * which also means that classOf[...] constructs such as:
- *
- * classOf[scala.reflect.ScalaSignature]
- *
- * in unpickleClass were also loaded by the URLClassLoader
- *
- * But mirror's classLoader used Thread.currentThread.getContextClassLoader,
- * which introduced a subtle bug that made the following snippet incorrectly:
- *
- * jclazz.getAnnotation(classOf[scala.reflect.ScalaSignature])
- *
- * Indeed, jclazz was loaded by context classloader, which defaulted to system classloader,
- * while ScalaSignature class was loaded by getClass.getClassLoader, which was incompatible with system classloader.
- * As a result, unpickler couldn't see the signature and that blew up the mirror.
- */
- var classLoader: ClassLoader
-
- /** Paul: It seems the default class loader does not pick up root classes, whereas the system classloader does.
- * Can you check with your newly acquired classloader fu whether this implementation makes sense?
- */
- def javaClass(path: String): jClass[_] =
- javaClass(path, classLoader)
- def javaClass(path: String, classLoader: JClassLoader): jClass[_] =
- Class.forName(path, true, classLoader)
-
- /** Does `path` correspond to a Java class with that fully qualified name? */
- def isJavaClass(path: String): Boolean =
- try {
- javaClass(path)
- true
- } catch {
- case (_: ClassNotFoundException) | (_: NoClassDefFoundError) | (_: IncompatibleClassChangeError) =>
- false
- }
-
- /**
- * Generate types for top-level Scala root class and root companion object
- * from the pickled information stored in a corresponding Java class
- * @param clazz The top-level Scala class for which info is unpickled
- * @param module The top-level Scala companion object for which info is unpickled
- * @param jclazz The Java class which contains the unpickled information in a
- * ScalaSignature or ScalaLongSignature annotation.
- */
- def unpickleClass(clazz: Symbol, module: Symbol, jclazz: jClass[_]): Unit = {
- def markAbsent(tpe: Type) = setAllInfos(clazz, module, tpe)
- def handleError(ex: Exception) = {
- markAbsent(ErrorType)
- if (settings.debug.value) ex.printStackTrace()
- val msg = ex.getMessage()
- MissingRequirementError.signal(
- (if (msg eq null) "reflection error while loading " + clazz.name
- else "error while loading " + clazz.name) + ", " + msg)
- }
- // don't use classOf[scala.reflect.ScalaSignature] here, because it will use getClass.getClassLoader, not mirror's classLoader
- // don't use asInstanceOf either because of the same reason (lol, I cannot believe I fell for it)
- // don't use structural types to simplify reflective invocations because of the same reason
- // todo. test for this
- def loadAnnotation(name: String): java.lang.annotation.Annotation = {
- def inferClasspath(cl: ClassLoader) = cl match {
- case cl: java.net.URLClassLoader => "[" + (cl.getURLs mkString ",") + "]"
- case _ => "<unknown>"
- }
- def show(cl: ClassLoader) = cl match {
- case cl if cl != null =>
- "%s of type %s with classpath %s".format(cl, cl.getClass, inferClasspath(cl))
- case null =>
- import scala.tools.util.PathResolver.Environment._
- "primordial classloader with boot classpath [%s]".format(javaBootClassPath)
- }
-
- try {
- val cls_ann = Class.forName(name, true, classLoader)
- val anns = jclazz.getAnnotations
- val ann = anns find (_.annotationType == cls_ann) orNull;
- if (ann == null && anns.find(_.annotationType.getName == name).isDefined) {
- val msg = "Mirror classloader mismatch: %s (loaded by %s)%nis unrelated to the mirror's classloader (%s)"
- throw new Error(msg.format(jclazz, show(jclazz.getClassLoader), show(classLoader)))
- }
- ann
- } catch {
- case ex: ClassNotFoundException =>
- val msg = "Dysfunctional mirror classloader, cannot load %s: %s."
- throw new Error(msg.format(name, show(classLoader)), ex)
- }
- }
- def loadScalaSignature: Option[String] = {
- val ssig = loadAnnotation("scala.reflect.ScalaSignature")
- if (ssig != null) {
- val bytesMethod = ssig.annotationType.getMethod("bytes")
- val result = bytesMethod.invoke(ssig)
- Some(result.asInstanceOf[String])
- } else {
- None
- }
- }
- def loadScalaLongSignature: Option[Array[String]] = {
- val slsig = loadAnnotation("scala.reflect.ScalaLongSignature")
- if (slsig != null) {
- val bytesMethod = slsig.annotationType.getMethod("bytes")
- val result = bytesMethod.invoke(slsig)
- Some(result.asInstanceOf[Array[String]])
- } else {
- None
- }
- }
- try {
- markAbsent(NoType)
- val sigs = (loadScalaSignature, loadScalaLongSignature)
- sigs match {
- case (Some(ssig), _) =>
- info("unpickling Scala "+clazz + " and " + module+ ", owner = " + clazz.owner)
- val bytes = ssig.getBytes
- val len = ByteCodecs.decode(bytes)
- unpickler.unpickle(bytes take len, 0, clazz, module, jclazz.getName)
- case (_, Some(slsig)) =>
- info("unpickling Scala "+clazz + " and " + module + " with long Scala signature")
- val byteSegments = slsig map (_.getBytes)
- val lens = byteSegments map ByteCodecs.decode
- val bytes = Array.ofDim[Byte](lens.sum)
- var len = 0
- for ((bs, l) <- byteSegments zip lens) {
- bs.copyToArray(bytes, len, l)
- len += l
- }
- unpickler.unpickle(bytes, 0, clazz, module, jclazz.getName)
- case (None, None) =>
- // class does not have a Scala signature; it's a Java class
- info("translating reflection info for Java " + jclazz) //debug
- initClassModule(clazz, module, new FromJavaClassCompleter(clazz, module, jclazz))
- }
- } catch {
- case ex: MissingRequirementError =>
- handleError(ex)
- case ex: IOException =>
- handleError(ex)
- }
- }
-
- /**
- * A fresh Scala type parameter that corresponds to a Java type variable.
- * The association between Scala type parameter and Java type variable is entered in the cache.
- * @param jtvar The Java type variable
- */
- private def createTypeParameter(jtvar: jTypeVariable[_ <: GenericDeclaration]): Symbol = {
- val tparam = sOwner(jtvar).newTypeParameter(newTypeName(jtvar.getName))
- .setInfo(new TypeParamCompleter(jtvar))
- tparamCache enter (jtvar, tparam)
- tparam
- }
-
- /**
- * A completer that fills in the type of a Scala type parameter from the bounds of a Java type variable.
- * @param jtvar The Java type variable
- */
- private class TypeParamCompleter(jtvar: jTypeVariable[_ <: GenericDeclaration]) extends LazyType {
- override def load(sym: Symbol) = complete(sym)
- override def complete(sym: Symbol) = {
- sym setInfo TypeBounds.upper(glb(jtvar.getBounds.toList map typeToScala map objToAny))
- }
- }
-
- /**
- * Copy all annotations of Java annotated element `jann` over to Scala symbol `sym`.
- * Pre: `sym` is already initialized with a concrete type.
- * Note: If `sym` is a method or constructor, its parameter annotations are copied as well.
- */
- private def copyAnnotations(sym: Symbol, jann: AnnotatedElement) {
- // to do: implement
- }
-
- /**
- * A completer that fills in the types of a Scala class and its companion object
- * by copying corresponding type info from a Java class. This completer is used
- * to reflect classes in Scala that do not have a Scala pickle info, be it
- * because they are local classes or have been compiled from Java sources.
- * @param clazz The Scala class for which info is copied
- * @param module The Scala companion object for which info is copied
- * @param jclazz The Java class
- */
- private class FromJavaClassCompleter(clazz: Symbol, module: Symbol, jclazz: jClass[_]) extends LazyType {
- override def load(sym: Symbol) = {
- debugInfo("completing from Java " + sym + "/" + clazz.fullName)//debug
- assert(sym == clazz || (module != NoSymbol && (sym == module || sym == module.moduleClass)), sym)
- val flags = toScalaClassFlags(jclazz.getModifiers)
- clazz setFlag (flags | JAVA)
- if (module != NoSymbol) {
- module setFlag (flags & PRIVATE | JAVA)
- module.moduleClass setFlag (flags & PRIVATE | JAVA)
- }
-
- copyAnnotations(clazz, jclazz)
- // to do: annotations to set also for module?
-
- clazz setInfo new LazyPolyType(jclazz.getTypeParameters.toList map createTypeParameter)
- if (module != NoSymbol) {
- module setInfo module.moduleClass.tpe
- module.moduleClass setInfo new LazyPolyType(List())
- }
- }
-
- override def complete(sym: Symbol): Unit = {
- load(sym)
- completeRest()
- }
- def completeRest(): Unit = self.synchronized {
- val tparams = clazz.rawInfo.typeParams
-
- val parents = try {
- parentsLevel += 1
- val jsuperclazz = jclazz.getGenericSuperclass
- val superclazz = if (jsuperclazz == null) AnyClass.tpe else typeToScala(jsuperclazz)
- superclazz :: (jclazz.getGenericInterfaces.toList map typeToScala)
- } finally {
- parentsLevel -= 1
- }
- clazz setInfo GenPolyType(tparams, new ClassInfoType(parents, newScope, clazz))
- if (module != NoSymbol) {
- module.moduleClass setInfo new ClassInfoType(List(), newScope, module.moduleClass)
- }
-
- def enter(sym: Symbol, mods: Int) =
- (if (jModifier.isStatic(mods)) module.moduleClass else clazz).info.decls enter sym
-
- for (jinner <- jclazz.getDeclaredClasses) {
- enter(jclassAsScala(jinner, clazz), jinner.getModifiers)
- }
-
- pendingLoadActions = { () =>
-
- for (jfield <- jclazz.getDeclaredFields)
- enter(jfieldAsScala(jfield), jfield.getModifiers)
-
- for (jmeth <- jclazz.getDeclaredMethods)
- enter(jmethodAsScala(jmeth), jmeth.getModifiers)
-
- for (jconstr <- jclazz.getConstructors)
- enter(jconstrAsScala(jconstr), jconstr.getModifiers)
-
- } :: pendingLoadActions
-
- if (parentsLevel == 0) {
- while (!pendingLoadActions.isEmpty) {
- val item = pendingLoadActions.head
- pendingLoadActions = pendingLoadActions.tail
- item()
- }
- }
- }
- class LazyPolyType(override val typeParams: List[Symbol]) extends LazyType {
- override def complete(sym: Symbol) {
- completeRest()
- }
- }
- }
-
- /** used to avoid cyclies */
- var parentsLevel = 0
- var pendingLoadActions: List[() => Unit] = Nil
-
- /**
- * If Java modifiers `mods` contain STATIC, return the module class
- * of the companion module of `clazz`, otherwise the class `clazz` itself.
- */
- private def followStatic(clazz: Symbol, mods: Int) =
- if (jModifier.isStatic(mods)) clazz.companionModule.moduleClass else clazz
-
- /** Methods which need to be wrapped because they either are getSimpleName
- * or call getSimpleName:
- *
- * public String getSimpleName()
- * public boolean isAnonymousClass()
- * public boolean isLocalClass()
- * public boolean isMemberClass()
- * public String getCanonicalName()
- *
- * TODO - find all such calls and wrap them.
- * TODO - create mechanism to avoid the recurrence of unwrapped calls.
- */
- private def wrapClassCheck[T](alt: T)(body: => T): T =
- try body catch { case x: InternalError if x.getMessage == "Malformed class name" => alt }
-
- private def wrapIsLocalClass(clazz: jClass[_]): Boolean =
- wrapClassCheck(false)(clazz.isLocalClass)
-
- private def wrapGetSimpleName(clazz: jClass[_]): String =
- wrapClassCheck("")(clazz.getSimpleName)
-
- /**
- * The Scala owner of the Scala class corresponding to the Java class `jclazz`
- */
- private def sOwner(jclazz: jClass[_]): Symbol = {
- if (jclazz.isMemberClass) {
- val jEnclosingClass = jclazz.getEnclosingClass
- val sEnclosingClass = classToScala(jEnclosingClass)
- followStatic(sEnclosingClass, jclazz.getModifiers)
- } else if (wrapIsLocalClass(jclazz)) {
- val jEnclosingMethod = jclazz.getEnclosingMethod
- if (jEnclosingMethod != null) {
- methodToScala(jEnclosingMethod)
- } else {
- val jEnclosingConstructor = jclazz.getEnclosingConstructor
- constrToScala(jEnclosingConstructor)
- }
- } else if (jclazz.isPrimitive || jclazz.isArray) {
- ScalaPackageClass
- } else if (jclazz.getPackage != null) {
- val jPackage = jclazz.getPackage
- packageToScala(jPackage)
- } else {
- // @eb: a weird classloader might return a null package for something with a non-empty package name
- // for example, http://groups.google.com/group/scala-internals/browse_thread/thread/7be09ff8f67a1e5c
- // in that case we could invoke packageNameToScala(jPackageName) and, probably, be okay
- // however, I think, it's better to blow up, since weirdness of the class loader might bite us elsewhere
- val jPackageName = jclazz.getName.substring(0, Math.max(jclazz.getName.lastIndexOf("."), 0))
- assert(jPackageName == "")
- EmptyPackageClass
- }
- }
-
- /**
- * The Scala owner of the Scala symbol corresponding to the Java member `jmember`
- */
- private def sOwner(jmember: jMember): Symbol = {
- followStatic(classToScala(jmember.getDeclaringClass), jmember.getModifiers)
- }
-
- /**
- * The Scala owner of the Scala type parameter corresponding to the Java type variable `jtvar`
- */
- private def sOwner(jtvar: jTypeVariable[_ <: GenericDeclaration]): Symbol =
- genericDeclarationToScala(jtvar.getGenericDeclaration)
-
- /**
- * Returns `true` if Scala name `name` equals Java name `jstr`, possibly after
- * make-not-private expansion.
- */
- private def approximateMatch(sym: Symbol, jstr: String): Boolean =
- (sym.name.toString == jstr) ||
- sym.isPrivate && nme.expandedName(sym.name.toTermName, sym.owner).toString == jstr
-
- /**
- * Find declarations or definition in class `clazz` that maps to a Java
- * entity with name `jname`. Because of name-mangling, this is more difficult
- * than a simple name-based lookup via `decl`. If `decl` fails, members
- * that start with the given name are searched instead.
- */
- private def lookup(clazz: Symbol, jname: String): Symbol =
- clazz.info.decl(newTermName(jname)) orElse {
- (clazz.info.decls.iterator filter (approximateMatch(_, jname))).toList match {
- case List() => NoSymbol
- case List(sym) => sym
- case alts => clazz.newOverloaded(alts.head.tpe.prefix, alts)
- }
- }
-
- /**
- * The Scala method corresponding to given Java method.
- * @param jmeth The Java method
- * @return A Scala method object that corresponds to `jmeth`.
- */
- def methodToScala(jmeth: jMethod): Symbol = methodCache.toScala(jmeth) {
- val jOwner = jmeth.getDeclaringClass
- var sOwner = classToScala(jOwner)
- sOwner = followStatic(sOwner, jmeth.getModifiers)
- lookup(sOwner, jmeth.getName) suchThat (erasesTo(_, jmeth)) orElse jmethodAsScala(jmeth)
- }
-
- /**
- * The Scala constructor corresponding to given Java constructor.
- * @param jconstr The Java constructor
- * @return A Scala method object that corresponds to `jconstr`.
- */
- def constrToScala(jconstr: jConstructor[_]): Symbol = constructorCache.toScala(jconstr) {
- val owner = followStatic(classToScala(jconstr.getDeclaringClass), jconstr.getModifiers)
- lookup(owner, "<init>") suchThat (erasesTo(_, jconstr)) orElse jconstrAsScala(jconstr)
- }
-
- /**
- * The Scala package corresponding to given Java package
- */
- def packageToScala(jpkg: jPackage): Symbol = packageCache.toScala(jpkg) {
- makeScalaPackage(jpkg.getName)
- }
-
- /**
- * The Scala package with given fully qualified name.
- */
- def packageNameToScala(fullname: String): Symbol = {
- val jpkg = jPackage.getPackage(fullname)
- if (jpkg != null) packageToScala(jpkg) else makeScalaPackage(fullname)
- }
-
- /**
- * The Scala package with given fully qualified name. Unlike `packageNameToScala`,
- * this one bypasses the cache.
- */
- def makeScalaPackage(fullname: String): Symbol = {
- val split = fullname lastIndexOf '.'
- val owner = if (split > 0) packageNameToScala(fullname take split) else RootClass
- assert(owner.isModuleClass, owner+" when making "+fullname)
- val name = newTermName(fullname drop (split + 1))
- var pkg = owner.info decl name
- if (pkg == NoSymbol) {
- pkg = owner.newPackage(name)
- pkg.moduleClass setInfo new LazyPackageType
- pkg setInfoAndEnter pkg.moduleClass.tpe
- info("made Scala "+pkg)
- } else if (!pkg.isPackage)
- throw new ReflectError(pkg+" is not a package")
- pkg.moduleClass
- }
-
- private def scalaSimpleName(jclazz: jClass[_]): TypeName = {
- val owner = sOwner(jclazz)
- val enclosingClass = jclazz.getEnclosingClass
- var prefix = if (enclosingClass != null) enclosingClass.getName else ""
- val isObject = owner.isModuleClass && !owner.isPackageClass
- if (isObject && !prefix.endsWith(nme.MODULE_SUFFIX_STRING)) prefix += nme.MODULE_SUFFIX_STRING
- assert(jclazz.getName.startsWith(prefix))
- var name = jclazz.getName.substring(prefix.length)
- name = name.substring(name.lastIndexOf(".") + 1)
- newTypeName(name)
- }
-
- /**
- * The Scala class that corresponds to a given Java class.
- * @param jclazz The Java class
- * @return A Scala class symbol that reflects all elements of the Java class,
- * in the form they appear in the Scala pickling info, or, if that is
- * not available, wrapped from the Java reflection info.
- */
- def classToScala(jclazz: jClass[_]): Symbol = classCache.toScala(jclazz) {
- val jname = javaTypeName(jclazz)
-
- val sym =
- if (jname == fulltpnme.RuntimeNothing)
- NothingClass
- else if (jname == fulltpnme.RuntimeNull)
- NullClass
- else
- {
- val owner = sOwner(jclazz)
- val simpleName = scalaSimpleName(jclazz)
-
- def lookup = {
- def coreLookup(name: Name): Symbol = {
- val sym = owner.info.decl(name)
- sym orElse {
- if (name.startsWith(nme.NAME_JOIN_STRING))
- coreLookup(name.subName(1, name.length))
- else
- NoSymbol
- }
- }
-
- if (nme.isModuleName(simpleName)) {
- val moduleName = nme.stripModuleSuffix(simpleName).toTermName
- val sym = coreLookup(moduleName)
- if (sym == NoSymbol) sym else sym.moduleClass
- } else {
- coreLookup(simpleName)
- }
- }
-
- val sym = {
- if (jclazz.isMemberClass && !nme.isImplClassName(jname)) {
- lookup
- } else if (wrapIsLocalClass(jclazz) || invalidClassName(jname)) {
- // local classes and implementation classes not preserved by unpickling - treat as Java
- jclassAsScala(jclazz)
- } else if (jclazz.isArray) {
- ArrayClass
- } else javaTypeToValueClass(jclazz) orElse {
- // jclazz is top-level - get signature
- lookup
- // val (clazz, module) = createClassModule(
- // sOwner(jclazz), newTypeName(jclazz.getSimpleName), new TopClassCompleter(_, _))
- // classCache enter (jclazz, clazz)
- // clazz
- }
- }
-
- if (!sym.isType) {
- val classloader = jclazz.getClassLoader
- println("classloader is: %s of type %s".format(classloader, classloader.getClass))
- def inferClasspath(cl: ClassLoader) = cl match {
- case cl: java.net.URLClassLoader => "[" + (cl.getURLs mkString ",") + "]"
- case _ => "<unknown>"
- }
- println("classpath is: %s".format(inferClasspath(classloader)))
- def msgNoSym = "no symbol could be loaded from %s (scala equivalent is %s) by name %s".format(owner, jclazz, simpleName)
- def msgIsNotType = "not a type: symbol %s loaded from %s (scala equivalent is %s) by name %s".format(sym, owner, jclazz, simpleName)
- assert(false, if (sym == NoSymbol) msgNoSym else msgIsNotType)
- }
-
- sym
- }
-
- sym.asInstanceOf[ClassSymbol]
- }
-
- /**
- * The Scala type parameter that corresponds to a given Java type parameter.
- * @param jparam The Java type parameter
- * @return A Scala type parameter symbol that has the same owner and name as the Java type parameter
- */
- def tparamToScala(jparam: jTypeVariable[_ <: GenericDeclaration]): Symbol = tparamCache.toScala(jparam) {
- val owner = genericDeclarationToScala(jparam.getGenericDeclaration)
- owner.info match {
- case PolyType(tparams, _) => tparams.find(_.name.toString == jparam.getName).get
- }
- }
-
- /**
- * The Scala symbol that corresponds to a given Java generic declaration (class, method, or constructor)
- */
- def genericDeclarationToScala(jdecl: GenericDeclaration) = jdecl match {
- case jclazz: jClass[_] => classToScala(jclazz)
- case jmeth: jMethod => methodToScala(jmeth)
- case jconstr: jConstructor[_] => constrToScala(jconstr)
- }
-
- /**
- * Given some Java type arguments, a corresponding list of Scala types, plus potentially
- * some existentially bound type variables that represent wildcard arguments.
- */
- private def targsToScala(owner: Symbol, args: List[jType]): (List[Type], List[Symbol]) = {
- val tparams = new ListBuffer[Symbol]
- def targToScala(arg: jType): Type = arg match {
- case jwild: WildcardType =>
- val tparam = owner.newExistential(newTypeName("T$" + tparams.length))
- .setInfo(TypeBounds(
- lub(jwild.getLowerBounds.toList map typeToScala),
- glb(jwild.getUpperBounds.toList map typeToScala map objToAny)))
- tparams += tparam
- typeRef(NoPrefix, tparam, List())
- case _ =>
- typeToScala(arg)
- }
- (args map targToScala, tparams.toList)
- }
-
- /**
- * The Scala type that corresponds to given Java type
- */
- def typeToScala(jtpe: jType): Type = jtpe match {
- case jclazz: jClass[_] =>
- if (jclazz.isArray)
- arrayType(typeToScala(jclazz.getComponentType))
- else {
- val clazz = classToScala(jclazz)
- rawToExistential(typeRef(clazz.owner.thisType, clazz, List()))
- }
- case japplied: ParameterizedType =>
- val (pre, sym) = typeToScala(japplied.getRawType) match {
- case ExistentialType(tparams, TypeRef(pre, sym, _)) => (pre, sym)
- case TypeRef(pre, sym, _) => (pre, sym)
- }
- val args0 = japplied.getActualTypeArguments
- val (args, bounds) = targsToScala(pre.typeSymbol, args0.toList)
- ExistentialType(bounds, typeRef(pre, sym, args))
- case jarr: GenericArrayType =>
- arrayType(typeToScala(jarr.getGenericComponentType))
- case jtvar: jTypeVariable[_] =>
- val tparam = tparamToScala(jtvar)
- typeRef(NoPrefix, tparam, List())
- }
-
- /**
- * The Scala class that corresponds to given Java class without taking
- * Scala pickling info into account.
- * @param jclazz The Java class
- * @return A Scala class symbol that wraps all reflection info of `jclazz`
- */
- private def jclassAsScala(jclazz: jClass[_]): Symbol = jclassAsScala(jclazz, sOwner(jclazz))
-
- private def jclassAsScala(jclazz: jClass[_], owner: Symbol): Symbol = {
- val name = scalaSimpleName(jclazz)
- val completer = (clazz: Symbol, module: Symbol) => new FromJavaClassCompleter(clazz, module, jclazz)
- val (clazz, module) = createClassModule(owner, name, completer)
- classCache enter (jclazz, clazz)
- clazz
- }
-
- /**
- * The Scala field that corresponds to given Java field without taking
- * Scala pickling info into account.
- * @param jfield The Java field
- * @return A Scala value symbol that wraps all reflection info of `jfield`
- */
- private def jfieldAsScala(jfield: jField): Symbol = fieldCache.toScala(jfield) {
- val field = (
- sOwner(jfield)
- newValue(newTermName(jfield.getName), NoPosition, toScalaFieldFlags(jfield.getModifiers))
- setInfo typeToScala(jfield.getGenericType)
- )
- fieldCache enter (jfield, field)
- copyAnnotations(field, jfield)
- field
- }
-
- private def setMethType(meth: Symbol, tparams: List[Symbol], paramtpes: List[Type], restpe: Type) = {
- meth setInfo GenPolyType(tparams, MethodType(meth.owner.newSyntheticValueParams(paramtpes map objToAny), restpe))
- }
-
- /**
- * The Scala method that corresponds to given Java method without taking
- * Scala pickling info into account.
- * @param jmeth The Java method
- * @return A Scala method symbol that wraps all reflection info of `jmethod`
- */
- private def jmethodAsScala(jmeth: jMethod): Symbol = methodCache.toScala(jmeth) {
- val clazz = sOwner(jmeth)
- val meth = clazz.newMethod(newTermName(jmeth.getName), NoPosition, toScalaMethodFlags(jmeth.getModifiers))
- methodCache enter (jmeth, meth)
- val tparams = jmeth.getTypeParameters.toList map createTypeParameter
- val paramtpes = jmeth.getGenericParameterTypes.toList map typeToScala
- val resulttpe = typeToScala(jmeth.getGenericReturnType)
- setMethType(meth, tparams, paramtpes, resulttpe)
- copyAnnotations(meth, jmeth)
- if ((jmeth.getModifiers & JAVA_ACC_VARARGS) != 0) {
- meth.setInfo(arrayToRepeated(meth.info))
- }
- meth
- }
-
- /**
- * The Scala constructor that corresponds to given Java constructor without taking
- * Scala pickling info into account.
- * @param jconstr The Java constructor
- * @return A Scala constructor symbol that wraps all reflection info of `jconstr`
- */
- private def jconstrAsScala(jconstr: jConstructor[_]): Symbol = {
- // [Martin] Note: I know there's a lot of duplication wrt jmethodAsScala, but don't think it's worth it to factor this out.
- val clazz = sOwner(jconstr)
- val constr = clazz.newConstructor(NoPosition, toScalaMethodFlags(jconstr.getModifiers))
- constructorCache enter (jconstr, constr)
- val tparams = jconstr.getTypeParameters.toList map createTypeParameter
- val paramtpes = jconstr.getGenericParameterTypes.toList map typeToScala
- setMethType(constr, tparams, paramtpes, clazz.tpe)
- constr setInfo GenPolyType(tparams, MethodType(clazz.newSyntheticValueParams(paramtpes), clazz.tpe))
- copyAnnotations(constr, jconstr)
- constr
- }
-}
-
-class ReflectError(msg: String) extends java.lang.Error(msg)
diff --git a/src/compiler/scala/reflect/runtime/JavaUniverse.scala b/src/compiler/scala/reflect/runtime/JavaUniverse.scala
new file mode 100644
index 0000000000..9dcf8786c5
--- /dev/null
+++ b/src/compiler/scala/reflect/runtime/JavaUniverse.scala
@@ -0,0 +1,33 @@
+package scala.reflect
+package runtime
+
+import internal.{SomePhase, NoPhase, Phase, TreeGen}
+
+/** The universe for standard runtime reflection from Java.
+ * This type implements all abstract term members in internal.SymbolTable.
+ */
+class JavaUniverse extends internal.SymbolTable with ReflectSetup with runtime.SymbolTable { self =>
+
+ type AbstractFileType = AbstractFile
+
+ def picklerPhase = SomePhase
+
+ type TreeGen = internal.TreeGen
+
+ override type Position = scala.tools.nsc.util.Position
+
+ override val gen = new TreeGen { val global: self.type = self }
+
+ lazy val settings = new Settings
+ def forInteractive = false
+ def forScaladoc = false
+
+ def log(msg: => AnyRef): Unit = println(" [] "+msg)
+
+ type TreeCopier = TreeCopierOps
+ def newStrictTreeCopier: TreeCopier = new StrictTreeCopier
+ def newLazyTreeCopier: TreeCopier = new LazyTreeCopier
+
+ init()
+}
+
diff --git a/src/compiler/scala/reflect/runtime/Mirror.scala b/src/compiler/scala/reflect/runtime/Mirror.scala
deleted file mode 100644
index bf4bc83bea..0000000000
--- a/src/compiler/scala/reflect/runtime/Mirror.scala
+++ /dev/null
@@ -1,85 +0,0 @@
-package scala.reflect
-package runtime
-
-import java.lang.reflect.Array
-import ReflectionUtils._
-import scala.tools.nsc.util.ScalaClassLoader._
-
-/** The mirror for standard runtime reflection from Java.
- */
-class Mirror(var classLoader: ClassLoader) extends Universe with api.Mirror {
-
- definitions.init()
- import definitions._
-
- def symbolForName(name: String): Symbol = {
- val clazz = javaClass(name, classLoader)
- classToScala(clazz)
- }
-
- def companionInstance(clazz: Symbol): AnyRef = {
- val singleton = singletonInstance(classLoader, clazz.fullName)
- singleton
- }
-
- 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 : ClassTag](x: T): Symbol = classTag[T].sym
-
- def getValueOfField(receiver: AnyRef, field: Symbol): Any = {
- fieldToJava(field).get(receiver)
- }
- def setValueOfField(receiver: AnyRef, field: Symbol, value: Any): Unit = {
- fieldToJava(field).set(receiver, value)
- }
- def invoke(receiver: AnyRef, meth: Symbol)(args: Any*): Any = {
- if (meth.owner == ArrayClass) {
- meth.name match {
- case nme.length => return Array.getLength(receiver)
- case nme.apply => return Array.get(receiver, args(0).asInstanceOf[Int])
- case nme.update => return Array.set(receiver, args(0).asInstanceOf[Int], args(1))
- }
- }
-
- val jmeth = methodToJava(meth)
- jmeth.invoke(receiver, args.asInstanceOf[Seq[AnyRef]]: _*)
- }
-
- private def validateIncomingClassLoader(wannabeCl: ClassLoader) = {
- val ourCls = loaderChain(classLoader)
- if (wannabeCl != null && !(ourCls contains wannabeCl))
- throw new Error("class doesn't belong to the classloader chain of the mirror")
- }
-
- def classToType(jclazz: java.lang.Class[_]): Type = {
- validateIncomingClassLoader(jclazz.getClassLoader)
- typeToScala(jclazz)
- }
-
- def classToSymbol(jclazz: java.lang.Class[_]): Symbol = {
- validateIncomingClassLoader(jclazz.getClassLoader)
- classToScala(jclazz)
- }
-
- def typeToClass(tpe: Type): java.lang.Class[_] =
- typeToJavaClass(tpe)
-
- def symbolToClass(sym: Symbol): java.lang.Class[_] =
- classToJava(sym)
-
- override def inReflexiveMirror = true
-}
-
-/** test code; should go to tests once things settle down a bit
- *
-
-object Test extends Mirror with App {
- val sym = classToScala(classOf[scala.collection.Iterable[_]])
- println(sym)
- println("parents = "+sym.info.parents)
- println("decls = "+(sym.info.decls.toList map (_.defString)))
- val ms = sym.info.members.toList map (_.initialize)
- println("members = "+(ms map (_.defString) mkString ("\n ")))
-}
-*/ \ No newline at end of file
diff --git a/src/compiler/scala/reflect/runtime/ReflectSetup.scala b/src/compiler/scala/reflect/runtime/ReflectSetup.scala
new file mode 100644
index 0000000000..6e28fc8520
--- /dev/null
+++ b/src/compiler/scala/reflect/runtime/ReflectSetup.scala
@@ -0,0 +1,12 @@
+package scala.reflect
+package runtime
+
+import internal.{SomePhase, NoPhase, Phase, TreeGen}
+
+/** A helper trait to initialize things that need to be set before JavaMirrors and other
+ * reflect specific traits are initialized */
+private[runtime] trait ReflectSetup extends internal.SymbolTable {
+ override val phaseWithId: Array[Phase] = Array(NoPhase, SomePhase)
+ override val currentRunId = 1 // fake a run id so that it is different from NoRunId
+ phase = SomePhase // set to a phase different from NoPhase
+}
diff --git a/src/compiler/scala/reflect/runtime/ReflectionUtils.scala b/src/compiler/scala/reflect/runtime/ReflectionUtils.scala
new file mode 100644
index 0000000000..4e82fe8ad2
--- /dev/null
+++ b/src/compiler/scala/reflect/runtime/ReflectionUtils.scala
@@ -0,0 +1,80 @@
+/* NSC -- new Scala compiler
+ * Copyright 2005-2011 LAMP/EPFL
+ * @author Paul Phillips
+ */
+
+package scala.reflect.runtime
+
+import java.lang.{Class => jClass}
+import java.lang.reflect.{ InvocationTargetException, UndeclaredThrowableException }
+
+/** A few java-reflection oriented utility functions useful during reflection bootstrapping.
+ */
+object ReflectionUtils {
+ // Unwraps some chained exceptions which arise during reflective calls.
+ def unwrapThrowable(x: Throwable): Throwable = x match {
+ case _: InvocationTargetException | // thrown by reflectively invoked method or constructor
+ _: ExceptionInInitializerError | // thrown when running a static initializer (e.g. a scala module constructor)
+ _: UndeclaredThrowableException | // invocation on a proxy instance if its invocation handler's `invoke` throws an exception
+ _: ClassNotFoundException | // no definition for a class instantiated by name
+ _: NoClassDefFoundError // the definition existed when the executing class was compiled, but can no longer be found
+ if x.getCause != null =>
+ unwrapThrowable(x.getCause)
+ case _ => x
+ }
+ // Transforms an exception handler into one which will only receive the unwrapped
+ // exceptions (for the values of wrap covered in unwrapThrowable.)
+ def unwrapHandler[T](pf: PartialFunction[Throwable, T]): PartialFunction[Throwable, T] = {
+ case ex if pf isDefinedAt unwrapThrowable(ex) => pf(unwrapThrowable(ex))
+ }
+
+ private def systemProperties: Iterator[(String, String)] = {
+ import scala.collection.JavaConverters._
+ System.getProperties.asScala.iterator
+ }
+
+ private def inferBootClasspath: String = (
+ systemProperties find (_._1 endsWith ".boot.class.path") map (_._2) getOrElse ""
+ )
+
+ def show(cl: ClassLoader) = {
+ def inferClasspath(cl: ClassLoader): String = cl match {
+ case cl: java.net.URLClassLoader =>
+ "[" + (cl.getURLs mkString ",") + "]"
+ case cl if cl != null && cl.getClass.getName == "scala.tools.nsc.interpreter.AbstractFileClassLoader" =>
+ "[" + cl.asInstanceOf[{val root: scala.reflect.internal.AbstractFileApi}].root + "] and " + inferClasspath(cl.getParent)
+ case null =>
+ inferBootClasspath
+ case _ =>
+ "<unknown>"
+ }
+ cl match {
+ case cl if cl != null =>
+ "%s of type %s with classpath %s".format(cl, cl.getClass, inferClasspath(cl))
+ case null =>
+ "primordial classloader with boot classpath [%s]".format(inferClasspath(cl))
+ }
+ }
+
+ def singletonInstance(cl: ClassLoader, className: String): AnyRef = {
+ val name = if (className endsWith "$") className else className + "$"
+ val clazz = java.lang.Class.forName(name, true, cl)
+ val singleton = clazz getField "MODULE$" get null
+ singleton
+ }
+
+ // Retrieves the MODULE$ field for the given class name.
+ def singletonInstanceOpt(cl: ClassLoader, className: String): Option[AnyRef] =
+ try Some(singletonInstance(cl, className))
+ catch { case _: ClassNotFoundException => None }
+
+ def invokeFactory(cl: ClassLoader, className: String, methodName: String, args: AnyRef*): AnyRef = {
+ val singleton = singletonInstance(cl, className)
+ val method = singleton.getClass.getMethod(methodName, classOf[ClassLoader])
+ method.invoke(singleton, args: _*)
+ }
+
+ def invokeFactoryOpt(cl: ClassLoader, className: String, methodName: String, args: AnyRef*): Option[AnyRef] =
+ try Some(invokeFactory(cl, className, methodName, args: _*))
+ catch { case _: ClassNotFoundException => None }
+}
diff --git a/src/compiler/scala/reflect/runtime/ScalaToJava.scala b/src/compiler/scala/reflect/runtime/ScalaToJava.scala
deleted file mode 100644
index 87cdd11652..0000000000
--- a/src/compiler/scala/reflect/runtime/ScalaToJava.scala
+++ /dev/null
@@ -1,87 +0,0 @@
-package scala.reflect
-package runtime
-
-import java.lang.{Class => jClass, Package => jPackage}
-import java.lang.reflect.{
- Method => jMethod, Constructor => jConstructor, Modifier => jModifier, Field => jField,
- Member => jMember, Type => jType, Array => jArray, GenericDeclaration}
-
-trait ScalaToJava extends ConversionUtil { self: SymbolTable =>
-
- import definitions._
-
- /** Optionally, the Java package corresponding to a given Scala package, or None if no such Java package exists.
- * @param pkg The Scala package
- */
- def packageToJava(pkg: Symbol): Option[jPackage] = packageCache.toJavaOption(pkg) {
- Option(jPackage.getPackage(pkg.fullName.toString))
- }
-
- /** The Java class corresponding to given Scala class.
- * Note: This only works for
- * - top-level classes
- * - Scala classes that were generated via jclassToScala
- * - classes that have a class owner that has a corresponding Java class
- * @throws A `ClassNotFoundException` for all Scala classes not in one of these categories.
- */
- @throws(classOf[ClassNotFoundException])
- def classToJava(clazz: Symbol): jClass[_] = classCache.toJava(clazz) {
- def noClass = throw new ClassNotFoundException("no Java class corresponding to "+clazz+" found")
- //println("classToJava "+clazz+" "+clazz.owner+" "+clazz.owner.isPackageClass)//debug
- if (clazz.isPrimitiveValueClass)
- valueClassToJavaType(clazz)
- else if (clazz == ArrayClass)
- noClass
- else if (clazz.owner.isPackageClass)
- javaClass(clazz.javaClassName)
- else if (clazz.owner.isClass)
- classToJava(clazz.owner)
- .getDeclaredClasses
- .find(_.getSimpleName == clazz.name.toString)
- .getOrElse(noClass)
- else
- noClass
- }
-
- private def expandedName(sym: Symbol): String =
- if (sym.isPrivate) nme.expandedName(sym.name.toTermName, sym.owner).toString
- else sym.name.toString
-
- def fieldToJava(fld: Symbol): jField = fieldCache.toJava(fld) {
- val jclazz = classToJava(fld.owner)
- try jclazz getDeclaredField fld.name.toString
- catch {
- case ex: NoSuchFieldException => jclazz getDeclaredField expandedName(fld)
- }
- }
-
- def methodToJava(meth: Symbol): jMethod = methodCache.toJava(meth) {
- val jclazz = classToJava(meth.owner)
- val paramClasses = transformedType(meth).paramTypes map typeToJavaClass
- try jclazz getDeclaredMethod (meth.name.toString, paramClasses: _*)
- catch {
- case ex: NoSuchMethodException =>
- jclazz getDeclaredMethod (expandedName(meth), paramClasses: _*)
- }
- }
-
- def constrToJava(constr: Symbol): jConstructor[_] = constructorCache.toJava(constr) {
- val jclazz = classToJava(constr.owner)
- val paramClasses = transformedType(constr).paramTypes map typeToJavaClass
- jclazz getConstructor (paramClasses: _*)
- }
-
- private def jArrayClass(elemClazz: jClass[_]): jClass[_] = {
- jArray.newInstance(elemClazz, 0).getClass
- }
-
- /** The Java class that corresponds to given Scala type.
- * Pre: Scala type is already transformed to Java level.
- */
- def typeToJavaClass(tpe: Type): jClass[_] = tpe match {
- case ExistentialType(_, rtpe) => typeToJavaClass(rtpe)
- case TypeRef(_, ArrayClass, List(elemtpe)) => jArrayClass(typeToJavaClass(elemtpe))
- case TypeRef(_, sym, _) => classToJava(sym)
- case _ => throw new NoClassDefFoundError("no Java class corresponding to "+tpe+" found")
- }
-} \ No newline at end of file
diff --git a/src/compiler/scala/reflect/runtime/SymbolLoaders.scala b/src/compiler/scala/reflect/runtime/SymbolLoaders.scala
index 7c1cc16152..c1cd5d2911 100644
--- a/src/compiler/scala/reflect/runtime/SymbolLoaders.scala
+++ b/src/compiler/scala/reflect/runtime/SymbolLoaders.scala
@@ -7,12 +7,6 @@ import collection.mutable
trait SymbolLoaders { self: SymbolTable =>
- /** The lazy type for root.
- */
- override val rootLoader = new LazyType {
- override def complete(sym: Symbol) = sym setInfo new LazyPackageType
- }
-
/** The standard completer for top-level classes
* @param clazz The top-level class
* @param module The companion object of `clazz`
@@ -35,7 +29,9 @@ trait SymbolLoaders { self: SymbolTable =>
assert(sym == clazz || sym == module || sym == module.moduleClass)
// try {
atPhaseNotLaterThan(picklerPhase) {
- unpickleClass(clazz, module, javaClass(clazz.javaClassName))
+ val loadingMirror = mirrorThatLoaded(sym)
+ val javaClass = loadingMirror.javaClass(clazz.javaClassName)
+ loadingMirror.unpickleClass(clazz, module, javaClass)
// } catch {
// case ex: ClassNotFoundException => makePackage()
// case ex: NoClassDefFoundError => makePackage()
@@ -65,8 +61,14 @@ trait SymbolLoaders { self: SymbolTable =>
assert(!(name.toString endsWith "[]"), name)
val clazz = owner.newClass(name)
val module = owner.newModule(name.toTermName)
- owner.info.decls enter clazz
- owner.info.decls enter module
+ // [Eugene++] am I doing this right?
+ // todo: drop condition, see what goes wrong
+ // [Eugene++ to Martin] test/files/run/t5256g and test/files/run/t5256h will crash
+ // reflection meeting verdict: need to enter the symbols into the first symbol in the owner chain that has a non-empty scope
+ if (owner.info.decls != EmptyScope) {
+ owner.info.decls enter clazz
+ owner.info.decls enter module
+ }
initClassModule(clazz, module, completer(clazz, module))
(clazz, module)
}
@@ -92,7 +94,7 @@ trait SymbolLoaders { self: SymbolTable =>
/** Is the given name valid for a top-level class? We exclude names with embedded $-signs, because
* these are nested classes or anonymous classes,
*/
- def invalidClassName(name: Name) = {
+ def isInvalidClassName(name: Name) = {
val dp = name pos '$'
0 < dp && dp < (name.length - 1)
}
@@ -104,20 +106,35 @@ trait SymbolLoaders { self: SymbolTable =>
val e = super.lookupEntry(name)
if (e != null)
e
- else if (invalidClassName(name) || (negatives contains name))
+ else if (isInvalidClassName(name) || (negatives contains name))
null
else {
val path =
if (pkgClass.isEmptyPackageClass) name.toString
else pkgClass.fullName + "." + name
- if (isJavaClass(path)) {
- val (clazz, module) = createClassModule(pkgClass, name.toTypeName, new TopClassCompleter(_, _))
- debugInfo("created "+module+"/"+module.moduleClass+" in "+pkgClass)
- lookupEntry(name)
- } else {
- debugInfo("*** not found : "+path)
- negatives += name
- null
+ val currentMirror = mirrorThatLoaded(pkgClass)
+ currentMirror.tryJavaClass(path) match {
+ case Some(cls) =>
+ val loadingMirror = currentMirror.mirrorDefining(cls)
+ val (clazz, module) =
+ if (loadingMirror eq currentMirror) {
+ createClassModule(pkgClass, name.toTypeName, new TopClassCompleter(_, _))
+ } else {
+ val origOwner = loadingMirror.packageNameToScala(pkgClass.fullName)
+ val clazz = origOwner.info decl name.toTypeName
+ val module = origOwner.info decl name.toTermName
+ assert(clazz != NoSymbol)
+ assert(module != NoSymbol)
+ pkgClass.info.decls enter clazz
+ pkgClass.info.decls enter module
+ (clazz, module)
+ }
+ debugInfo(s"created $module/${module.moduleClass} in $pkgClass")
+ lookupEntry(name)
+ case none =>
+ debugInfo("*** not found : "+path)
+ negatives += name
+ null
}
}
}
diff --git a/src/compiler/scala/reflect/runtime/SymbolTable.scala b/src/compiler/scala/reflect/runtime/SymbolTable.scala
index 64a5894d01..c90665508b 100644
--- a/src/compiler/scala/reflect/runtime/SymbolTable.scala
+++ b/src/compiler/scala/reflect/runtime/SymbolTable.scala
@@ -3,14 +3,15 @@ package runtime
/**
* This symbol table trait fills in the definitions so that class information is obtained by refection.
- * It can be used either from the reflexive mirror itself (class Mirror), or else from
+ * It can be used either from a reflexive universe (class scala.reflect.runtime.JavaUniverse), or else from
* a runtime compiler that uses reflection to get a class information (class scala.tools.nsc.ReflectGlobal)
*/
-trait SymbolTable extends internal.SymbolTable with JavaToScala with ScalaToJava with ClassLoaders with SymbolLoaders with SynchronizedOps {
+trait SymbolTable extends internal.SymbolTable with JavaMirrors with SymbolLoaders with SynchronizedOps {
def info(msg: => String) =
if (settings.verbose.value) println("[reflect-compiler] "+msg)
def debugInfo(msg: => String) =
if (settings.debug.value) info(msg)
+
}
diff --git a/src/compiler/scala/reflect/runtime/SynchronizedSymbols.scala b/src/compiler/scala/reflect/runtime/SynchronizedSymbols.scala
index 2322911220..3b28ddf42c 100644
--- a/src/compiler/scala/reflect/runtime/SynchronizedSymbols.scala
+++ b/src/compiler/scala/reflect/runtime/SynchronizedSymbols.scala
@@ -14,11 +14,11 @@ trait SynchronizedSymbols extends internal.Symbols { self: SymbolTable =>
override def connectModuleToClass(m: ModuleSymbol, moduleClass: ClassSymbol): ModuleSymbol =
synchronized { super.connectModuleToClass(m, moduleClass) }
- override def newFreeTermSymbol(name: TermName, info: Type, value: => Any, flags: Long = 0L, origin: String = null): FreeTerm =
- new FreeTerm(name, value, origin) with SynchronizedTermSymbol initFlags flags setInfo info
+ override def newFreeTermSymbol(name: TermName, info: Type, value: => Any, flags: Long = 0L, origin: String = null): FreeTermSymbol =
+ new FreeTermSymbol(name, value, origin) with SynchronizedTermSymbol initFlags flags setInfo info
- override def newFreeTypeSymbol(name: TypeName, info: Type, value: => Any, flags: Long = 0L, origin: String = null): FreeType =
- new FreeType(name, value, origin) with SynchronizedTypeSymbol initFlags flags setInfo info
+ override def newFreeTypeSymbol(name: TypeName, info: Type, value: => Any, flags: Long = 0L, origin: String = null): FreeTypeSymbol =
+ new FreeTypeSymbol(name, value, origin) with SynchronizedTypeSymbol initFlags flags setInfo info
override protected def makeNoSymbol: NoSymbol = new NoSymbol with SynchronizedSymbol
@@ -92,8 +92,7 @@ trait SynchronizedSymbols extends internal.Symbols { self: SymbolTable =>
override protected def createModuleSymbol(name: TermName, pos: Position, newFlags: Long): ModuleSymbol =
new ModuleSymbol(this, pos, name) with SynchronizedTermSymbol initFlags newFlags
- override protected def createPackageSymbol(name: TermName, pos: Position, newFlags: Long): PackageSymbol =
- new PackageSymbol(this, pos, name) with SynchronizedTermSymbol initFlags newFlags
+ override protected def createPackageSymbol(name: TermName, pos: Position, newFlags: Long): ModuleSymbol = createModuleSymbol(name, pos, newFlags)
// TODO
// override protected def createValueParameterSymbol(name: TermName, pos: Position, newFlags: Long)
@@ -133,7 +132,8 @@ trait SynchronizedSymbols extends internal.Symbols { self: SymbolTable =>
trait SynchronizedModuleClassSymbol extends ModuleClassSymbol with SynchronizedClassSymbol {
override def sourceModule = synchronized { super.sourceModule }
- override def sourceModule_=(module: Symbol) = synchronized { super.sourceModule_=(module: Symbol) }
+ // [Eugene++ to Martin] doesn't override anything. no longer necessary?
+ // def sourceModule_=(module: ModuleSymbol) = synchronized { super.sourceModule_=(module) }
override def implicitMembers: List[Symbol] = synchronized { super.implicitMembers }
}
}
diff --git a/src/compiler/scala/reflect/runtime/SynchronizedTypes.scala b/src/compiler/scala/reflect/runtime/SynchronizedTypes.scala
index e5a508f802..e1eb7a57fe 100644
--- a/src/compiler/scala/reflect/runtime/SynchronizedTypes.scala
+++ b/src/compiler/scala/reflect/runtime/SynchronizedTypes.scala
@@ -9,7 +9,8 @@ trait SynchronizedTypes extends internal.Types { self: SymbolTable =>
// No sharing of map objects:
override protected def commonOwnerMap = new CommonOwnerMap
- private val uniqueLock = new Object
+ private object uniqueLock
+
override def unique[T <: Type](tp: T): T = uniqueLock.synchronized { super.unique(tp) }
class SynchronizedUndoLog extends UndoLog {
@@ -29,7 +30,7 @@ trait SynchronizedTypes extends internal.Types { self: SymbolTable =>
override protected def baseTypeOfNonClassTypeRef(tpe: NonClassTypeRef, clazz: Symbol) =
synchronized { super.baseTypeOfNonClassTypeRef(tpe, clazz) }
- private val subsametypeLock = new Object
+ private object subsametypeLock
override def isSameType(tp1: Type, tp2: Type): Boolean =
subsametypeLock.synchronized { super.isSameType(tp1, tp2) }
@@ -40,7 +41,7 @@ trait SynchronizedTypes extends internal.Types { self: SymbolTable =>
override def isSubType(tp1: Type, tp2: Type, depth: Int): Boolean =
subsametypeLock.synchronized { super.isSubType(tp1, tp2, depth) }
- private val lubglbLock = new Object
+ private object lubglbLock
override def glb(ts: List[Type]): Type =
lubglbLock.synchronized { super.glb(ts) }
@@ -48,13 +49,13 @@ trait SynchronizedTypes extends internal.Types { self: SymbolTable =>
override def lub(ts: List[Type]): Type =
lubglbLock.synchronized { super.lub(ts) }
- private val indentLock = new Object
+ private object indentLock
override protected def explain[T](op: String, p: (Type, T) => Boolean, tp1: Type, arg2: T): Boolean = {
indentLock.synchronized { super.explain(op, p, tp1, arg2) }
}
- private val toStringLock = new Object
+ private object toStringLock
override protected def typeToString(tpe: Type): String =
toStringLock.synchronized(super.typeToString(tpe))
@@ -84,4 +85,4 @@ trait SynchronizedTypes extends internal.Types { self: SymbolTable =>
override protected def defineBaseTypeSeqOfTypeRef(tpe: TypeRef) =
tpe.synchronized { super.defineBaseTypeSeqOfTypeRef(tpe) }
-} \ No newline at end of file
+}
diff --git a/src/compiler/scala/reflect/runtime/TwoWayCache.scala b/src/compiler/scala/reflect/runtime/TwoWayCache.scala
new file mode 100644
index 0000000000..c7bfb3435d
--- /dev/null
+++ b/src/compiler/scala/reflect/runtime/TwoWayCache.scala
@@ -0,0 +1,52 @@
+package scala.reflect
+package runtime
+
+/** A cache that maintains a bijection between Java reflection type `J`
+ * and Scala reflection type `S`.
+ */
+import collection.mutable.HashMap
+
+private[runtime] class TwoWayCache[J, S] {
+
+ private val toScalaMap = new HashMap[J, S]
+ private val toJavaMap = new HashMap[S, J]
+
+ def enter(j: J, s: S) = synchronized {
+ // debugInfo("cached: "+j+"/"+s)
+ toScalaMap(j) = s
+ toJavaMap(s) = j
+ }
+
+ def toScala(key: J)(body: => S): S = synchronized {
+ toScalaMap get key match {
+ case Some(v) =>
+ v
+ case none =>
+ val result = body
+ enter(key, result)
+ result
+ }
+ }
+
+ def toJava(key: S)(body: => J): J = synchronized {
+ toJavaMap get key match {
+ case Some(v) =>
+ v
+ case none =>
+ val result = body
+ enter(result, key)
+ result
+ }
+ }
+
+ def toJavaOption(key: S)(body: => Option[J]): Option[J] = synchronized {
+ toJavaMap get key match {
+ case None =>
+ val result = body
+ for (value <- result) enter(value, key)
+ result
+ case some => some
+ }
+ }
+}
+
diff --git a/src/compiler/scala/reflect/runtime/Universe.scala b/src/compiler/scala/reflect/runtime/Universe.scala
deleted file mode 100644
index fd53308d0a..0000000000
--- a/src/compiler/scala/reflect/runtime/Universe.scala
+++ /dev/null
@@ -1,43 +0,0 @@
-package scala.reflect
-package runtime
-
-import internal.{SomePhase, NoPhase, Phase, TreeGen}
-
-/** The universe for standard runtime reflection from Java.
- * This type implements all abstract term members in internal.SymbolTable.
- * It also provides methods to go from Java members to Scala members,
- * using the code in JavaConversions.
- */
-abstract class Universe extends SymbolTable with ToolBoxes {
-
- type AbstractFileType = AbstractFile
-
- def picklerPhase = SomePhase
-
- type TreeGen = internal.TreeGen
-
- val gen = new TreeGen { val global: Universe.this.type = Universe.this }
-
- lazy val settings = new Settings
- def forInteractive = false
- def forScaladoc = false
-
- val phaseWithId: Array[Phase] = Array(NoPhase, SomePhase)
- val currentRunId = 1 // fake a run id so that it is different from NoRunId
- phase = SomePhase // set to a phase different from NoPhase
-
- def log(msg: => AnyRef): Unit = println(" [] "+msg)
-
- type TreeCopier = TreeCopierOps
- def newStrictTreeCopier: TreeCopier = new StrictTreeCopier
- def newLazyTreeCopier: TreeCopier = new LazyTreeCopier
-
- definitions.AnyValClass // force it.
-
- // establish root association to avoid cyclic dependency errors later
- // don't use classOf[...] here, because it gets serviced by getClass.getClassLoader!
- classToScala(Class.forName("java.lang.Object", true, classLoader)).initialize
-
-// println("initializing definitions")
- definitions.init()
-}
diff --git a/src/compiler/scala/reflect/runtime/package.scala b/src/compiler/scala/reflect/runtime/package.scala
index 52ab2c5deb..531873c661 100644
--- a/src/compiler/scala/reflect/runtime/package.scala
+++ b/src/compiler/scala/reflect/runtime/package.scala
@@ -1,5 +1,13 @@
package scala.reflect
+import language.experimental.macros
+
package object runtime {
- def mkMirror(classLoader: ClassLoader): api.Mirror = new Mirror(classLoader)
-} \ No newline at end of file
+
+ // type is api.JavaUniverse because we only want to expose the `scala.reflect.api.*` subset of reflection
+ lazy val universe: api.JavaUniverse = new runtime.JavaUniverse
+
+ // [Eugene++ to Martin] removed `mirrorOfLoader`, because one can use `universe.runtimeMirror` instead
+
+ def currentMirror: universe.Mirror = ???
+}
diff --git a/src/compiler/scala/tools/cmd/FromString.scala b/src/compiler/scala/tools/cmd/FromString.scala
index dd3b680afe..29f1baaa0c 100644
--- a/src/compiler/scala/tools/cmd/FromString.scala
+++ b/src/compiler/scala/tools/cmd/FromString.scala
@@ -7,6 +7,7 @@ package scala.tools
package cmd
import nsc.io.{ Path, File, Directory }
+import scala.reflect.runtime.{universe => ru}
import scala.tools.reflect.StdTags._
/** A general mechanism for defining how a command line argument
@@ -14,7 +15,7 @@ import scala.tools.reflect.StdTags._
* example instances are in the companion object, but in general
* either IntFromString will suffice or you'll want custom transformers.
*/
-abstract class FromString[+T](implicit t: TypeTag[T]) extends PartialFunction[String, T] {
+abstract class FromString[+T](implicit t: ru.TypeTag[T]) extends PartialFunction[String, T] {
def apply(s: String): T
def isDefinedAt(s: String): Boolean = true
def zero: T = apply("")
diff --git a/src/compiler/scala/tools/nsc/ClassLoaders.scala b/src/compiler/scala/tools/nsc/ClassLoaders.scala
deleted file mode 100644
index 4058ee9324..0000000000
--- a/src/compiler/scala/tools/nsc/ClassLoaders.scala
+++ /dev/null
@@ -1,64 +0,0 @@
-package scala.tools.nsc
-
-import util.ScalaClassLoader
-
-trait ClassLoaders { self: Global =>
-
- def staticClass(fullname: String) = {
- if (self.forMSIL)
- throw new UnsupportedOperationException("Scala reflection not available on this platform")
-
- getClass(newTypeName(fullname))
- }
-
- def staticModule(fullname: String) = {
- if (self.forMSIL)
- throw new UnsupportedOperationException("Scala reflection not available on this platform")
-
- getModule(newTermName(fullname))
- }
-
- private def getClass(fullname: Name): Symbol = {
- var result = getModuleOrClass(fullname.toTypeName)
- while (result.isAliasType) result = result.info.typeSymbol
- result
- }
-
- private def getModule(fullname: Name): Symbol =
- getModuleOrClass(fullname.toTermName)
-
- private def getModuleOrClass(path: Name): Symbol =
- getModuleOrClass(path, path.length)
-
- private def getModuleOrClass(path: Name, len: Int): Symbol = {
- val point = path lastPos('.', len - 1)
- val owner =
- if (point > 0) getModuleOrClass(path.toTermName, point)
- else definitions.RootClass
- val name = path subName (point + 1, len)
- val sym = owner.info member name
- val result = if (path.isTermName) sym.suchThat(_ hasFlag symtab.Flags.MODULE) else sym
- if (result != NoSymbol) result
- else {
- if (settings.debug.value) { log(sym.info); log(sym.info.members) }//debug
- if (owner.isRoot && isJavaClass(name.toString))
- definitions.EmptyPackageClass.info decl name
- else {
- def info(msg: => String) = if (settings.verbose.value) println(msg)
- info("*** missing: "+name+"/"+name.isTermName+"/"+owner+"/"+owner.hasPackageFlag+"/"+owner.info.decls.getClass)
- MissingRequirementError.notFound((if (path.isTermName) "object " else "class ")+path)
- }
- }
- }
-
- private def isJavaClass(path: String): Boolean =
- try {
- val classpath = platform.classPath.asURLs
- var classLoader = ScalaClassLoader.fromURLs(classpath)
- Class.forName(path, true, classLoader)
- true
- } catch {
- case (_: ClassNotFoundException) | (_: NoClassDefFoundError) | (_: IncompatibleClassChangeError) =>
- false
- }
-}
diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala
index 271dca3157..57124b9c1c 100644
--- a/src/compiler/scala/tools/nsc/Global.scala
+++ b/src/compiler/scala/tools/nsc/Global.scala
@@ -31,21 +31,42 @@ import backend.icode.analysis._
import language.postfixOps
import reflect.internal.StdAttachments
-class Global(var currentSettings: Settings, var reporter: Reporter) extends SymbolTable
- with ClassLoaders
- with ToolBoxes
- with CompilationUnits
- with Plugins
- with PhaseAssembly
- with Trees
- with FreeVars
- with TreePrinters
- with DocComments
- with Positions {
+class Global(var currentSettings: Settings, var reporter: Reporter)
+ extends SymbolTable
+ with CompilationUnits
+ with Plugins
+ with PhaseAssembly
+ with Trees
+ with TreePrinters
+ with DocComments
+ with Positions { self =>
+
+ // [Eugene++] would love to find better homes for the new things dumped into Global
+
+ // the mirror --------------------------------------------------
+
+ override def isCompilerUniverse = true
+
+ class GlobalMirror extends Roots(NoSymbol) {
+ val universe: self.type = self
+ def rootLoader: LazyType = platform.rootLoader
+ override def toString = "compiler mirror"
+ }
+
+ lazy val rootMirror: Mirror = {
+ val rm = new GlobalMirror
+ rm.init()
+ rm.asInstanceOf[Mirror]
+ }
+ def RootClass: ClassSymbol = rootMirror.RootClass
+ def EmptyPackageClass: ClassSymbol = rootMirror.EmptyPackageClass
+ // [Eugene++] this little inconvenience gives us precise types for Expr.mirror and TypeTag.mirror
+ // by the way, is it possible to define variant type members?
override def settings = currentSettings
- import definitions.{ findNamedMember, findMemberFromRoot }
+ import definitions.findNamedMember
+ def findMemberFromRoot(fullName: Name): Symbol = rootMirror.findMemberFromRoot(fullName)
// alternate constructors ------------------------------------------
@@ -77,14 +98,12 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb
def classPath: PlatformClassPath = platform.classPath
- def rootLoader: LazyType = platform.rootLoader
-
// sub-components --------------------------------------------------
/** Generate ASTs */
type TreeGen = scala.tools.nsc.ast.TreeGen
- object gen extends {
+ override object gen extends {
val global: Global.this.type = Global.this
} with TreeGen {
def mkAttributedCast(tree: Tree, pt: Type): Tree =
@@ -386,6 +405,9 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb
val global: Global.this.type = Global.this
}
+ /** Returns the mirror that loaded given symbol */
+ def mirrorThatLoaded(sym: Symbol): Mirror = rootMirror
+
// ------------ Phases -------------------------------------------}
var globalPhase: Phase = NoPhase
@@ -686,7 +708,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb
object icodeChecker extends icodeCheckers.ICodeChecker()
object typer extends analyzer.Typer(
- analyzer.NoContext.make(EmptyTree, Global.this.definitions.RootClass, newScope)
+ analyzer.NoContext.make(EmptyTree, RootClass, newScope)
)
/** Add the internal compiler phases to the phases set.
@@ -849,7 +871,9 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb
/** Is given package class a system package class that cannot be invalidated?
*/
private def isSystemPackageClass(pkg: Symbol) =
- pkg == definitions.RootClass ||
+ // [Eugene++ to Martin] please, verify
+// was: pkg == definitions.RootClass ||
+ pkg == RootClass ||
pkg == definitions.ScalaPackageClass || {
val pkgname = pkg.fullName
(pkgname startsWith "scala.") && !(pkgname startsWith "scala.tools")
@@ -911,7 +935,9 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb
else new MergedClassPath(elems, classPath.context)
val oldEntries = mkClassPath(subst.keys)
val newEntries = mkClassPath(subst.values)
- reSync(definitions.RootClass, Some(classPath), Some(oldEntries), Some(newEntries), invalidated, failed)
+ // [Eugene++ to Martin] please, verify
+// was: reSync(definitions.RootClass, Some(classPath), Some(oldEntries), Some(newEntries), invalidated, failed)
+ reSync(RootClass, Some(classPath), Some(oldEntries), Some(newEntries), invalidated, failed)
}
}
def show(msg: String, syms: collection.Traversable[Symbol]) =
@@ -970,7 +996,9 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb
invalidateOrRemove(root)
} else {
if (classesFound) {
- if (root.isRoot) invalidateOrRemove(definitions.EmptyPackageClass)
+ // [Eugene++ to Martin] please, verify
+// was: if (root.isRoot) invalidateOrRemove(definitions.EmptyPackageClass)
+ if (root.isRoot) invalidateOrRemove(EmptyPackageClass)
else failed += root
}
(oldEntries, newEntries) match {
@@ -1514,13 +1542,16 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb
compileUnits(sources map (new CompilationUnit(_)), firstPhase)
}
- /** Compile list of units, starting with phase `fromPhase`
- */
def compileUnits(units: List[CompilationUnit], fromPhase: Phase) {
try compileUnitsInternal(units, fromPhase)
catch { case ex =>
+ val shown = if (settings.verbose.value) {
+ val pw = new java.io.PrintWriter(new java.io.StringWriter)
+ ex.printStackTrace(pw)
+ pw.toString
+ } else ex.getClass.getName
// ex.printStackTrace(Console.out) // DEBUG for fsc, note that error stacktraces do not print in fsc
- globalError(supplementErrorMessage("uncaught exception during compilation: " + ex.getClass.getName))
+ globalError(supplementErrorMessage("uncaught exception during compilation: " + shown))
throw ex
}
}
@@ -1600,7 +1631,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb
// Reset project
if (!stopPhase("namer")) {
atPhase(namerPhase) {
- resetProjectClasses(definitions.RootClass)
+ resetProjectClasses(RootClass)
}
}
}
diff --git a/src/compiler/scala/tools/nsc/ReflectGlobal.scala b/src/compiler/scala/tools/nsc/ReflectGlobal.scala
index 68a6a4d336..4f4db83339 100644
--- a/src/compiler/scala/tools/nsc/ReflectGlobal.scala
+++ b/src/compiler/scala/tools/nsc/ReflectGlobal.scala
@@ -5,17 +5,33 @@ import reporters.Reporter
/** A version of Global that uses reflection to get class
* infos, instead of reading class or source files.
*/
-class ReflectGlobal(currentSettings: Settings, reporter: Reporter, var classLoader: ClassLoader)
- extends Global(currentSettings, reporter) with reflect.runtime.SymbolTable {
+class ReflectGlobal(currentSettings: Settings, reporter: Reporter, override val rootClassLoader: ClassLoader)
+ extends Global(currentSettings, reporter) with scala.tools.nsc.ReflectSetup with scala.reflect.runtime.SymbolTable {
override def transformedType(sym: Symbol) =
erasure.transformInfo(sym,
uncurry.transformInfo(sym,
refChecks.transformInfo(sym, sym.info)))
- override def staticClass(fullname: String) =
- super[SymbolTable].staticClass(fullname)
+ override def isCompilerUniverse = true
- override def staticModule(fullname: String) =
- super[SymbolTable].staticModule(fullname)
+ // Typically `runtimeMirror` creates a new mirror for every new classloader
+ // and shares symbols between the created mirrors.
+ //
+ // However we can't do that for the compiler.
+ // The problem is that symbol sharing violates owner chain assumptions that the compiler has.
+ //
+ // For example, we can easily end up with a situation when:
+ //
+ // Predef defined in package scala loaded by the classloader that has scala-library.jar
+ //
+ // cannot be accessed in:
+ //
+ // package scala for the rootMirror of ReflectGlobal that might correspond to a different classloader
+ //
+ // This happens because, despite the fact that `Predef` is shared between multiple `scala` packages (i.e. multiple scopes)
+ // (each mirror has its own set package symbols, because of the peculiarities of symbol loading in scala),
+ // that `Predef` symbol only has a single owner, and this messes up visibility, which is calculated based on owners, not scopes.
+ override def runtimeMirror(cl: ClassLoader): Mirror = rootMirror
}
+
diff --git a/src/compiler/scala/tools/nsc/ReflectMain.scala b/src/compiler/scala/tools/nsc/ReflectMain.scala
index f9a18abc25..161391fc2c 100644
--- a/src/compiler/scala/tools/nsc/ReflectMain.scala
+++ b/src/compiler/scala/tools/nsc/ReflectMain.scala
@@ -1,16 +1,15 @@
package scala.tools.nsc
-import util.ScalaClassLoader
import tools.util.PathResolver
import util.ClassPath.DefaultJavaContext
+import util.ScalaClassLoader
object ReflectMain extends Driver {
- private def reflectionClassloaderFromSettings(settings: Settings) = {
+ private def classloaderFromSettings(settings: Settings) = {
val classpath = new PathResolver(settings).result
ScalaClassLoader.fromURLs(classpath.asURLs, getClass.getClassLoader)
}
- override def newCompiler(): Global = new ReflectGlobal(settings, reporter, reflectionClassloaderFromSettings(settings))
-
+ override def newCompiler(): Global = new ReflectGlobal(settings, reporter, classloaderFromSettings(settings))
} \ No newline at end of file
diff --git a/src/compiler/scala/tools/nsc/ReflectSetup.scala b/src/compiler/scala/tools/nsc/ReflectSetup.scala
new file mode 100644
index 0000000000..26c720a10f
--- /dev/null
+++ b/src/compiler/scala/tools/nsc/ReflectSetup.scala
@@ -0,0 +1,7 @@
+package scala.tools.nsc
+
+/** A helper trait to initialize things that need to be set before JavaMirrors and other
+ * reflect specific traits are initialized */
+private[nsc] trait ReflectSetup { this: Global =>
+ phase = new Run().typerPhase
+} \ No newline at end of file
diff --git a/src/compiler/scala/tools/nsc/ToolBoxes.scala b/src/compiler/scala/tools/nsc/ToolBoxes.scala
deleted file mode 100644
index f5eefa4e62..0000000000
--- a/src/compiler/scala/tools/nsc/ToolBoxes.scala
+++ /dev/null
@@ -1,84 +0,0 @@
-package scala.tools.nsc
-
-import util.ScalaClassLoader
-
-trait ToolBoxes { self: Global =>
-
- def mkToolBox(frontEnd: FrontEnd = mkSilentFrontEnd(), options: String = "") = new ToolBox(frontEnd, options)
-
- class ToolBox(val frontEnd: FrontEnd, val options: String) extends AbsToolBox {
- def typeCheck(tree0: Tree, pt: Type = WildcardType, freeTypes: Map[FreeType, Type] = Map[FreeType, Type](), silent: Boolean = false, withImplicitViewsDisabled: Boolean = false, withMacrosDisabled: Boolean = false): Tree = {
- val tree = substituteFreeTypes(tree0, freeTypes)
- val currentTyper = typer
- val wrapper1 = if (!withImplicitViewsDisabled) (currentTyper.context.withImplicitsEnabled[Tree] _) else (currentTyper.context.withImplicitsDisabled[Tree] _)
- val wrapper2 = if (!withMacrosDisabled) (currentTyper.context.withMacrosEnabled[Tree] _) else (currentTyper.context.withMacrosDisabled[Tree] _)
- def wrapper (tree: => Tree) = wrapper1(wrapper2(tree))
- wrapper(currentTyper.silent(_.typed(tree, analyzer.EXPRmode, pt)) match {
- case analyzer.SilentResultValue(result) =>
- result
- case error @ analyzer.SilentTypeError(_) =>
- if (!silent) throw new ToolBoxError(this, "reflective typecheck has failed: %s".format(error.err.errMsg))
- EmptyTree
- })
- }
-
- def inferImplicitValue(pt: Type, silent: Boolean = true, withMacrosDisabled: Boolean = false): Tree =
- // todo. implement this
- ???
-
- def inferImplicitView(tree: Tree, from: Type, to: Type, silent: Boolean = true, withMacrosDisabled: Boolean = false, reportAmbiguous: Boolean = true): Tree =
- // todo. implement this
- ???
-
- def resetAllAttrs(tree: Tree): Tree =
- self.resetAllAttrs(tree)
-
- def resetLocalAttrs(tree: Tree): Tree =
- self.resetLocalAttrs(tree)
-
- def runExpr(tree0: Tree, freeTypes: Map[FreeType, Type] = Map[FreeType, Type]()): Any = {
- var tree = substituteFreeTypes(tree0, freeTypes)
- // need to reset the tree, otherwise toolbox will refuse to work with it
- // upd. this has to be done by the user himself, otherwise we run into troubles. see SI-5713
-// tree = resetAllAttrs(tree0.duplicate)
- val imported = importer.importTree(tree)
- val toolBox = libraryClasspathMirror.mkToolBox(frontEnd.asInstanceOf[libraryClasspathMirror.FrontEnd], options)
- try toolBox.runExpr(imported)
- catch {
- case ex: toolBox.ToolBoxError =>
- throw new ToolBoxError(this, ex.message, ex.cause)
- }
- }
-
- // [Eugene] how do I make this work without casts?
- // private lazy val importer = libraryClasspathMirror.mkImporter(self)
- private lazy val importer = libraryClasspathMirror.mkImporter(self).asInstanceOf[libraryClasspathMirror.Importer { val from: self.type }]
-
- private lazy val libraryClasspathMirror = {
- if (self.forMSIL)
- throw new UnsupportedOperationException("Scala reflection not available on this platform")
-
- val libraryClassLoader = {
- val classpath = self.classPath.asURLs
- var loader: ClassLoader = ScalaClassLoader.fromURLs(classpath, self.getClass.getClassLoader)
-
- // [Eugene] a heuristic to detect REPL
- if (self.settings.exposeEmptyPackage.value) {
- import scala.tools.nsc.interpreter._
- val virtualDirectory = self.settings.outputDirs.getSingleOutput.get
- loader = new AbstractFileClassLoader(virtualDirectory, loader) {}
- }
-
- loader
- }
-
- new scala.reflect.runtime.Mirror(libraryClassLoader)
- }
-
- class ToolBoxError(val toolBox: ToolBox, val message: String, val cause: Throwable = null) extends Throwable(message, cause)
-
- object ToolBoxError extends ToolBoxErrorExtractor {
- def unapply(error: ToolBoxError): Option[(ToolBox, String)] = Some((error.toolBox, error.message))
- }
- }
-} \ No newline at end of file
diff --git a/src/compiler/scala/tools/nsc/ast/DocComments.scala b/src/compiler/scala/tools/nsc/ast/DocComments.scala
index 028c5741c9..a01756b35b 100755
--- a/src/compiler/scala/tools/nsc/ast/DocComments.scala
+++ b/src/compiler/scala/tools/nsc/ast/DocComments.scala
@@ -458,7 +458,7 @@ trait DocComments { self: Global =>
case site :: sites1 => select(site.thisType, name, findIn(sites1))
}
val (classes, pkgs) = site.ownerChain.span(!_.isPackageClass)
- findIn(classes ::: List(pkgs.head, definitions.RootClass))
+ findIn(classes ::: List(pkgs.head, rootMirror.RootClass))
}
def getType(_str: String, variable: String): Type = {
@@ -508,7 +508,7 @@ trait DocComments { self: Global =>
val tpe = getType(repl.trim, alias.name.toString)
if (tpe != NoType) tpe
else {
- val alias1 = alias.cloneSymbol(definitions.RootClass, alias.rawflags, newTypeName(repl))
+ val alias1 = alias.cloneSymbol(rootMirror.RootClass, alias.rawflags, newTypeName(repl))
typeRef(NoPrefix, alias1, Nil)
}
case None =>
diff --git a/src/compiler/scala/tools/nsc/ast/FreeVars.scala b/src/compiler/scala/tools/nsc/ast/FreeVars.scala
deleted file mode 100644
index a1983d1834..0000000000
--- a/src/compiler/scala/tools/nsc/ast/FreeVars.scala
+++ /dev/null
@@ -1,26 +0,0 @@
-package scala.tools.nsc
-package ast
-
-trait FreeVars extends reflect.internal.FreeVars { self: Global =>
-
- import self._
- import definitions._
- import treeInfo._
-
- def logFreeVars(position: Position, reified: Tree): Unit = {
- if (settings.logFreeTerms.value || settings.logFreeTypes.value) {
- reified match {
- case Reified(_, symbolTable, _) =>
- // logging free vars only when they are untyped prevents avalanches of duplicate messages
- symbolTable foreach {
- case FreeTermDef(_, _, binding, _, origin) if settings.logFreeTerms.value && binding.tpe == null =>
- reporter.echo(position, "free term: %s %s".format(showRaw(binding), origin))
- case FreeTypeDef(_, _, binding, _, origin) if settings.logFreeTypes.value && binding.tpe == null =>
- reporter.echo(position, "free type: %s %s".format(showRaw(binding), origin))
- case _ =>
- // do nothing
- }
- }
- }
- }
-} \ No newline at end of file
diff --git a/src/compiler/scala/tools/nsc/ast/NodePrinters.scala b/src/compiler/scala/tools/nsc/ast/NodePrinters.scala
index 17d8def2e9..ba1f3b2e3c 100644
--- a/src/compiler/scala/tools/nsc/ast/NodePrinters.scala
+++ b/src/compiler/scala/tools/nsc/ast/NodePrinters.scala
@@ -169,7 +169,7 @@ abstract class NodePrinters {
}
}
- def treePrefix(tree: Tree) = showPosition(tree) + tree.printingPrefix
+ def treePrefix(tree: Tree) = showPosition(tree) + tree.productPrefix
def printMultiline(tree: Tree)(body: => Unit) {
printMultiline(treePrefix(tree), showAttributes(tree))(body)
}
diff --git a/src/compiler/scala/tools/nsc/ast/TreeBrowsers.scala b/src/compiler/scala/tools/nsc/ast/TreeBrowsers.scala
index b4beb231ab..f88e41375d 100644
--- a/src/compiler/scala/tools/nsc/ast/TreeBrowsers.scala
+++ b/src/compiler/scala/tools/nsc/ast/TreeBrowsers.scala
@@ -354,7 +354,7 @@ abstract class TreeBrowsers {
*/
object TreeInfo {
/** Return the case class name and the Name, if the node defines one */
- def treeName(t: Tree): (String, Name) = ((t.printingPrefix, t match {
+ def treeName(t: Tree): (String, Name) = ((t.productPrefix, t match {
case UnitTree(unit) => newTermName("" + unit)
case Super(_, mix) => newTermName("mix: " + mix)
case This(qual) => qual
diff --git a/src/compiler/scala/tools/nsc/ast/Trees.scala b/src/compiler/scala/tools/nsc/ast/Trees.scala
index 6f1a8f488f..1d29e33c50 100644
--- a/src/compiler/scala/tools/nsc/ast/Trees.scala
+++ b/src/compiler/scala/tools/nsc/ast/Trees.scala
@@ -116,7 +116,10 @@ trait Trees extends reflect.internal.Trees { self: Global =>
if (vparamss1.isEmpty || !vparamss1.head.isEmpty && vparamss1.head.head.mods.isImplicit)
vparamss1 = List() :: vparamss1;
val superRef: Tree = atPos(superPos)(gen.mkSuperSelect)
- val superCall = (superRef /: argss) (Apply)
+ def mkApply(fun: Tree, args: List[Tree]) = Apply(fun, args)
+ val superCall = (superRef /: argss) (mkApply)
+ // [Eugene++] no longer compiles after I moved the `Apply` case class into scala.reflect.internal
+ // val superCall = (superRef /: argss) (Apply)
List(
atPos(wrappingPos(superPos, lvdefs ::: argss.flatten)) (
DefDef(constrMods, nme.CONSTRUCTOR, List(), vparamss1, TypeTree(), Block(lvdefs ::: List(superCall), Literal(Constant())))))
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
index 226c17f10d..688da4fd04 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
@@ -1026,7 +1026,7 @@ self =>
val tok = in.token
val name = ident()
t = atPos(start) {
- if (tok == BACKQUOTED_IDENT) Ident(name) withAttachment BackquotedIdentifier
+ if (tok == BACKQUOTED_IDENT) Ident(name) addAttachment BackquotedIdentifierAttachment
else Ident(name)
}
if (in.token == DOT) {
diff --git a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala
index de7e6f9c7a..90f9d538c1 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala
@@ -546,7 +546,10 @@ abstract class TreeBuilder {
rhs1,
List(
atPos(pat1.pos) {
- CaseDef(pat1, EmptyTree, makeTupleTerm(vars map (_._1) map Ident, true))
+ def mkIdent(name: Name) = Ident(name)
+ CaseDef(pat1, EmptyTree, makeTupleTerm(vars map (_._1) map mkIdent, true))
+ // [Eugene++] no longer compiles after I moved the `Ident` case class into scala.reflect.internal
+ // CaseDef(pat1, EmptyTree, makeTupleTerm(vars map (_._1) map Ident, true))
}
))
}
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
index 3f193672ec..0c527fbaf4 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
@@ -53,7 +53,7 @@ abstract class GenASM extends SubComponent with BytecodeWriters {
override def erasedTypes = true
def apply(cls: IClass) = sys.error("no implementation")
- val BeanInfoAttr = definitions.getRequiredClass("scala.beans.BeanInfo")
+ val BeanInfoAttr = rootMirror.getRequiredClass("scala.beans.BeanInfo")
def isJavaEntryPoint(icls: IClass) = {
val sym = icls.symbol
@@ -345,8 +345,8 @@ abstract class GenASM extends SubComponent with BytecodeWriters {
def inameToSymbol(iname: String): Symbol = {
val name = global.newTypeName(iname)
val res0 =
- if (nme.isModuleName(name)) definitions.getModule(nme.stripModuleSuffix(name))
- else definitions.getClassByName(name.replace('/', '.')) // TODO fails for inner classes (but this hasn't been tested).
+ if (nme.isModuleName(name)) rootMirror.getModule(nme.stripModuleSuffix(name))
+ else rootMirror.getClassByName(name.replace('/', '.')) // TODO fails for inner classes (but this hasn't been tested).
assert(res0 != NoSymbol)
val res = jsymbol(res0)
res
@@ -1180,8 +1180,8 @@ abstract class GenASM extends SubComponent with BytecodeWriters {
*/
private val androidFieldName = newTermName("CREATOR")
- private lazy val AndroidParcelableInterface = definitions.getClassIfDefined("android.os.Parcelable")
- private lazy val AndroidCreatorClass = definitions.getClassIfDefined("android.os.Parcelable$Creator")
+ private lazy val AndroidParcelableInterface = rootMirror.getClassIfDefined("android.os.Parcelable")
+ private lazy val AndroidCreatorClass = rootMirror.getClassIfDefined("android.os.Parcelable$Creator")
def isAndroidParcelableClass(sym: Symbol) =
(AndroidParcelableInterface != NoSymbol) &&
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenAndroid.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenAndroid.scala
index 1ba5b155fc..e3da5c486b 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/GenAndroid.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/GenAndroid.scala
@@ -25,8 +25,8 @@ trait GenAndroid {
*/
private val fieldName = newTermName("CREATOR")
- private lazy val AndroidParcelableInterface = definitions.getClassIfDefined("android.os.Parcelable")
- private lazy val AndroidCreatorClass = definitions.getClassIfDefined("android.os.Parcelable$Creator")
+ private lazy val AndroidParcelableInterface = rootMirror.getClassIfDefined("android.os.Parcelable")
+ private lazy val AndroidCreatorClass = rootMirror.getClassIfDefined("android.os.Parcelable$Creator")
def isAndroidParcelableClass(sym: Symbol) =
(AndroidParcelableInterface != NoSymbol) &&
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
index 73bcd08f4b..f302318185 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
@@ -203,10 +203,10 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with
val MethodHandleType = new JObjectType("java.dyn.MethodHandle")
// Scala attributes
- val BeanInfoAttr = definitions.getRequiredClass("scala.beans.BeanInfo")
- val BeanInfoSkipAttr = definitions.getRequiredClass("scala.beans.BeanInfoSkip")
- val BeanDisplayNameAttr = definitions.getRequiredClass("scala.beans.BeanDisplayName")
- val BeanDescriptionAttr = definitions.getRequiredClass("scala.beans.BeanDescription")
+ val BeanInfoAttr = rootMirror.getRequiredClass("scala.beans.BeanInfo")
+ val BeanInfoSkipAttr = rootMirror.getRequiredClass("scala.beans.BeanInfoSkip")
+ val BeanDisplayNameAttr = rootMirror.getRequiredClass("scala.beans.BeanDisplayName")
+ val BeanDescriptionAttr = rootMirror.getRequiredClass("scala.beans.BeanDescription")
final val ExcludedForwarderFlags = {
import Flags._
diff --git a/src/compiler/scala/tools/nsc/doc/Uncompilable.scala b/src/compiler/scala/tools/nsc/doc/Uncompilable.scala
index 8f426a443d..fef753b12c 100644
--- a/src/compiler/scala/tools/nsc/doc/Uncompilable.scala
+++ b/src/compiler/scala/tools/nsc/doc/Uncompilable.scala
@@ -16,7 +16,8 @@ trait Uncompilable {
val settings: Settings
import global.{ reporter, inform, warning, newTypeName, newTermName, Symbol, Name, DocComment, NoSymbol }
- import global.definitions.{ RootClass, AnyRefClass }
+ import global.definitions.AnyRefClass
+ import global.rootMirror.RootClass
private implicit def translateName(name: Global#Name) =
if (name.isTypeName) newTypeName("" + name) else newTermName("" + name)
diff --git a/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala b/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala
index 9062203dcd..3dd77d47da 100644
--- a/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala
+++ b/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala
@@ -20,7 +20,8 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
thisFactory: ModelFactory with ModelFactoryImplicitSupport with CommentFactory with TreeFactory =>
import global._
- import definitions.{ ObjectClass, RootPackage, EmptyPackage, NothingClass, AnyClass, AnyValClass, AnyRefClass }
+ import definitions.{ ObjectClass, NothingClass, AnyClass, AnyValClass, AnyRefClass }
+ import rootMirror.{ RootPackage, EmptyPackage }
private var droppedPackages = 0
def templatesCount = templatesCache.size - droppedPackages
@@ -339,7 +340,7 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
/** */
def normalizeTemplate(aSym: Symbol): Symbol = aSym match {
- case null | EmptyPackage | NoSymbol =>
+ case null | rootMirror.EmptyPackage | NoSymbol =>
normalizeTemplate(RootPackage)
case ObjectClass =>
normalizeTemplate(AnyRefClass)
diff --git a/src/compiler/scala/tools/nsc/interactive/Picklers.scala b/src/compiler/scala/tools/nsc/interactive/Picklers.scala
index b7a9c7329c..7c635c6d65 100644
--- a/src/compiler/scala/tools/nsc/interactive/Picklers.scala
+++ b/src/compiler/scala/tools/nsc/interactive/Picklers.scala
@@ -115,7 +115,7 @@ trait Picklers { self: Global =>
if (sym.isOverloaded) makeSymbol(sym.alternatives(rest.head.toString.toInt), rest.tail)
else makeSymbol(sym, rest)
}
- pkl[List[Name]] .wrapped { makeSymbol(definitions.RootClass, _) } { ownerNames(_, new ListBuffer).toList }
+ pkl[List[Name]] .wrapped { makeSymbol(rootMirror.RootClass, _) } { ownerNames(_, new ListBuffer).toList }
}
implicit def workEvent: Pickler[WorkEvent] = {
diff --git a/src/compiler/scala/tools/nsc/interactive/RangePositions.scala b/src/compiler/scala/tools/nsc/interactive/RangePositions.scala
index 49ba9d0aeb..c3eb06f2ff 100644
--- a/src/compiler/scala/tools/nsc/interactive/RangePositions.scala
+++ b/src/compiler/scala/tools/nsc/interactive/RangePositions.scala
@@ -189,7 +189,7 @@ self: scala.tools.nsc.Global =>
override def validatePositions(tree: Tree) {
def reportTree(prefix : String, tree : Tree) {
val source = if (tree.pos.isDefined) tree.pos.source else ""
- inform("== "+prefix+" tree ["+tree.id+"] of type "+tree.printingPrefix+" at "+tree.pos.show+source)
+ inform("== "+prefix+" tree ["+tree.id+"] of type "+tree.productPrefix+" at "+tree.pos.show+source)
inform("")
inform(treeStatus(tree))
inform("")
diff --git a/src/compiler/scala/tools/nsc/interpreter/ILoop.scala b/src/compiler/scala/tools/nsc/interpreter/ILoop.scala
index 84836ce1db..fdf7db1b9f 100644
--- a/src/compiler/scala/tools/nsc/interpreter/ILoop.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/ILoop.scala
@@ -106,7 +106,7 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter)
}
def isAsync = !settings.Yreplsync.value
- lazy val power = new Power(intp, new StdReplVals(this))(tagOfStdReplVals)
+ lazy val power = new Power(intp, new StdReplVals(this))(tagOfStdReplVals, classTag[StdReplVals])
def history = in.history
/** The context class loader at the time this object was created */
@@ -831,7 +831,7 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter)
}
// Bind intp somewhere out of the regular namespace where
// we can get at it in generated code.
- addThunk(intp.quietBind(NamedParam[IMain]("$intp", intp)(tagOfIMain)))
+ addThunk(intp.quietBind(NamedParam[IMain]("$intp", intp)(tagOfIMain, classTag[IMain])))
addThunk({
import scala.tools.nsc.io._
import Properties.userHome
diff --git a/src/compiler/scala/tools/nsc/interpreter/IMain.scala b/src/compiler/scala/tools/nsc/interpreter/IMain.scala
index 7ae8ea4535..94f51b78ed 100644
--- a/src/compiler/scala/tools/nsc/interpreter/IMain.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/IMain.scala
@@ -25,6 +25,7 @@ import IMain._
import java.util.concurrent.Future
import typechecker.Analyzer
import language.implicitConversions
+import scala.reflect.runtime.{ universe => ru }
import scala.tools.reflect.StdTags._
/** directory to save .class files to */
@@ -196,17 +197,8 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends
lazy val compiler: global.type = global
import global._
- import definitions.{
- ScalaPackage, JavaLangPackage, RootClass,
- getClassIfDefined, getModuleIfDefined, getRequiredModule, getRequiredClass,
- termMember, typeMember
- }
-
- private implicit def privateTreeOps(t: Tree): List[Tree] = {
- (new Traversable[Tree] {
- def foreach[U](f: Tree => U): Unit = t foreach { x => f(x) ; () }
- }).toList
- }
+ import definitions.{ScalaPackage, JavaLangPackage, termMember, typeMember}
+ import rootMirror.{RootClass, getClassIfDefined, getModuleIfDefined, getRequiredModule, getRequiredClass}
implicit class ReplTypeOps(tp: Type) {
def orElse(other: => Type): Type = if (tp ne NoType) tp else other
@@ -333,14 +325,7 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends
def getInterpreterClassLoader() = classLoader
// Set the current Java "context" class loader to this interpreter's class loader
- def setContextClassLoader() = {
- classLoader.setAsContext()
-
- // this is risky, but it's our only possibility to make default reflexive mirror to work with REPL
- // so far we have only used the default mirror to create a few tags for the compiler
- // so it shouldn't be in conflict with our classloader, especially since it respects its parent
- scala.reflect.mirror.classLoader = classLoader
- }
+ def setContextClassLoader() = classLoader.setAsContext()
/** Given a simple repl-defined name, returns the real name of
* the class representing it, e.g. for "Bippy" it may return
@@ -501,11 +486,17 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends
case Some(trees) => trees
}
repltrace(
- trees map (t =>
- t map (t0 =>
+ trees map (t => {
+ // [Eugene to Paul] previously it just said `t map ...`
+ // because there was an implicit conversion from Tree to a list of Trees
+ // however Martin and I have removed the conversion
+ // (it was conflicting with the new reflection API),
+ // so I had to rewrite this a bit
+ val subs = t collect { case sub => sub }
+ subs map (t0 =>
" " + safePos(t0, -1) + ": " + t0.shortClass + "\n"
) mkString ""
- ) mkString "\n"
+ }) mkString "\n"
)
// If the last tree is a bare expression, pinpoint where it begins using the
// AST node position and snap the line off there. Rewrite the code embodied
@@ -653,8 +644,8 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends
directlyBoundNames += newTermName(name)
result
}
- def directBind(p: NamedParam): IR.Result = directBind(p.name, p.tpe, p.value)
- def directBind[T: ClassTag](name: String, value: T): IR.Result = directBind((name, value))
+ def directBind(p: NamedParam): IR.Result = directBind(p.name, p.tpe, p.value)
+ def directBind[T: ru.TypeTag : ClassTag](name: String, value: T): IR.Result = directBind((name, value))
def rebind(p: NamedParam): IR.Result = {
val name = p.name
@@ -670,12 +661,12 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends
if (ids.isEmpty) IR.Success
else interpret("import " + ids.mkString(", "))
- def quietBind(p: NamedParam): IR.Result = beQuietDuring(bind(p))
- def bind(p: NamedParam): IR.Result = bind(p.name, p.tpe, p.value)
- def bind[T: TypeTag](name: String, value: T): IR.Result = bind((name, value))
- def bindSyntheticValue(x: Any): IR.Result = bindValue(freshInternalVarName(), x)
- def bindValue(x: Any): IR.Result = bindValue(freshUserVarName(), x)
- def bindValue(name: String, x: Any): IR.Result = bind(name, TypeStrings.fromValue(x), x)
+ def quietBind(p: NamedParam): IR.Result = beQuietDuring(bind(p))
+ def bind(p: NamedParam): IR.Result = bind(p.name, p.tpe, p.value)
+ def bind[T: ru.TypeTag : ClassTag](name: String, value: T): IR.Result = bind((name, value))
+ def bindSyntheticValue(x: Any): IR.Result = bindValue(freshInternalVarName(), x)
+ def bindValue(x: Any): IR.Result = bindValue(freshUserVarName(), x)
+ def bindValue(name: String, x: Any): IR.Result = bind(name, TypeStrings.fromValue(x), x)
/** Reset this interpreter, forgetting all user-specified requests. */
def reset() {
@@ -718,7 +709,7 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends
val unwrapped = unwrap(t)
withLastExceptionLock[String]({
- directBind[Throwable]("lastException", unwrapped)(classTag[Throwable])
+ directBind[Throwable]("lastException", unwrapped)(tagOfThrowable, classTag[Throwable])
util.stackTraceString(unwrapped)
}, util.stackTraceString(unwrapped))
}
@@ -1052,7 +1043,7 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends
valueOfTerm(id) map (_.getClass)
def typeOfTerm(id: String): Type = newTermName(id) match {
- case nme.ROOTPKG => definitions.RootClass.tpe
+ case nme.ROOTPKG => RootClass.tpe
case name => requestForName(name).fold(NoType: Type)(_ compilerTypeOf name)
}
diff --git a/src/compiler/scala/tools/nsc/interpreter/JLineCompletion.scala b/src/compiler/scala/tools/nsc/interpreter/JLineCompletion.scala
index b1e6a9d7d9..c429e3b196 100644
--- a/src/compiler/scala/tools/nsc/interpreter/JLineCompletion.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/JLineCompletion.scala
@@ -16,7 +16,8 @@ import collection.mutable.ListBuffer
class JLineCompletion(val intp: IMain) extends Completion with CompletionOutput {
val global: intp.global.type = intp.global
import global._
- import definitions.{ PredefModule, RootClass, AnyClass, AnyRefClass, ScalaPackage, JavaLangPackage, getModuleIfDefined }
+ import definitions.{ PredefModule, AnyClass, AnyRefClass, ScalaPackage, JavaLangPackage }
+ import rootMirror.{ RootClass, getModuleIfDefined }
type ExecResult = Any
import intp.{ debugging }
diff --git a/src/compiler/scala/tools/nsc/interpreter/NamedParam.scala b/src/compiler/scala/tools/nsc/interpreter/NamedParam.scala
index a3cbfffc3b..61a61de1e9 100644
--- a/src/compiler/scala/tools/nsc/interpreter/NamedParam.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/NamedParam.scala
@@ -8,23 +8,24 @@ package interpreter
import NamedParam._
import language.implicitConversions
+import scala.reflect.runtime.{universe => ru}
trait NamedParamCreator {
protected def freshName: () => String
def apply(name: String, tpe: String, value: Any): NamedParam = NamedParamClass(name, tpe, value)
- def apply[T: TypeTag](name: String, x: T): NamedParam = new Typed[T](name, x)
- def apply[T: TypeTag](x: T): NamedParam = apply(freshName(), x)
+ def apply[T: ru.TypeTag : ClassTag](name: String, x: T): NamedParam = new Typed[T](name, x)
+ def apply[T: ru.TypeTag : ClassTag](x: T): NamedParam = apply(freshName(), x)
def clazz(name: String, x: Any): NamedParam = new Untyped(name, x)
def clazz(x: Any): NamedParam = clazz(freshName(), x)
- implicit def namedValue[T: TypeTag](name: String, x: T): NamedParam = apply(name, x)
- implicit def tuple[T: TypeTag](pair: (String, T)): NamedParam = apply(pair._1, pair._2)
+ implicit def namedValue[T: ru.TypeTag : ClassTag](name: String, x: T): NamedParam = apply(name, x)
+ implicit def tuple[T: ru.TypeTag : ClassTag](pair: (String, T)): NamedParam = apply(pair._1, pair._2)
}
object NamedParam extends NamedParamCreator {
- class Typed[T: TypeTag](val name: String, val value: T) extends NamedParam {
+ class Typed[T: ru.TypeTag : ClassTag](val name: String, val value: T) extends NamedParam {
val tpe = TypeStrings.fromTag[T]
}
class Untyped(val name: String, val value: Any) extends NamedParam {
diff --git a/src/compiler/scala/tools/nsc/interpreter/Power.scala b/src/compiler/scala/tools/nsc/interpreter/Power.scala
index 9c4c05f1ee..a0687c824b 100644
--- a/src/compiler/scala/tools/nsc/interpreter/Power.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/Power.scala
@@ -14,6 +14,7 @@ import scala.io.Codec
import java.net.{ URL, MalformedURLException }
import io.{ Path }
import language.implicitConversions
+import scala.reflect.runtime.{universe => ru}
/** Collecting some power mode examples.
@@ -42,10 +43,11 @@ Lost after 18/flatten {
/** A class for methods to be injected into the intp in power mode.
*/
-class Power[ReplValsImpl <: ReplVals : TypeTag](val intp: IMain, replVals: ReplValsImpl) {
+class Power[ReplValsImpl <: ReplVals : ru.TypeTag: ClassTag](val intp: IMain, replVals: ReplValsImpl) {
import intp.{ beQuietDuring, typeOfExpression, interpret, parse }
import intp.global._
- import definitions.{ compilerTypeFromTag, compilerSymbolFromTag, getClassIfDefined, getModuleIfDefined }
+ import definitions.{ compilerTypeFromTag, compilerSymbolFromTag}
+ import rootMirror.{ getClassIfDefined, getModuleIfDefined }
abstract class SymSlurper {
def isKeep(sym: Symbol): Boolean
@@ -162,7 +164,7 @@ class Power[ReplValsImpl <: ReplVals : TypeTag](val intp: IMain, replVals: ReplV
}
trait LowPriorityInternalInfo {
- implicit def apply[T: TypeTag] : InternalInfo[T] = new InternalInfo[T](None)
+ implicit def apply[T: ru.TypeTag : ClassTag] : InternalInfo[T] = new InternalInfo[T](None)
}
object InternalInfo extends LowPriorityInternalInfo { }
@@ -173,12 +175,12 @@ class Power[ReplValsImpl <: ReplVals : TypeTag](val intp: IMain, replVals: ReplV
* of the conveniences exist on that wrapper.
*/
trait LowPriorityInternalInfoWrapper {
- implicit def apply[T: TypeTag] : InternalInfoWrapper[T] = new InternalInfoWrapper[T](None)
+ implicit def apply[T: ru.TypeTag : ClassTag] : InternalInfoWrapper[T] = new InternalInfoWrapper[T](None)
}
object InternalInfoWrapper extends LowPriorityInternalInfoWrapper {
}
- class InternalInfoWrapper[T: TypeTag](value: Option[T] = None) {
+ class InternalInfoWrapper[T: ru.TypeTag : ClassTag](value: Option[T] = None) {
def ? : InternalInfo[T] = new InternalInfo[T](value)
}
@@ -186,8 +188,8 @@ class Power[ReplValsImpl <: ReplVals : TypeTag](val intp: IMain, replVals: ReplV
* translate tag type arguments into applied types
* customizable symbol filter (had to hardcode no-spec to reduce noise)
*/
- class InternalInfo[T: TypeTag](value: Option[T] = None) {
- private def newInfo[U: TypeTag](value: U): InternalInfo[U] = new InternalInfo[U](Some(value))
+ class InternalInfo[T](value: Option[T] = None)(implicit typeEvidence: ru.TypeTag[T], erasureEvidence: ClassTag[T]) {
+ private def newInfo[U: ru.TypeTag : ClassTag](value: U): InternalInfo[U] = new InternalInfo[U](Some(value))
private def isSpecialized(s: Symbol) = s.name.toString contains "$mc"
private def isImplClass(s: Symbol) = s.name.toString endsWith "$class"
@@ -226,8 +228,8 @@ class Power[ReplValsImpl <: ReplVals : TypeTag](val intp: IMain, replVals: ReplV
def pkgClasses = pkgMembers filter (s => s.isClass && s.isDefinedInPackage)
def pkgSymbols = new PackageSlurper(pkgClass).slurp() filterNot excludeMember
- def tag = typeTag[T]
- def erasure = tag.erasure
+ def tag = typeEvidence
+ def erasure = erasureEvidence.erasure
def shortClass = erasure.getName split "[$.]" last
def baseClasses = tpe.baseClasses
@@ -236,9 +238,9 @@ class Power[ReplValsImpl <: ReplVals : TypeTag](val intp: IMain, replVals: ReplV
def ancestorDeclares(name: String) = ancestors filter (_.info member newTermName(name) ne NoSymbol)
def baseTypes = tpe.baseTypeSeq.toList
- def <:<[U: TypeTag](other: U) = tpe <:< newInfo(other).tpe
- def lub[U: TypeTag](other: U) = intp.global.lub(List(tpe, newInfo(other).tpe))
- def glb[U: TypeTag](other: U) = intp.global.glb(List(tpe, newInfo(other).tpe))
+ def <:<[U: ru.TypeTag : ClassTag](other: U) = tpe <:< newInfo(other).tpe
+ def lub[U: ru.TypeTag : ClassTag](other: U) = intp.global.lub(List(tpe, newInfo(other).tpe))
+ def glb[U: ru.TypeTag : ClassTag](other: U) = intp.global.glb(List(tpe, newInfo(other).tpe))
override def toString = value match {
case Some(x) => "%s (%s)".format(x, shortClass)
@@ -362,7 +364,7 @@ class Power[ReplValsImpl <: ReplVals : TypeTag](val intp: IMain, replVals: ReplV
implicit lazy val powerSymbolOrdering: Ordering[Symbol] = Ordering[Name] on (_.name)
implicit lazy val powerTypeOrdering: Ordering[Type] = Ordering[Symbol] on (_.typeSymbol)
- implicit def replInternalInfo[T: TypeTag](x: T): InternalInfoWrapper[T] = new InternalInfoWrapper[T](Some(x))
+ implicit def replInternalInfo[T: ru.TypeTag : ClassTag](x: T): InternalInfoWrapper[T] = new InternalInfoWrapper[T](Some(x))
implicit def replEnhancedStrings(s: String): RichReplString = new RichReplString(s)
implicit def replMultiPrinting[T: Prettifier](xs: TraversableOnce[T]): MultiPrettifierClass[T] =
new MultiPrettifierClass[T](xs.toSeq)
@@ -378,12 +380,12 @@ class Power[ReplValsImpl <: ReplVals : TypeTag](val intp: IMain, replVals: ReplV
trait ReplUtilities {
// [Eugene to Paul] needs review!
- // def module[T: TypeTag] = getModuleIfDefined(typeTag[T].erasure.getName stripSuffix nme.MODULE_SUFFIX_STRING)
- // def clazz[T: TypeTag] = getClassIfDefined(typeTag[T].erasure.getName)
- def module[T: TypeTag] = typeTag[T].sym.suchThat(_.isPackage)
- def clazz[T: TypeTag] = typeTag[T].sym.suchThat(_.isClass)
- def info[T: TypeTag] = InternalInfo[T]
- def ?[T: TypeTag] = InternalInfo[T]
+ // def module[T: Manifest] = getModuleIfDefined(manifest[T].erasure.getName stripSuffix nme.MODULE_SUFFIX_STRING)
+ // def clazz[T: Manifest] = getClassIfDefined(manifest[T].erasure.getName)
+ def module[T: ru.TypeTag] = ru.typeOf[T].typeSymbol.suchThat(_.isPackage)
+ def clazz[T: ru.TypeTag] = ru.typeOf[T].typeSymbol.suchThat(_.isClass)
+ def info[T: ru.TypeTag : ClassTag] = InternalInfo[T]
+ def ?[T: ru.TypeTag : ClassTag] = InternalInfo[T]
def url(s: String) = {
try new URL(s)
catch { case _: MalformedURLException =>
diff --git a/src/compiler/scala/tools/nsc/interpreter/ReplVals.scala b/src/compiler/scala/tools/nsc/interpreter/ReplVals.scala
index 280247f20c..ff99cd47da 100644
--- a/src/compiler/scala/tools/nsc/interpreter/ReplVals.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/ReplVals.scala
@@ -6,8 +6,9 @@
package scala.tools.nsc
package interpreter
-import scala.reflect.{mirror => rm}
import language.implicitConversions
+import scala.reflect.base.{Universe => BaseUniverse}
+import scala.reflect.runtime.{universe => ru}
/** A class which the repl utilizes to expose predefined objects.
* The base implementation is empty; the standard repl implementation
@@ -64,15 +65,15 @@ object ReplVals {
* I have this forwarder which widens the type and then cast the result back
* to the dependent type.
*/
- def compilerTypeFromTag(t: rm.TypeTag[_]): Global#Type =
+ def compilerTypeFromTag(t: BaseUniverse # TypeTag[_]): Global#Type =
definitions.compilerTypeFromTag(t)
class AppliedTypeFromTags(sym: Symbol) {
- def apply[M](implicit m1: rm.TypeTag[M]): Type =
+ def apply[M](implicit m1: ru.TypeTag[M]): Type =
if (sym eq NoSymbol) NoType
else appliedType(sym, compilerTypeFromTag(m1).asInstanceOf[Type])
- def apply[M1, M2](implicit m1: rm.TypeTag[M1], m2: rm.TypeTag[M2]): Type =
+ def apply[M1, M2](implicit m1: ru.TypeTag[M1], m2: ru.TypeTag[M2]): Type =
if (sym eq NoSymbol) NoType
else appliedType(sym, compilerTypeFromTag(m1).asInstanceOf[Type], compilerTypeFromTag(m2).asInstanceOf[Type])
}
diff --git a/src/compiler/scala/tools/nsc/interpreter/TypeStrings.scala b/src/compiler/scala/tools/nsc/interpreter/TypeStrings.scala
index 5d5123811e..cea9b9e112 100644
--- a/src/compiler/scala/tools/nsc/interpreter/TypeStrings.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/TypeStrings.scala
@@ -10,7 +10,7 @@ import java.lang.{ reflect => r }
import r.TypeVariable
import scala.reflect.NameTransformer
import NameTransformer._
-import scala.reflect.{mirror => rm}
+import scala.reflect.runtime.{universe => ru}
import typechecker.DestructureTypes
import scala.tools.util.StringOps.ojoin
@@ -192,7 +192,7 @@ trait TypeStrings {
else enclClass.getName + "." + (name stripPrefix enclPre)
)
}
- def scalaName(m: ClassTag[_]): String = scalaName(m.erasure)
+ def scalaName(ct: ClassTag[_]): String = scalaName(ct.erasure)
def anyClass(x: Any): JClass = if (x == null) null else x.getClass
private def brackets(tps: String*): String =
@@ -209,10 +209,12 @@ trait TypeStrings {
brackets(clazz.getTypeParameters map tvarString: _*)
}
- private def tparamString[T: TypeTag] : String = {
- // [Eugene to Paul] needs review!!
- def typeArguments: List[rm.Type] = typeTag[T].tpe.typeArguments
- def typeVariables: List[java.lang.Class[_]] = typeArguments map (targ => rm.typeToClass(targ))
+ private def tparamString[T: ru.TypeTag] : String = {
+ // [Eugene++ to Paul] needs review!!
+ def typeArguments: List[ru.Type] = ru.typeOf[T].typeArguments
+ // [Eugene++] todo. need to use not the `rootMirror`, but a mirror with the REPL's classloader
+ // how do I get to it? acquiring context classloader seems unreliable because of multithreading
+ def typeVariables: List[java.lang.Class[_]] = typeArguments map (targ => ru.rootMirror.runtimeClass(targ))
brackets(typeArguments map (jc => tvarString(List(jc))): _*)
}
@@ -224,10 +226,10 @@ trait TypeStrings {
* practice to rely on toString for correctness) generated the VALID string
* representation of the type.
*/
- def fromTypedValue[T: TypeTag](x: T): String = fromTag[T]
- def fromValue(value: Any): String = if (value == null) "Null" else fromClazz(anyClass(value))
- def fromClazz(clazz: JClass): String = scalaName(clazz) + tparamString(clazz)
- def fromTag[T: TypeTag] : String = scalaName(typeTag[T].erasure) + tparamString[T]
+ def fromTypedValue[T: ru.TypeTag : ClassTag](x: T): String = fromTag[T]
+ def fromValue(value: Any): String = if (value == null) "Null" else fromClazz(anyClass(value))
+ def fromClazz(clazz: JClass): String = scalaName(clazz) + tparamString(clazz)
+ def fromTag[T: ru.TypeTag : ClassTag] : String = scalaName(classTag[T].erasure) + tparamString[T]
/** Reducing fully qualified noise for some common packages.
*/
diff --git a/src/compiler/scala/tools/nsc/io/AbstractFile.scala b/src/compiler/scala/tools/nsc/io/AbstractFile.scala
index deb914f806..08b9df2fa8 100644
--- a/src/compiler/scala/tools/nsc/io/AbstractFile.scala
+++ b/src/compiler/scala/tools/nsc/io/AbstractFile.scala
@@ -10,7 +10,6 @@ package io
import java.io.{ FileOutputStream, IOException, InputStream, OutputStream, BufferedOutputStream }
import java.net.URL
import scala.collection.mutable.ArrayBuffer
-import scala.reflect.api.RequiredFile
/**
* @author Philippe Altherr
@@ -82,7 +81,7 @@ object AbstractFile {
* <code>global.settings.encoding.value</code>.
* </p>
*/
-abstract class AbstractFile extends AnyRef with RequiredFile with Iterable[AbstractFile] {
+abstract class AbstractFile extends reflect.internal.AbstractFileApi with Iterable[AbstractFile] {
/** Returns the name of this abstract file. */
def name: String
diff --git a/src/compiler/scala/tools/nsc/scratchpad/Executor.scala b/src/compiler/scala/tools/nsc/scratchpad/Executor.scala
index 8a918a829c..89523df71e 100644
--- a/src/compiler/scala/tools/nsc/scratchpad/Executor.scala
+++ b/src/compiler/scala/tools/nsc/scratchpad/Executor.scala
@@ -4,7 +4,7 @@ import java.io.{PrintStream, OutputStreamWriter, Writer}
import scala.runtime.ScalaRunTime.stringOf
import java.lang.reflect.InvocationTargetException
-import scala.reflect.ReflectionUtils._
+import scala.reflect.runtime.ReflectionUtils._
object Executor {
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
index 7373a610d7..d8bf23f4fe 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
@@ -183,7 +183,7 @@ abstract class ClassfileParser {
if (in.buf(start).toInt != CONSTANT_CLASS) errorBadTag(start)
val name = getExternalName(in.getChar(start + 1))
if (nme.isModuleName(name))
- c = definitions.getModule(nme.stripModuleSuffix(name))
+ c = rootMirror.getModule(nme.stripModuleSuffix(name))
else
c = classNameToSymbol(name)
@@ -234,7 +234,7 @@ abstract class ClassfileParser {
//assert(name.endsWith("$"), "Not a module class: " + name)
f = forceMangledName(name dropRight 1, true)
if (f == NoSymbol)
- f = definitions.getModule(name dropRight 1)
+ f = rootMirror.getModule(name dropRight 1)
} else {
val origName = nme.originalName(name)
val owner = if (static) ownerTpe.typeSymbol.linkedClassOfClass else ownerTpe.typeSymbol
@@ -417,7 +417,7 @@ abstract class ClassfileParser {
*/
def forceMangledName(name: Name, module: Boolean): Symbol = {
val parts = name.decode.toString.split(Array('.', '$'))
- var sym: Symbol = definitions.RootClass
+ var sym: Symbol = rootMirror.RootClass
// was "at flatten.prev"
beforeFlatten {
@@ -445,7 +445,7 @@ abstract class ClassfileParser {
return NoSymbol.newClass(name.toTypeName)
}
val completer = new global.loaders.ClassfileLoader(file)
- var owner: Symbol = definitions.RootClass
+ var owner: Symbol = rootMirror.RootClass
var sym: Symbol = NoSymbol
var ss: Name = null
var start = 0
@@ -473,9 +473,9 @@ abstract class ClassfileParser {
def lookupClass(name: Name) = try {
if (name.pos('.') == name.length)
- definitions.getMember(definitions.EmptyPackageClass, name.toTypeName)
+ definitions.getMember(rootMirror.EmptyPackageClass, name.toTypeName)
else
- definitions.getClass(name) // see tickets #2464, #3756
+ rootMirror.getClass(name) // see tickets #2464, #3756
} catch {
case _: FatalError => loadClassSymbol(name)
}
@@ -919,7 +919,7 @@ abstract class ClassfileParser {
val srcfileLeaf = pool.getName(in.nextChar).toString.trim
val srcpath = sym.enclosingPackage match {
case NoSymbol => srcfileLeaf
- case definitions.EmptyPackage => srcfileLeaf
+ case rootMirror.EmptyPackage => srcfileLeaf
case pkg => pkg.fullName(File.separatorChar)+File.separator+srcfileLeaf
}
srcfile0 = settings.outputDirs.srcFilesFor(in.file, srcpath).find(_.exists)
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala
index 862a3ffdc7..bb9f9bde98 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala
@@ -165,21 +165,21 @@ abstract class ICodeReader extends ClassfileParser {
else if (name == fulltpnme.RuntimeNull)
definitions.NullClass
else if (nme.isImplClassName(name)) {
- val iface = definitions.getClass(tpnme.interfaceName(name))
+ val iface = rootMirror.getClassByName(tpnme.interfaceName(name))
log("forcing " + iface.owner + " at phase: " + phase + " impl: " + iface.implClass)
iface.owner.info // force the mixin type-transformer
- definitions.getClass(name)
+ rootMirror.getClassByName(name)
}
else if (nme.isModuleName(name)) {
val strippedName = nme.stripModuleSuffix(name)
val sym = forceMangledName(newTermName(strippedName.decode), true)
- if (sym == NoSymbol) definitions.getModule(strippedName)
+ if (sym == NoSymbol) rootMirror.getModule(strippedName)
else sym
}
else {
forceMangledName(name, false)
- afterFlatten(definitions.getClass(name.toTypeName))
+ afterFlatten(rootMirror.getClassByName(name.toTypeName))
}
if (sym.isModule)
sym.moduleClass
diff --git a/src/compiler/scala/tools/nsc/symtab/clr/TypeParser.scala b/src/compiler/scala/tools/nsc/symtab/clr/TypeParser.scala
index 028d6f2484..e54ecdd590 100644
--- a/src/compiler/scala/tools/nsc/symtab/clr/TypeParser.scala
+++ b/src/compiler/scala/tools/nsc/symtab/clr/TypeParser.scala
@@ -653,7 +653,7 @@ abstract class TypeParser {
private def getClassType(typ: MSILType): Type = {
assert(typ != null);
- val res = definitions.getClass(typ.FullName.replace('+', '.')).tpe;
+ val res = rootMirror.getClassByName(typ.FullName.replace('+', '.')).tpe;
//if (res.isError())
// global.reporter.error("unknown class reference " + type.FullName);
res
diff --git a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
index 9cffb6a1e1..6d6430207d 100644
--- a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
+++ b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
@@ -385,7 +385,7 @@ abstract class ExplicitOuter extends InfoTransform
method setInfo new MethodType(params, BooleanClass.tpe)
localTyper typed {
- DEF(method) === guard.changeOwner(currentOwner -> method).substTreeSyms(vs zip params: _*)
+ DEF(method) === guard.changeOwner(currentOwner -> method).substituteSymbols(vs, params)
}
}
diff --git a/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala b/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala
index 8556cc9ddc..31d804b4b5 100644
--- a/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala
+++ b/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala
@@ -138,9 +138,9 @@ abstract class ExtensionMethods extends Transform with TypingTransformers {
val GenPolyType(extensionTpeParams, extensionMono) = extensionMeth.info
val origTpeParams = (tparams map (_.symbol)) ::: currentOwner.typeParams
val extensionBody = rhs
- .substTreeSyms(origTpeParams, extensionTpeParams)
- .substTreeSyms(vparamss.flatten map (_.symbol), allParams(extensionMono).tail)
- .substTreeThis(currentOwner, thisParamRef)
+ .substituteSymbols(origTpeParams, extensionTpeParams)
+ .substituteSymbols(vparamss.flatten map (_.symbol), allParams(extensionMono).tail)
+ .substituteThis(currentOwner, thisParamRef)
.changeOwner((origMeth, extensionMeth))
extensionDefs(companion) += atPos(tree.pos) { DefDef(extensionMeth, extensionBody) }
val extensionCallPrefix = Apply(
diff --git a/src/compiler/scala/tools/nsc/transform/Mixin.scala b/src/compiler/scala/tools/nsc/transform/Mixin.scala
index 79b9317f20..fe5bef5009 100644
--- a/src/compiler/scala/tools/nsc/transform/Mixin.scala
+++ b/src/compiler/scala/tools/nsc/transform/Mixin.scala
@@ -477,7 +477,7 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
/** The rootContext used for typing */
private val rootContext =
- erasure.NoContext.make(EmptyTree, RootClass, newScope)
+ erasure.NoContext.make(EmptyTree, rootMirror.RootClass, newScope)
/** The typer */
private var localTyper: erasure.Typer = _
diff --git a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
index f2e109a5ad..d45db9ea5d 100644
--- a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
+++ b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
@@ -66,11 +66,12 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
private implicit val typeOrdering: Ordering[Type] = Ordering[String] on ("" + _.typeSymbol.name)
import definitions.{
- RootClass, BooleanClass, UnitClass, ArrayClass,
+ BooleanClass, UnitClass, ArrayClass,
ScalaValueClasses, isPrimitiveValueClass, isPrimitiveValueType,
SpecializedClass, UnspecializedClass, AnyRefClass, ObjectClass, AnyRefModule,
GroupOfSpecializable, uncheckedVarianceClass, ScalaInlineClass
}
+ import rootMirror.RootClass
/** TODO - this is a lot of maps.
*/
@@ -434,7 +435,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
val sClassMap = anyrefSpecCache.getOrElseUpdate(sClass, mutable.Map[Symbol, Symbol]())
sClassMap.getOrElseUpdate(tparam,
- tparam.cloneSymbol(sClass, tparam.flags, tparam.name append tpnme.SPECIALIZED_SUFFIX)
+ tparam.cloneSymbol(sClass, tparam.flags, (tparam.name append tpnme.SPECIALIZED_SUFFIX).asInstanceOf[Name]) // [Eugene++] why do we need this cast?
modifyInfo (info => TypeBounds(info.bounds.lo, AnyRefClass.tpe))
).tpe
}
@@ -1695,7 +1696,10 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
private def forwardCall(pos: util.Position, receiver: Tree, paramss: List[List[ValDef]]): Tree = {
val argss = mmap(paramss)(x => Ident(x.symbol))
- atPos(pos) { (receiver /: argss) (Apply) }
+ def mkApply(fun: Tree, args: List[Tree]) = Apply(fun, args)
+ atPos(pos) { (receiver /: argss) (mkApply) }
+ // [Eugene++] no longer compiles after I moved the `Apply` case class into scala.reflect.internal
+ // atPos(pos) { (receiver /: argss) (Apply) }
}
/** Forward to the generic class constructor. If the current class initializes
@@ -1737,7 +1741,10 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
else
Ident(x.symbol)
)
- atPos(pos) { (receiver /: argss) (Apply) }
+ def mkApply(fun: Tree, args: List[Tree]) = Apply(fun, args)
+ atPos(pos) { (receiver /: argss) (mkApply) }
+ // [Eugene++] no longer compiles after I moved the `Apply` case class into scala.reflect.internal
+ // atPos(pos) { (receiver /: argss) (Apply) }
}
/** Add method m to the set of symbols for which we need an implementation tree
diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
index f4f081252f..ac3c94c47a 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
@@ -30,9 +30,9 @@ trait Contexts { self: Analyzer =>
private val startContext = {
NoContext.make(
- global.Template(List(), emptyValDef, List()) setSymbol global.NoSymbol setType global.NoType,
- global.definitions.RootClass,
- global.definitions.RootClass.info.decls)
+ Template(List(), emptyValDef, List()) setSymbol global.NoSymbol setType global.NoType,
+ rootMirror.RootClass,
+ rootMirror.RootClass.info.decls)
}
var lastAccessCheckDetails: String = ""
@@ -543,7 +543,7 @@ trait Contexts { self: Analyzer =>
(pre == NoPrefix) || {
val ab = sym.accessBoundary(sym.owner)
- ( (ab.isTerm || ab == definitions.RootClass)
+ ( (ab.isTerm || ab == rootMirror.RootClass)
|| (accessWithin(ab) || accessWithinLinked(ab)) &&
( !sym.hasLocalFlag
|| sym.owner.isImplClass // allow private local accesses to impl classes
diff --git a/src/compiler/scala/tools/nsc/typechecker/DestructureTypes.scala b/src/compiler/scala/tools/nsc/typechecker/DestructureTypes.scala
index 0b414801d6..aebe3454b1 100644
--- a/src/compiler/scala/tools/nsc/typechecker/DestructureTypes.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/DestructureTypes.scala
@@ -64,7 +64,7 @@ trait DestructureTypes {
case x: NameTree => atom(x.name.toString, x)
case _ => wrapAtom(tree)
},
- tree.printingPrefix
+ tree.productPrefix
)
def wrapSymbol(label: String, sym: Symbol): Node = {
if (sym eq NoSymbol) wrapEmpty
diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
index 6a2a9b850c..f3afa2d33f 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
@@ -1133,7 +1133,6 @@ trait Implicits {
private def TagSymbols = TagMaterializers.keySet
private val TagMaterializers = Map[Symbol, Symbol](
ArrayTagClass -> MacroInternal_materializeArrayTag,
- ErasureTagClass -> MacroInternal_materializeErasureTag,
ClassTagClass -> MacroInternal_materializeClassTag,
TypeTagClass -> MacroInternal_materializeTypeTag,
ConcreteTypeTagClass -> MacroInternal_materializeConcreteTypeTag
@@ -1166,9 +1165,9 @@ trait Implicits {
}
val prefix = (
- // ClassTags only exist for scala.reflect.mirror, so their materializer
+ // ClassTags and ArrayTags only exist for scala.reflect, so their materializer
// doesn't care about prefixes
- if ((tagClass eq ArrayTagClass) || (tagClass eq ErasureTagClass) || (tagClass eq ClassTagClass)) ReflectMirrorPrefix
+ if ((tagClass eq ArrayTagClass) || (tagClass eq ClassTagClass)) gen.mkBasisUniverseRef
else pre match {
// [Eugene to Martin] this is the crux of the interaction between
// implicits and reifiers here we need to turn a (supposedly
@@ -1295,13 +1294,33 @@ trait Implicits {
}
val tagInScope =
- if (full) context.withMacrosDisabled(resolveTypeTag(ReflectMirrorPrefix.tpe, tp, pos, true))
- else context.withMacrosDisabled(resolveArrayTag(tp, pos))
+ if (full) resolveTypeTag(NoType, tp, pos, concrete = true)
+ else resolveArrayTag(tp, pos)
if (tagInScope.isEmpty) mot(tp, Nil, Nil)
else {
+ if (full) {
+ if (ReflectRuntimeUniverse == NoSymbol) {
+ // todo. write a test for this
+ context.error(pos, s"""
+ |to create a manifest here, it is necessary to interoperate with the type tag `$tagInScope` in scope.
+ |however typetag -> manifest conversion requires Scala reflection, which is not present on the classpath.
+ |to proceed put scala-reflect.jar on your compilation classpath and recompile.""".trim.stripMargin)
+ return SearchFailure
+ }
+ if (resolveErasureTag(tp, pos, concrete = true) == EmptyTree) {
+ context.error(pos, s"""
+ |to create a manifest here, it is necessary to interoperate with the type tag `$tagInScope` in scope.
+ |however typetag -> manifest conversion requires a class tag for the corresponding type to be present.
+ |to proceed add a class tag to the type `$tp` (e.g. by introducing a context bound) and recompile.""".trim.stripMargin)
+ return SearchFailure
+ }
+ }
+
val interop =
- if (full) gen.mkMethodCall(ReflectPackage, nme.concreteTypeTagToManifest, List(tp), List(tagInScope))
- else gen.mkMethodCall(ReflectPackage, nme.arrayTagToClassManifest, List(tp), List(tagInScope))
+ if (full) {
+ val cm = typed(Ident(ReflectRuntimeCurrentMirror))
+ gen.mkMethodCall(ReflectRuntimeUniverse, nme.concreteTypeTagToManifest, List(tp), List(cm, tagInScope))
+ } else gen.mkMethodCall(ReflectRuntimeUniverse, nme.arrayTagToClassManifest, List(tp), List(tagInScope))
wrapResult(interop)
}
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
index 85c2aebfab..1ed9350d3f 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
@@ -187,7 +187,7 @@ trait Infer {
tp1 // @MAT aliases already handled by subtyping
}
- private val stdErrorClass = RootClass.newErrorClass(tpnme.ERROR)
+ private val stdErrorClass = rootMirror.RootClass.newErrorClass(tpnme.ERROR)
private val stdErrorValue = stdErrorClass.newErrorValue(nme.ERROR)
/** The context-dependent inferencer part */
diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala
index 8895642893..ed3f372cb2 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala
@@ -4,7 +4,7 @@ package typechecker
import symtab.Flags._
import scala.tools.nsc.util._
import scala.tools.nsc.util.ClassPath._
-import scala.reflect.ReflectionUtils
+import scala.reflect.runtime.ReflectionUtils
import scala.collection.mutable.ListBuffer
import scala.compat.Platform.EOL
import util.Statistics._
@@ -796,7 +796,7 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces {
def collectMacroArgs(tree: Tree): Unit = tree match {
case Apply(fn, args) =>
// todo. infer precise typetag for this Expr, namely the declared type of the corresponding macro impl argument
- exprArgs.prepend(args map (Expr(_)(TypeTag.Nothing)))
+ exprArgs.prepend(args map (arg => Expr(rootMirror, FixedMirrorTreeCreator(rootMirror, arg))(TypeTag.Nothing)))
collectMacroArgs(fn)
case TypeApply(fn, args) =>
typeArgs = args
@@ -806,7 +806,7 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces {
case _ =>
}
collectMacroArgs(expandee)
- val context = expandee.attachmentOpt[MacroAttachment].flatMap(_.macroContext).getOrElse(macroContext(typer, prefixTree, expandee))
+ val context = expandee.attachments.get[MacroAttachment].flatMap(_.macroContext).getOrElse(macroContext(typer, prefixTree, expandee))
var argss: List[List[Any]] = List(context) :: exprArgs.toList
macroTraceVerbose("argss: ")(argss)
val rawArgss =
@@ -897,13 +897,7 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces {
}
Some(tparam)
})
- val tags = paramss.last takeWhile (_.isType) map (resolved(_)) map (tpe => {
- // generally speaking, it's impossible to calculate erasure from a tpe here
- // the tpe might be compiled by this run, so its jClass might not exist yet
- // hence I just pass `null` instead and leave this puzzle to macro programmers
- val ttag = TypeTag(tpe, null)
- if (ttag.isConcrete) ttag.toConcrete else ttag
- })
+ val tags = paramss.last takeWhile (_.isType) map (resolved(_)) map (tpe => if (tpe.isConcrete) context.ConcreteTypeTag(tpe) else context.TypeTag(tpe))
if (paramss.lastOption map (params => !params.isEmpty && params.forall(_.isType)) getOrElse false) argss = argss :+ Nil
argss = argss.dropRight(1) :+ (tags ++ argss.last) // todo. add support for context bounds in argss
@@ -1059,7 +1053,7 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces {
+ "If you have troubles tracking free @kind@ variables, consider using -Xlog-free-@kind@s"
)
val forgotten = (
- if (sym.isTerm) "eval when splicing this variable into a reifee"
+ if (sym.isTerm) "splice when splicing this variable into a reifee"
else "c.TypeTag annotation for this type parameter"
)
typer.context.error(expandee.pos,
@@ -1086,8 +1080,8 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces {
macroLogVerbose("original:")
macroLogLite("" + expanded.tree + "\n" + showRaw(expanded.tree))
- freeTerms(expanded.tree) foreach issueFreeError
- freeTypes(expanded.tree) foreach issueFreeError
+ expanded.tree.freeTerms foreach issueFreeError
+ expanded.tree.freeTypes foreach issueFreeError
if (hasNewErrors) failExpansion()
// inherit the position from the first position-ful expandee in macro callstack
@@ -1121,7 +1115,7 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces {
delayed += expandee -> undetparams
// need to save typer context for `macroExpandAll`
// need to save macro context to preserve enclosures
- expandee attach MacroAttachment(delayed = true, typerContext = typer.context, macroContext = Some(context))
+ expandee addAttachment MacroAttachment(delayed = true, typerContext = typer.context, macroContext = Some(context.asInstanceOf[MacroContext]))
Delay(expandee)
}
else {
@@ -1136,7 +1130,7 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces {
case x => x
}
finally {
- expandee.detach(classOf[MacroAttachment])
+ expandee.removeAttachment[MacroAttachment]
if (!isSuccess) openMacros = openMacros.tail
}
}
@@ -1287,7 +1281,7 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces {
override def transform(tree: Tree) = super.transform(tree match {
// todo. expansion should work from the inside out
case wannabe if (delayed contains wannabe) && calculateUndetparams(wannabe).isEmpty =>
- val context = wannabe.attachment[MacroAttachment].typerContext
+ val context = wannabe.attachments.get[MacroAttachment].get.typerContext
delayed -= wannabe
context.implicitsEnabled = typer.context.implicitsEnabled
context.enrichmentEnabled = typer.context.enrichmentEnabled
diff --git a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala
index cf94f7d4d6..d26f3247da 100644
--- a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala
@@ -8,7 +8,7 @@ package typechecker
import symtab.Flags._
import scala.collection.{ mutable, immutable }
import scala.tools.util.StringOps.{ ojoin }
-import scala.reflect.{ mirror => rm }
+import scala.reflect.runtime.{ universe => ru }
import language.higherKinds
/** Logic related to method synthesis which involves cooperation between
@@ -22,7 +22,7 @@ trait MethodSynthesis {
import CODE._
object synthesisUtil {
- type CTT[T] = rm.ConcreteTypeTag[T]
+ type CTT[T] = ru.ConcreteTypeTag[T]
type CT[T] = ClassTag[T]
def ValOrDefDef(sym: Symbol, body: Tree) =
@@ -30,7 +30,7 @@ trait MethodSynthesis {
else DefDef(sym, body)
def applyTypeInternal(tags: List[CTT[_]]): Type = {
- // [Eugene to Paul] needs review!!
+ // [Eugene++ to Paul] needs review!!
val symbols = tags map compilerSymbolFromTag
val container :: args = symbols
val tparams = container.typeConstructor.typeParams
@@ -44,26 +44,33 @@ trait MethodSynthesis {
appliedType(container, args map (_.tpe): _*)
}
- def companionType[T](implicit m: CTT[T]) =
- getRequiredModule(m.erasure.getName).tpe
+ def companionType[T](implicit ct: CT[T]) =
+ rootMirror.getRequiredModule(ct.erasure.getName).tpe
// Use these like `applyType[List, Int]` or `applyType[Map, Int, String]`
- def applyType[CC](implicit m1: CTT[CC]): Type =
- applyTypeInternal(List(m1))
+ def applyType[CC](implicit t1: CTT[CC]): Type =
+ applyTypeInternal(List(t1))
- def applyType[CC[X1], X1](implicit m1: CTT[CC[_]], m2: CTT[X1]): Type =
- applyTypeInternal(List(m1, m2))
+ def applyType[CC[X1], X1](implicit t1: CTT[CC[_]], t2: CTT[X1]): Type =
+ applyTypeInternal(List[CTT[_]](t1, t2))
- def applyType[CC[X1, X2], X1, X2](implicit m1: CTT[CC[_,_]], m2: CTT[X1], m3: CTT[X2]): Type =
- applyTypeInternal(List(m1, m2, m3))
+ def applyType[CC[X1, X2], X1, X2](implicit t1: CTT[CC[_,_]], t2: CTT[X1], t3: CTT[X2]): Type =
+ // [Eugene++] without an explicit type annotation for List, we get this:
+ // [scalacfork] C:\Projects\KeplerUnderRefactoring\src\compiler\scala\tools\nsc\typechecker\MethodSynthesis.scala:59: error: no type parameters for method apply: (xs: A*)List[A] in object List exist so that it can be applied to arguments (scala.tools.nsc.typechecker.MethodSynthesis.synthesisUtil.CTT[CC[_, _]], scala.tools.nsc.typechecker.MethodSynthesis.synthesisUtil.CTT[X1], scala.tools.nsc.typechecker.MethodSynthesis.synthesisUtil.CTT[X2])
+ // [scalacfork] --- because ---
+ // [scalacfork] undetermined type
+ // [scalacfork] applyTypeInternal(List(t1, t2, t3))
+ applyTypeInternal(List[CTT[_]](t1, t2, t3))
- def applyType[CC[X1, X2, X3], X1, X2, X3](implicit m1: CTT[CC[_,_,_]], m2: CTT[X1], m3: CTT[X2], m4: CTT[X3]): Type =
- applyTypeInternal(List(m1, m2, m3, m4))
+ def applyType[CC[X1, X2, X3], X1, X2, X3](implicit t1: CTT[CC[_,_,_]], t2: CTT[X1], t3: CTT[X2], t4: CTT[X3]): Type =
+ applyTypeInternal(List[CTT[_]](t1, t2, t3, t4))
+ // [Martin->Eugene] !!! reinstantiate when typeables are in.
+ // [Eugene++->Martin] now this compiles, will soon check it out
def newMethodType[F](owner: Symbol)(implicit t: CTT[F]): Type = {
val fnSymbol = compilerSymbolFromTag(t)
assert(fnSymbol isSubClass FunctionClass(t.tpe.typeArguments.size - 1), (owner, t))
- // [Eugene to Paul] needs review!!
+ // [Eugene++ to Paul] needs review!!
// val symbols = m.typeArguments map (m => manifestToSymbol(m))
// val formals = symbols.init map (_.typeConstructor)
val formals = compilerTypeFromTag(t).typeArguments
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
index 4eba665b93..decd18b599 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -313,7 +313,7 @@ trait Namers extends MethodSynthesis {
/** All PackageClassInfoTypes come from here. */
private def createPackageSymbol(pos: Position, pid: RefTree): Symbol = {
val pkgOwner = pid match {
- case Ident(_) => if (owner == EmptyPackageClass) RootClass else owner
+ case Ident(_) => if (owner.isEmptyPackageClass) rootMirror.RootClass else owner
case Select(qual: RefTree, _) => createPackageSymbol(pos, qual).moduleClass
}
val existing = pkgOwner.info.decls.lookup(pid.name)
diff --git a/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala b/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala
index 48985213d1..eb77ec8224 100644
--- a/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala
@@ -53,11 +53,11 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
else noopTransformer
// duplicated from CPSUtils (avoid dependency from compiler -> cps plugin...)
- private lazy val MarkerCPSAdaptPlus = definitions.getClassIfDefined("scala.util.continuations.cpsPlus")
- private lazy val MarkerCPSAdaptMinus = definitions.getClassIfDefined("scala.util.continuations.cpsMinus")
- private lazy val MarkerCPSSynth = definitions.getClassIfDefined("scala.util.continuations.cpsSynth")
+ private lazy val MarkerCPSAdaptPlus = rootMirror.getClassIfDefined("scala.util.continuations.cpsPlus")
+ private lazy val MarkerCPSAdaptMinus = rootMirror.getClassIfDefined("scala.util.continuations.cpsMinus")
+ private lazy val MarkerCPSSynth = rootMirror.getClassIfDefined("scala.util.continuations.cpsSynth")
private lazy val stripTriggerCPSAnns = List(MarkerCPSSynth, MarkerCPSAdaptMinus, MarkerCPSAdaptPlus)
- private lazy val MarkerCPSTypes = definitions.getClassIfDefined("scala.util.continuations.cpsParam")
+ private lazy val MarkerCPSTypes = rootMirror.getClassIfDefined("scala.util.continuations.cpsParam")
private lazy val strippedCPSAnns = MarkerCPSTypes :: stripTriggerCPSAnns
private def removeCPSAdaptAnnotations(tp: Type) = tp filterAnnotations (ann => !(strippedCPSAnns exists (ann matches _)))
@@ -204,7 +204,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
// the alternative to attaching the default case override would be to simply
// append the default to the list of cases and suppress the unreachable case error that may arise (once we detect that...)
- val matchFailGenOverride = match_ firstAttachment {case DefaultOverrideMatchAttachment(default) => ((scrut: Tree) => default)}
+ val matchFailGenOverride = match_.attachments.get[DefaultOverrideMatchAttachment].map{case DefaultOverrideMatchAttachment(default) => ((scrut: Tree) => default)}
val selectorSym = freshSym(selector.pos, pureType(selectorTp)) setFlag SYNTH_CASE
// pt = Any* occurs when compiling test/files/pos/annotDepMethType.scala with -Xexperimental
@@ -1488,7 +1488,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
// hashconsing trees (modulo value-equality)
def unique(t: Tree, tpOverride: Type = NoType): Tree =
- trees find (a => a.equalsStructure0(t)(sameValue)) match {
+ trees find (a => a.correspondsStructure(t)(sameValue)) match {
case Some(orig) => orig // patmatDebug("unique: "+ (t eq orig, orig));
case _ =>
trees += t
diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
index 553294d0fe..26cf246ed7 100644
--- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
@@ -285,7 +285,7 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R
def memberTp = self.memberType(member)
def otherTp = self.memberType(other)
def noErrorType = other.tpe != ErrorType && member.tpe != ErrorType
- def isRootOrNone(sym: Symbol) = sym == RootClass || sym == NoSymbol
+ def isRootOrNone(sym: Symbol) = sym != null && sym.isRoot || sym == NoSymbol
def isNeitherInClass = (member.owner != clazz) && (other.owner != clazz)
def objectOverrideErrorMsg = (
"overriding " + other.fullLocationString + " with " + member.fullLocationString + ":\n" +
diff --git a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
index d327d9c397..daae69590f 100644
--- a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
@@ -246,7 +246,7 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT
&& sym.isProtected
&& sym.enclClass != currentClass
&& !sym.owner.isTrait
- && (sym.owner.enclosingPackageClass != currentPackage)
+ && (sym.owner.enclosingPackageClass != currentClass.enclosingPackageClass)
&& (qual.symbol.info.member(sym.name) ne NoSymbol)
)
if (shouldEnsureAccessor) {
@@ -451,7 +451,7 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT
&& sym.isJavaDefined
&& !sym.isDefinedInPackage
&& !accessibleThroughSubclassing
- && (sym.enclosingPackageClass != currentPackage)
+ && (sym.enclosingPackageClass != currentClass.enclosingPackageClass)
&& (sym.enclosingPackageClass == sym.accessBoundary(sym.enclosingPackageClass))
)
val host = hostForAccessorOf(sym, clazz)
diff --git a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
index 6faa9a3cb7..f01e095856 100644
--- a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
@@ -63,7 +63,7 @@ trait SyntheticMethods extends ast.TreeDSL {
// in the original order.
def accessors = clazz.caseFieldAccessors sortBy { acc =>
originalAccessors indexWhere { orig =>
- (acc.name == orig.name) || (acc.name startsWith (orig.name append "$"))
+ (acc.name == orig.name) || (acc.name startsWith (orig.name append "$").asInstanceOf[Name]) // [Eugene++] why do we need this cast?
}
}
val arity = accessors.size
@@ -87,7 +87,7 @@ trait SyntheticMethods extends ast.TreeDSL {
)
def forwardToRuntime(method: Symbol): Tree =
- forwardMethod(method, getMember(ScalaRunTimeModule, method.name prepend "_"))(mkThis :: _)
+ forwardMethod(method, getMember(ScalaRunTimeModule, (method.name prepend "_").asInstanceOf[Name]))(mkThis :: _) // [Eugene++] why do we need this cast?
def callStaticsMethod(name: String)(args: Tree*): Tree = {
val method = termMember(RuntimeStaticsModule, name)
diff --git a/src/compiler/scala/tools/nsc/typechecker/Taggings.scala b/src/compiler/scala/tools/nsc/typechecker/Taggings.scala
index fb0d6fb3c5..bbcfa2920b 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Taggings.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Taggings.scala
@@ -48,7 +48,7 @@ trait Taggings {
* EmptyTree if `concrete` is true and the result contains unresolved (i.e. not spliced) type parameters and abstract type members.
*/
def resolveErasureTag(tp: Type, pos: Position, concrete: Boolean): Tree = {
- val taggedTp = appliedType(if (concrete) ClassTagClass.typeConstructor else ErasureTagClass.typeConstructor, List(tp))
+ val taggedTp = appliedType(if (concrete) ClassTagClass.typeConstructor else ???, List(tp))
resolveTag(taggedTp, pos)
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala b/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala
index fde760c752..b0956446a7 100644
--- a/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala
@@ -272,7 +272,7 @@ abstract class TreeCheckers extends Analyzer {
tree match {
case x: PackageDef =>
- if ((sym.ownerChain contains currentOwner) || currentOwner == definitions.EmptyPackageClass) ()
+ if ((sym.ownerChain contains currentOwner) || currentOwner.isEmptyPackageClass) ()
else fail(sym + " owner chain does not contain currentOwner " + currentOwner + sym.ownerChain)
case _ =>
def cond(s: Symbol) = !s.isTerm || s.isMethod || s == sym.owner
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index a2ef06fe38..cc36ed7428 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -1361,7 +1361,7 @@ trait Typers extends Modes with Adaptations with Taggings {
case List(acc) =>
def isUnderlyingAcc(sym: Symbol) =
sym == acc || acc.hasAccessorFlag && sym == acc.accessed
- if (acc.accessBoundary(clazz) != RootClass)
+ if (acc.accessBoundary(clazz) != rootMirror.RootClass)
unit.error(acc.pos, "value class needs to have a publicly accessible val parameter")
for (stat <- body)
if (!treeInfo.isAllowedInUniversalTrait(stat) && !isUnderlyingAcc(stat.symbol))
@@ -2315,7 +2315,7 @@ trait Typers extends Modes with Adaptations with Taggings {
import CODE._
// need to duplicate the cases before typing them to generate the apply method, or the symbols will be all messed up
- val casesTrue = if (isPartial) cases map (c => deriveCaseDef(c)(x => atPos(x.pos.focus)(TRUE_typed)).duplicate) else Nil
+ val casesTrue = if (isPartial) cases map (c => deriveCaseDef(c)(x => atPos(x.pos.focus)(TRUE_typed)).duplicate.asInstanceOf[CaseDef]) else Nil
// println("casesTrue "+ casesTrue)
def parentsPartial(targs: List[Type]) = addSerializable(appliedType(AbstractPartialFunctionClass.typeConstructor, targs))
@@ -2383,7 +2383,7 @@ trait Typers extends Modes with Adaptations with Taggings {
match_ setType B1.tpe
// the default uses applyOrElse's first parameter since the scrut's type has been widened
- val body = methodBodyTyper.virtualizedMatch(match_ withAttachment DefaultOverrideMatchAttachment(REF(default) APPLY (REF(x))), mode, B1.tpe)
+ val body = methodBodyTyper.virtualizedMatch(match_ addAttachment DefaultOverrideMatchAttachment(REF(default) APPLY (REF(x))), mode, B1.tpe)
DefDef(methodSym, body)
}
@@ -2401,7 +2401,7 @@ trait Typers extends Modes with Adaptations with Taggings {
methodSym setInfoAndEnter MethodType(paramSyms, BooleanClass.tpe)
val match_ = methodBodyTyper.typedMatch(gen.mkUnchecked(selector), casesTrue, mode, BooleanClass.tpe)
- val body = methodBodyTyper.virtualizedMatch(match_ withAttachment DefaultOverrideMatchAttachment(FALSE_typed), mode, BooleanClass.tpe)
+ val body = methodBodyTyper.virtualizedMatch(match_ addAttachment DefaultOverrideMatchAttachment(FALSE_typed), mode, BooleanClass.tpe)
DefDef(methodSym, body)
}
@@ -4402,7 +4402,7 @@ trait Typers extends Modes with Adaptations with Taggings {
// last ditch effort before failing. This method sets defSym and returns
// true if a member of the given name exists.
def checkEmptyPackage(): Boolean = {
- defSym = EmptyPackageClass.tpe.nonPrivateMember(name)
+ defSym = rootMirror.EmptyPackageClass.tpe.nonPrivateMember(name)
defSym != NoSymbol
}
def startingIdentContext = (
@@ -4530,7 +4530,7 @@ trait Typers extends Modes with Adaptations with Taggings {
log("Allowing empty package member " + name + " due to settings.")
else {
if ((mode & QUALmode) != 0) {
- val lastTry = missingHook(RootClass, name)
+ val lastTry = missingHook(rootMirror.RootClass, name)
if (lastTry != NoSymbol) return typed1(tree setSymbol lastTry, mode, pt)
}
if (settings.debug.value) {
@@ -4912,7 +4912,7 @@ trait Typers extends Modes with Adaptations with Taggings {
if (tree1.symbol != null && tree1.symbol.isOnlyRefinementMember)
checkFeature(tree1.pos, ReflectiveCallsFeature, tree1.symbol.toString)
- if (qual1.symbol == RootPackage) treeCopy.Ident(tree1, name)
+ if (qual1.hasSymbolWhich(_.isRootPackage)) treeCopy.Ident(tree1, name)
else tree1
case Ident(name) =>
diff --git a/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala b/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala
index d75e2705c3..4c20d14406 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala
@@ -224,7 +224,10 @@ trait Unapplies extends ast.TreeDSL
case Nil => Nil
case ps :: _ => mmap(ps :: funParamss)(toIdent)
}
- val body = funParamss.foldRight(New(classTpe, argss): Tree)(Function)
+ def mkFunction(vparams: List[ValDef], body: Tree) = Function(vparams, body)
+ val body = funParamss.foldRight(New(classTpe, argss): Tree)(mkFunction)
+ // [Eugene++] no longer compiles after I moved the `Function` case class into scala.reflect.internal
+ // val body = funParamss.foldRight(New(classTpe, argss): Tree)(Function)
Some(atPos(cdef.pos.focus)(
DefDef(Modifiers(SYNTHETIC), nme.copy, tparams, copyParamss, bodyTpe,
diff --git a/src/compiler/scala/tools/nsc/util/Position.scala b/src/compiler/scala/tools/nsc/util/Position.scala
index 208cd5703a..b27ca17bfe 100644
--- a/src/compiler/scala/tools/nsc/util/Position.scala
+++ b/src/compiler/scala/tools/nsc/util/Position.scala
@@ -7,6 +7,9 @@
package scala.tools.nsc
package util
+import reflect.base.Attachments
+import reflect.api.PositionApi
+
object Position {
val tabInc = 8
@@ -33,22 +36,13 @@ object Position {
}
}
-trait Position extends scala.reflect.api.Position with scala.reflect.api.Attachment {
- /** Exposes itself as payload of Attachment */
- // necessary for conformance with Attachment
- def pos: Position = this
+abstract class Position extends PositionApi { self =>
- /** A bit weird method that is necessary to safely update positions without destroying custom attachments */
- // necessary for conformance with Attachment
- def withPos(newPos: scala.reflect.api.Position): scala.reflect.api.Attachment = newPos
+ type Pos = Position
- /** Exposes itself as payload of Attachment */
- // necessary for conformance with Attachment
- def payload: Position = this
+ def pos: Position = this
- /** A bit weird method that is necessary to safely update positions without destroying custom attachments */
- // necessary for conformance with Attachment
- def withPayload(newPos: Any): scala.reflect.api.Attachment = newPos.asInstanceOf[Position]
+ def withPos(newPos: Position): Attachments { type Pos = self.Pos } = newPos
/** Java file corresponding to the source file of this position.
*/
@@ -118,7 +112,7 @@ trait Position extends scala.reflect.api.Position with scala.reflect.api.Attachm
/** If this is a range, the union with the other range, with the point of this position.
* Otherwise, this position
*/
- def union(pos: scala.reflect.api.Position): Position = this
+ def union(pos: Position): Position = this
/** If this is a range position, the offset position of its start.
* Otherwise the position itself
@@ -139,39 +133,39 @@ trait Position extends scala.reflect.api.Position with scala.reflect.api.Attachm
* This holds if `this` is a range position and its range [start..end]
* is the same or covers the range of the given position, which may or may not be a range position.
*/
- def includes(pos: scala.reflect.api.Position): Boolean = false
+ def includes(pos: Position): Boolean = false
/** Does this position properly include the given position `pos` ("properly" meaning their
* ranges are not the same)?
*/
- def properlyIncludes(pos: scala.reflect.api.Position): Boolean =
+ def properlyIncludes(pos: Position): Boolean =
includes(pos) && (start < pos.startOrPoint || pos.endOrPoint < end)
/** Does this position precede that position?
* This holds if both positions are defined and the end point of this position
* is not larger than the start point of the given position.
*/
- def precedes(pos: scala.reflect.api.Position): Boolean =
+ def precedes(pos: Position): Boolean =
isDefined && pos.isDefined && endOrPoint <= pos.startOrPoint
/** Does this position properly precede the given position `pos` ("properly" meaning their ranges
* do not share a common point).
*/
- def properlyPrecedes(pos: scala.reflect.api.Position): Boolean =
+ def properlyPrecedes(pos: Position): Boolean =
isDefined && pos.isDefined && endOrPoint < pos.startOrPoint
/** Does this position overlap with that position?
* This holds if both positions are ranges and there is an interval of
* non-zero length that is shared by both position ranges.
*/
- def overlaps(pos: scala.reflect.api.Position): Boolean =
+ def overlaps(pos: Position): Boolean =
isRange && pos.isRange &&
((pos.start < end && start < pos.end) || (start < pos.end && pos.start < end))
/** Does this position cover the same range as that position?
* Holds only if both position are ranges
*/
- def sameRange(pos: scala.reflect.api.Position): Boolean =
+ def sameRange(pos: Position): Boolean =
isRange && pos.isRange && start == pos.start && end == pos.end
def line: Int = throw new UnsupportedOperationException("Position.line")
@@ -224,10 +218,7 @@ class OffsetPosition(override val source: SourceFile, override val point: Int) e
col + 1
}
- override def union(pos: scala.reflect.api.Position) =
- // [Eugene] how do I get rid of this cast?
- // I could introduce a "type PositionType <: scala.reflect.api.Position", but that's also ugly
- if (pos.isRange) pos.asInstanceOf[Position] else this
+ override def union(pos: Position) = if (pos.isRange) pos else this
override def equals(that : Any) = that match {
case that : OffsetPosition => point == that.point && source.file == that.source.file
@@ -261,8 +252,8 @@ extends OffsetPosition(source, point) {
}
override def focusEnd = new OffsetPosition(source, end)
override def makeTransparent = new TransparentPosition(source, start, point, end)
- override def includes(pos: scala.reflect.api.Position) = pos.isDefined && start <= pos.startOrPoint && pos.endOrPoint <= end
- override def union(pos: scala.reflect.api.Position): Position =
+ override def includes(pos: Position) = pos.isDefined && start <= pos.startOrPoint && pos.endOrPoint <= end
+ override def union(pos: Position): Position =
if (pos.isRange) new RangePosition(source, start min pos.start, point, end max pos.end) else this
override def toSingleLine: Position = source match {
diff --git a/src/compiler/scala/tools/nsc/util/ScalaClassLoader.scala b/src/compiler/scala/tools/nsc/util/ScalaClassLoader.scala
index 4c7920d6b3..1db6b4a170 100644
--- a/src/compiler/scala/tools/nsc/util/ScalaClassLoader.scala
+++ b/src/compiler/scala/tools/nsc/util/ScalaClassLoader.scala
@@ -11,7 +11,7 @@ import java.lang.reflect.{ Constructor, Modifier, Method }
import java.io.{ File => JFile }
import java.net.{ URLClassLoader => JURLClassLoader }
import java.net.URL
-import scala.reflect.ReflectionUtils.unwrapHandler
+import scala.reflect.runtime.ReflectionUtils.unwrapHandler
import ScalaClassLoader._
import scala.util.control.Exception.{ catching }
import language.implicitConversions
diff --git a/src/compiler/scala/tools/reflect/FastTrack.scala b/src/compiler/scala/tools/reflect/FastTrack.scala
index 738bcd01a7..8658e3225d 100644
--- a/src/compiler/scala/tools/reflect/FastTrack.scala
+++ b/src/compiler/scala/tools/reflect/FastTrack.scala
@@ -35,7 +35,6 @@ trait FastTrack {
var registry = Map[Symbol, FastTrackEntry]()
implicit class BindTo(sym: Symbol) { def bindTo(expander: FastTrackExpander): Unit = if (sym != NoSymbol) registry += sym -> FastTrackEntry(sym, expander) }
MacroInternal_materializeArrayTag bindTo { case (c, Apply(TypeApply(_, List(tt)), List(u))) => c.materializeArrayTag(u, tt.tpe) }
- MacroInternal_materializeErasureTag bindTo { case (c, Apply(TypeApply(_, List(tt)), List(u))) => c.materializeErasureTag(u, tt.tpe, concrete = false) }
MacroInternal_materializeClassTag bindTo { case (c, Apply(TypeApply(_, List(tt)), List(u))) => c.materializeClassTag(u, tt.tpe) }
MacroInternal_materializeTypeTag bindTo { case (c, Apply(TypeApply(_, List(tt)), List(u))) => c.materializeTypeTag(u, tt.tpe, concrete = false) }
MacroInternal_materializeConcreteTypeTag bindTo { case (c, Apply(TypeApply(_, List(tt)), List(u))) => c.materializeTypeTag(u, tt.tpe, concrete = true) }
diff --git a/src/compiler/scala/reflect/internal/FrontEnds.scala b/src/compiler/scala/tools/reflect/FrontEnds.scala
index 74501c7686..52eadc4e04 100644
--- a/src/compiler/scala/reflect/internal/FrontEnds.scala
+++ b/src/compiler/scala/tools/reflect/FrontEnds.scala
@@ -1,10 +1,12 @@
-package scala.reflect
-package internal
+package scala.tools
+package reflect
-trait FrontEnds { self: SymbolTable =>
+import scala.tools.nsc.reporters._
+import scala.tools.nsc.Settings
- import scala.tools.nsc.reporters._
- import scala.tools.nsc.Settings
+trait FrontEnds extends scala.reflect.api.FrontEnds {
+
+ type Position = scala.tools.nsc.util.Position
def mkConsoleFrontEnd(minSeverity: Int = 1): FrontEnd = {
val settings = new Settings()
diff --git a/src/compiler/scala/tools/reflect/StdTags.scala b/src/compiler/scala/tools/reflect/StdTags.scala
index d6dba5df1b..914219c04e 100644
--- a/src/compiler/scala/tools/reflect/StdTags.scala
+++ b/src/compiler/scala/tools/reflect/StdTags.scala
@@ -2,21 +2,36 @@ package scala.tools
package reflect
import java.lang.{Class => jClass}
-import scala.reflect.mirror._
+import scala.reflect.base.{MirrorOf, TypeCreator, Universe => BaseUniverse}
+import scala.reflect.runtime.{universe => ru}
// [Eugene++] Before 2.10 is released, I suggest we don't rely on automated type tag generation
// sure, it's convenient, but then refactoring reflection / reification becomes a pain
// `ClassTag` tags are fine, because they don't need a reifier to be generated
object StdTags {
- lazy val tagOfString = TypeTag.String
- lazy val tagOfListOfString = TypeTag[List[String]]({
- val pre = ThisType(staticModule("scala.collection.immutable").moduleClass)
- TypeRef(pre, definitions.ListClass, List(definitions.StringClass.asTypeConstructor))
- }, classOf[List[String]])
+ // root mirror is fine for these guys, since scala-library.jar is guaranteed to be reachable from the root mirror
+ lazy val tagOfString = ru.TypeTag.String
+ lazy val tagOfListOfString = ru.TypeTag[List[String]](
+ ru.rootMirror,
+ new TypeCreator {
+ def apply[U <: BaseUniverse with Singleton](m: MirrorOf[U]): U # Type = {
+ val u = m.universe
+ val pre = u.ThisType(m.staticModule("scala.collection.immutable").moduleClass.asInstanceOf[u.Symbol])
+ u.TypeRef(pre, u.definitions.ListClass, List(u.definitions.StringClass.asTypeConstructor))
+ }
+ })
- private def tagOfStaticClass[T: ClassTag] = TypeTag[T](staticClass(classTag[T].erasure.getName).asTypeConstructor, classTag[T].erasure)
- lazy val tagOfInt = TypeTag.Int
+ // root mirror is NOT fine for these guys, hence we use the `currentMirror` trick
+ private val ourClassloader = getClass.getClassLoader
+ private def tagOfStaticClass[T: ClassTag] =
+ ru.TypeTag[T](
+ ru.runtimeMirror(ourClassloader),
+ new TypeCreator {
+ def apply[U <: BaseUniverse with Singleton](m: MirrorOf[U]): U # Type =
+ m.staticClass(classTag[T].erasure.getName).asTypeConstructor.asInstanceOf[U # Type]
+ })
+ lazy val tagOfInt = ru.TypeTag.Int
lazy val tagOfFile = tagOfStaticClass[scala.tools.nsc.io.File]
lazy val tagOfDirectory = tagOfStaticClass[scala.tools.nsc.io.Directory]
lazy val tagOfStdReplVals = tagOfStaticClass[scala.tools.nsc.interpreter.StdReplVals]
diff --git a/src/compiler/scala/tools/reflect/ToolBox.scala b/src/compiler/scala/tools/reflect/ToolBox.scala
new file mode 100644
index 0000000000..edd22c60f4
--- /dev/null
+++ b/src/compiler/scala/tools/reflect/ToolBox.scala
@@ -0,0 +1,93 @@
+package scala.tools
+package reflect
+
+import scala.reflect.api.Universe
+import scala.reflect.base.MirrorOf
+
+trait ToolBox[U <: Universe] {
+
+ /** Underlying universe of a ToolBox
+ */
+ val u: U
+
+ /** Underlying mirror of a ToolBox
+ */
+ val mirror: MirrorOf[u.type]
+
+ /** Front end of the toolbox.
+ *
+ * Accumulates and displays warnings and errors, can drop to interactive mode (if supported).
+ * The latter can be useful to study the typechecker or to debug complex macros.
+ */
+ def frontEnd: FrontEnd
+
+ /** Typechecks a tree using this ToolBox.
+ * This populates symbols and types of the tree and possibly transforms it to reflect certain desugarings.
+ *
+ * If the tree has unresolved type variables (represented as instances of ``FreeTypeSymbol'' symbols),
+ * then they might, might be partially or might not be specified in the ``freeTypes'' parameter.
+ *
+ * If ``silent'' is false, ``TypeError'' will be thrown in case of a typecheck error.
+ * If ``silent'' is true, the typecheck is silent and will return ``EmptyTree'' if an error occurs.
+ * Such errors don't vanish and can be inspected by turning on -Ydebug.
+ *
+ * Typechecking can be steered with the following optional parameters:
+ * ``withImplicitViewsDisabled'' recursively prohibits implicit views (though, implicit vals will still be looked up and filled in), default value is false
+ * ``withMacrosDisabled'' recursively prohibits macro expansions and macro-based implicits, default value is false
+ */
+ def typeCheck(tree: u.Tree, pt: u.Type = u.WildcardType, freeTypes: Map[u.FreeTypeSymbol, u.Type] = Map[u.FreeTypeSymbol, u.Type](), silent: Boolean = false, withImplicitViewsDisabled: Boolean = false, withMacrosDisabled: Boolean = false): u.Tree
+
+
+ /** Infers an implicit value of the expected type ``pt'' in the macro callsite context.
+ *
+ * If ``silent'' is false, ``TypeError'' will be thrown in case of an inference error.
+ * If ``silent'' is true, the typecheck is silent and will return ``EmptyTree'' if an error occurs.
+ * Such errors don't vanish and can be inspected by turning on -Xlog-implicits.
+ * Unlike in ``typeCheck'', ``silent'' is true by default.
+ */
+ def inferImplicitValue(pt: u.Type, silent: Boolean = true, withMacrosDisabled: Boolean = false): u.Tree
+
+ /** Infers an implicit view from the provided tree ``tree'' from the type ``from'' to the type ``to'' in the macro callsite context.
+ *
+ * Otional parameter, ``reportAmbiguous`` controls whether ambiguous implicit errors should be reported.
+ * If we search for a view simply to find out whether one type is coercible to another, it might be desirable to set this flag to ``false''.
+ *
+ * If ``silent'' is false, ``TypeError'' will be thrown in case of an inference error.
+ * If ``silent'' is true, the typecheck is silent and will return ``EmptyTree'' if an error occurs.
+ * Such errors don't vanish and can be inspected by turning on -Xlog-implicits.
+ * Unlike in ``typeCheck'', ``silent'' is true by default.
+ */
+ def inferImplicitView(tree: u.Tree, from: u.Type, to: u.Type, silent: Boolean = true, withMacrosDisabled: Boolean = false, reportAmbiguous: Boolean = true): u.Tree
+
+ /** Recursively resets symbols and types in a given tree.
+ *
+ * Note that this does not revert the tree to its pre-typer shape.
+ * For more info, read up https://issues.scala-lang.org/browse/SI-5464.
+ */
+ def resetAllAttrs(tree: u.Tree): u.Tree
+
+ /** Recursively resets locally defined symbols and types in a given tree.
+ *
+ * Note that this does not revert the tree to its pre-typer shape.
+ * For more info, read up https://issues.scala-lang.org/browse/SI-5464.
+ */
+ def resetLocalAttrs(tree: u.Tree): u.Tree
+
+ /** .. */
+ def parseExpr(code: String): u.Tree
+
+ /** Compiles and runs a tree using this ToolBox.
+ *
+ * If the tree has unresolved type variables (represented as instances of ``FreeTypeSymbol'' symbols),
+ * then they all have to be specified in the ``freeTypes'' parameter or an error occurs.
+ *
+ * This spawns the compiler at the Namer phase, and pipelines the tree through that compiler.
+ * Currently ``runExpr'' does not accept trees that already typechecked, because typechecking isn't idempotent.
+ * For more info, take a look at https://issues.scala-lang.org/browse/SI-5464.
+ */
+ def runExpr(tree: u.Tree, freeTypes: Map[u.FreeTypeSymbol, u.Type] = Map[u.FreeTypeSymbol, u.Type]()): Any
+}
+
+/** Represents an error during toolboxing
+ */
+case class ToolBoxError(val message: String, val cause: Throwable = null) extends Throwable(message, cause)
diff --git a/src/compiler/scala/reflect/runtime/ToolBoxes.scala b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala
index 895c645c83..3ef2337e0f 100644
--- a/src/compiler/scala/reflect/runtime/ToolBoxes.scala
+++ b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala
@@ -1,5 +1,5 @@
-package scala.reflect
-package runtime
+package scala.tools
+package reflect
import scala.tools.nsc.reporters._
import scala.tools.nsc.ReflectGlobal
@@ -8,31 +8,45 @@ import scala.tools.nsc.Global
import scala.tools.nsc.typechecker.Modes
import scala.tools.nsc.io.VirtualDirectory
import scala.tools.nsc.interpreter.AbstractFileClassLoader
-import scala.tools.nsc.util.FreshNameCreator
+import scala.tools.nsc.util.{FreshNameCreator, BatchSourceFile}
import scala.reflect.internal.Flags
import scala.tools.nsc.util.{NoSourceFile, NoFile}
import java.lang.{Class => jClass}
import scala.compat.Platform.EOL
+import scala.reflect.NameTransformer
+import scala.reflect.api.JavaUniverse
+import scala.reflect.base.MirrorOf
-trait ToolBoxes extends { self: Universe =>
+// [Eugene++ to Martin] by the way, toolboxes are unable to compile anything that involves packages
+// is this intentional?
- def mkToolBox(frontEnd: FrontEnd = mkSilentFrontEnd(), options: String = "") = new ToolBox(frontEnd, options)
+abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf =>
- class ToolBox(val frontEnd: FrontEnd, val options: String) extends AbsToolBox {
+ val mirror: u.Mirror
+
+ def mkToolBox(frontEnd: FrontEnd = mkSilentFrontEnd(), options: String = ""): ToolBox[U] =
+ new ToolBoxImpl(frontEnd, options)
+
+ private class ToolBoxImpl(val frontEnd: FrontEnd, val options: String) extends ToolBox[U] { toolBoxSelf =>
+
+ val u: factorySelf.u.type = factorySelf.u
+ val mirror: u.Mirror = factorySelf.mirror
class ToolBoxGlobal(settings: scala.tools.nsc.Settings, reporter: Reporter)
- extends ReflectGlobal(settings, reporter, ToolBox.this.classLoader) {
+ extends ReflectGlobal(settings, reporter, toolBoxSelf.classLoader) {
import definitions._
private val trace = scala.tools.nsc.util.trace when settings.debug.value
- private final val wrapperMethodName = "wrapper"
-
private var wrapCount = 0
+ private final val wrapperMethodName = "wrapper"
+
private def nextWrapperModuleName() = {
wrapCount += 1
- newTermName("__wrapper$" + wrapCount)
+ // we need to use UUIDs here, because our toolbox might be spawned by another toolbox
+ // that already has, say, __wrapper$1 in its virtual directory, which will shadow our codegen
+ newTermName("__wrapper$" + wrapCount + "$" + java.util.UUID.randomUUID.toString.replace("-", ""))
}
def verifyExpr(expr: Tree): Unit = {
@@ -46,25 +60,21 @@ trait ToolBoxes extends { self: Universe =>
// That's why we cannot allow inputs of toolboxes to be typechecked,
// at least not until the aforementioned issue is closed.
val typed = expr filter (t => t.tpe != null && t.tpe != NoType && !t.isInstanceOf[TypeTree])
- if (!typed.isEmpty) throw new ToolBoxError(ToolBox.this, "reflective toolbox has failed: cannot operate on trees that are already typed")
+ if (!typed.isEmpty) throw ToolBoxError("reflective toolbox has failed: cannot operate on trees that are already typed")
- val freeTypes = this.freeTypes(expr)
+ val freeTypes = expr.freeTypes
if (freeTypes.length > 0) {
var msg = "reflective toolbox has failed:" + EOL
msg += "unresolved free type variables (namely: " + (freeTypes map (ft => "%s %s".format(ft.name, ft.origin)) mkString ", ") + "). "
msg += "have you forgot to use TypeTag annotations for type parameters external to a reifee? "
msg += "if you have troubles tracking free type variables, consider using -Xlog-free-types"
- throw new ToolBoxError(ToolBox.this, msg)
+ throw ToolBoxError(msg)
}
}
- def typeCheckExpr(expr0: Tree, pt: Type, silent: Boolean = false, withImplicitViewsDisabled: Boolean = false, withMacrosDisabled: Boolean = false): Tree = {
- verifyExpr(expr0)
-
- // need to wrap the expr, because otherwise you won't be able to typecheck macros against something that contains free vars
- // [Eugene] get rid of the copy/paste w.r.t compileExpr
- val freeTerms = this.freeTerms(expr0)
- val freeTermNames = collection.mutable.Map[Symbol, TermName]()
+ def extractFreeTerms(expr0: Tree, wrapFreeTermRefs: Boolean): (Tree, collection.mutable.LinkedHashMap[FreeTermSymbol, TermName]) = {
+ val freeTerms = expr0.freeTerms
+ val freeTermNames = collection.mutable.LinkedHashMap[FreeTermSymbol, TermName]()
freeTerms foreach (ft => {
var name = ft.name.toString
val namesakes = freeTerms takeWhile (_ != ft) filter (ft2 => ft != ft2 && ft.name == ft2.name)
@@ -76,7 +86,8 @@ trait ToolBoxes extends { self: Universe =>
if (tree.hasSymbol && tree.symbol.isFreeTerm) {
tree match {
case Ident(_) =>
- Ident(freeTermNames(tree.symbol))
+ val freeTermRef = Ident(freeTermNames(tree.symbol.asFreeTermSymbol))
+ if (wrapFreeTermRefs) Apply(freeTermRef, List()) else freeTermRef
case _ =>
throw new Error("internal error: %s (%s, %s) is not supported".format(tree, tree.productPrefix, tree.getClass))
}
@@ -84,14 +95,23 @@ trait ToolBoxes extends { self: Universe =>
super.transform(tree)
}
}.transform(expr0)
- val dummies = freeTerms map (freeTerm => ValDef(NoMods, freeTermNames(freeTerm), TypeTree(freeTerm.info), Select(Ident(PredefModule), newTermName("$qmark$qmark$qmark"))))
+ (expr, freeTermNames)
+ }
+
+ def typeCheckExpr(expr0: Tree, pt: Type, silent: Boolean = false, withImplicitViewsDisabled: Boolean, withMacrosDisabled: Boolean): Tree = {
+ verifyExpr(expr0)
+
+ // need to wrap the expr, because otherwise you won't be able to typecheck macros against something that contains free vars
+ var (expr, freeTerms) = extractFreeTerms(expr0, wrapFreeTermRefs = false)
+ val dummies = freeTerms.map{ case (freeTerm, name) => ValDef(NoMods, name, TypeTree(freeTerm.info), Select(Ident(PredefModule), newTermName("$qmark$qmark$qmark"))) }.toList
expr = Block(dummies, expr)
// [Eugene] how can we implement that?
// !!! Why is this is in the empty package? If it's only to make
// it inaccessible then please put it somewhere designed for that
// rather than polluting the empty package with synthetics.
- val ownerClass = EmptyPackageClass.newClassWithInfo(newTypeName("<expression-owner>"), List(ObjectClass.tpe), newScope)
+ val ownerClass = rootMirror.EmptyPackageClass.newClassSymbol(newTypeName("<expression-owner>"))
+ build.setTypeSignature(ownerClass, ClassInfoType(List(ObjectClass.tpe), newScope, ownerClass))
val owner = ownerClass.newLocalDummy(expr.pos)
var currentTyper = typer.atOwner(expr, owner)
val wrapper1 = if (!withImplicitViewsDisabled) (currentTyper.context.withImplicitsEnabled[Tree] _) else (currentTyper.context.withImplicitsDisabled[Tree] _)
@@ -107,22 +127,22 @@ trait ToolBoxes extends { self: Universe =>
case analyzer.SilentResultValue(result) =>
trace("success: ")(showAttributed(result, true, true, settings.Yshowsymkinds.value))
var Block(dummies, unwrapped) = result
- var reversedFreeTermNames = freeTermNames map (_.swap)
+ var invertedIndex = freeTerms map (_.swap)
// todo. also fixup singleton types
unwrapped = new Transformer {
override def transform(tree: Tree): Tree =
tree match {
- case Ident(name) if reversedFreeTermNames contains name =>
- Ident(reversedFreeTermNames(name)) setType tree.tpe
+ case Ident(name) if invertedIndex contains name =>
+ Ident(invertedIndex(name)) setType tree.tpe
case _ =>
super.transform(tree)
}
}.transform(unwrapped)
- new TreeTypeSubstituter(dummies map (_.symbol), dummies map (dummy => SingleType(NoPrefix, reversedFreeTermNames(dummy.symbol.name)))).traverse(unwrapped)
+ new TreeTypeSubstituter(dummies map (_.symbol), dummies map (dummy => SingleType(NoPrefix, invertedIndex(dummy.symbol.name)))).traverse(unwrapped)
unwrapped
case error @ analyzer.SilentTypeError(_) =>
trace("failed: ")(error.err.errMsg)
- if (!silent) throw new ToolBoxError(ToolBox.this, "reflective typecheck has failed: %s".format(error.err.errMsg))
+ if (!silent) throw ToolBoxError("reflective typecheck has failed: %s".format(error.err.errMsg))
EmptyTree
})
}
@@ -131,48 +151,32 @@ trait ToolBoxes extends { self: Universe =>
verifyExpr(expr)
def wrapExpr(expr0: Tree): Tree = {
- def defOwner(tree: Tree): Symbol = tree find (_.isDef) map (_.symbol) match {
- case Some(sym) if sym != null && sym != NoSymbol => sym.owner
- case _ => NoSymbol
- }
+ val (expr, freeTerms) = extractFreeTerms(expr0, wrapFreeTermRefs = true)
- val freeTerms = this.freeTerms(expr0)
- val freeTermNames = collection.mutable.Map[Symbol, TermName]()
- freeTerms foreach (ft => {
- var name = ft.name.toString
- val namesakes = freeTerms takeWhile (_ != ft) filter (ft2 => ft != ft2 && ft.name == ft2.name)
- if (namesakes.length > 0) name += ("$" + (namesakes.length + 1))
- freeTermNames += (ft -> newTermName(name + nme.MIRROR_FREE_VALUE_SUFFIX))
- })
- val expr = new Transformer {
- override def transform(tree: Tree): Tree =
- if (tree.hasSymbol && tree.symbol.isFreeTerm) {
- tree match {
- case Ident(_) =>
- Apply(Ident(freeTermNames(tree.symbol)), List())
- case _ =>
- throw new Error("internal error: %s (%s, %s) is not supported".format(tree, tree.productPrefix, tree.getClass))
- }
- } else {
- super.transform(tree)
- }
- }.transform(expr0)
+ val (obj, mclazz) = rootMirror.EmptyPackageClass.newModuleAndClassSymbol(
+ nextWrapperModuleName())
- val obj = EmptyPackageClass.newModule(nextWrapperModuleName())
val minfo = ClassInfoType(List(ObjectClass.tpe), newScope, obj.moduleClass)
obj.moduleClass setInfo minfo
obj setInfo obj.moduleClass.tpe
+
val meth = obj.moduleClass.newMethod(newTermName(wrapperMethodName))
- def makeParam(fv: Symbol) = {
+ def makeParam(schema: (FreeTermSymbol, TermName)) = {
+ val (fv, name) = schema
// [Eugene] conventional way of doing this?
val underlying = fv.tpe.resultType
val tpe = appliedType(definitions.FunctionClass(0).tpe, List(underlying))
- meth.newValueParameter(freeTermNames(fv)) setInfo tpe
+ meth.newValueParameter(name) setInfo tpe
}
- meth setInfo MethodType(freeTerms map makeParam, AnyClass.tpe)
+ meth setInfo MethodType(freeTerms.map(makeParam).toList, AnyClass.tpe)
minfo.decls enter meth
+ def defOwner(tree: Tree): Symbol = tree find (_.isDef) map (_.symbol) match {
+ case Some(sym) if sym != null && sym != NoSymbol => sym.owner
+ case _ => NoSymbol
+ }
trace("wrapping ")(defOwner(expr) -> meth)
val methdef = DefDef(meth, expr changeOwner (defOwner(expr) -> meth))
+
val moduledef = ModuleDef(
obj,
Template(
@@ -184,6 +188,7 @@ trait ToolBoxes extends { self: Universe =>
List(methdef),
NoPosition))
trace("wrapped: ")(showAttributed(moduledef, true, true, settings.Yshowsymkinds.value))
+
var cleanedUp = resetLocalAttrs(moduledef)
trace("cleaned up: ")(showAttributed(cleanedUp, true, true, settings.Yshowsymkinds.value))
cleanedUp
@@ -210,7 +215,7 @@ trait ToolBoxes extends { self: Universe =>
}
def runExpr(expr: Tree, freeTypes: Map[TypeName, Type] = Map[TypeName, Type]()): Any = {
- val freeTerms = this.freeTerms(expr) // need to calculate them here, because later on they will be erased
+ val freeTerms = expr.freeTerms // need to calculate them here, because later on they will be erased
val thunks = freeTerms map (fte => () => fte.value) // need to be lazy in order not to distort evaluation order
// @odersky writes: Not sure we will be able to drop this. I forgot the reason why we dereference () functions,
@@ -218,14 +223,33 @@ trait ToolBoxes extends { self: Universe =>
// @Eugene writes: this dates back to the days when one could only reify functions
// hence, blocks were translated into nullary functions, so
// presumably, it was useful to immediately evaluate them to get the result of a block
-// val result = jmeth.invoke(singleton, freeTerms map (sym => sym.asInstanceOf[FreeTermVar].value.asInstanceOf[AnyRef]): _*)
-// if (etpe.typeSymbol != FunctionClass(0)) result
-// else {
-// val applyMeth = result.getClass.getMethod("apply")
-// applyMeth.invoke(result)
-// }
+ // @Eugene writes: anyways, I'll stash the old sources here in comments in case anyone wants to revive them
+ // val result = jmeth.invoke(singleton, freeTerms map (sym => sym.asInstanceOf[FreeTermVar].value.asInstanceOf[AnyRef]): _*)
+ // if (etpe.typeSymbol != FunctionClass(0)) result
+ // else {
+ // val applyMeth = result.getClass.getMethod("apply")
+ // applyMeth.invoke(result)
+ // }
val (singleton, jmeth) = compileExpr(expr)
- jmeth.invoke(singleton, thunks map (_.asInstanceOf[AnyRef]): _*)
+ val result = jmeth.invoke(singleton, thunks map (_.asInstanceOf[AnyRef]): _*)
+ result
+ }
+
+ def parseExpr(code: String): Tree = {
+ val run = new Run
+ reporter.reset()
+ val wrappedCode = "object wrapper {" + EOL + code + EOL + "}"
+ val file = new BatchSourceFile("<toolbox>", wrappedCode)
+ val unit = new CompilationUnit(file)
+ phase = run.parserPhase
+ val parser = new syntaxAnalyzer.UnitParser(unit)
+ val wrappedTree = parser.parse()
+ throwIfErrors()
+ val PackageDef(_, List(ModuleDef(_, _, Template(_, _, _ :: parsed)))) = wrappedTree
+ parsed match {
+ case expr :: Nil => expr
+ case stats :+ expr => Block(stats, expr)
+ }
}
def showAttributed(tree: Tree, printTypes: Boolean = true, printIds: Boolean = true, printKinds: Boolean = false): String = {
@@ -249,7 +273,7 @@ trait ToolBoxes extends { self: Universe =>
if (frontEnd.hasErrors) {
var msg = "reflective compilation has failed: " + EOL + EOL
msg += frontEnd.infos map (_.msg) mkString EOL
- throw new ToolBoxError(ToolBox.this, msg)
+ throw ToolBoxError(msg)
}
}
}
@@ -258,94 +282,93 @@ trait ToolBoxes extends { self: Universe =>
lazy val arguments = options.split(" ")
lazy val virtualDirectory =
- (arguments zip arguments.tail) collect { case ("-d", dir) => dir } lastOption match {
+ (arguments zip arguments.tail).collect{ case ("-d", dir) => dir }.lastOption match {
case Some(outDir) => scala.tools.nsc.io.AbstractFile.getDirectory(outDir)
case None => new VirtualDirectory("(memory)", None)
}
lazy val compiler: ToolBoxGlobal = {
try {
- val errorFn: String => Unit = msg => frontEnd.log(NoPosition, msg, frontEnd.ERROR)
+ val errorFn: String => Unit = msg => frontEnd.log(scala.tools.nsc.util.NoPosition, msg, frontEnd.ERROR)
val command = new CompilerCommand(arguments.toList, errorFn)
command.settings.outputDirs setSingleOutput virtualDirectory
val instance = new ToolBoxGlobal(command.settings, new FrontEndToReporterProxy(frontEnd) { val settings = command.settings })
if (frontEnd.hasErrors) {
var msg = "reflective compilation has failed: cannot initialize the compiler: " + EOL + EOL
msg += frontEnd.infos map (_.msg) mkString EOL
- throw new ToolBoxError(this, msg)
+ throw ToolBoxError(msg)
}
- instance.phase = (new instance.Run).typerPhase // need to manually set a phase, because otherwise TypeHistory will crash
instance
} catch {
case ex: Throwable =>
var msg = "reflective compilation has failed: cannot initialize the compiler due to %s".format(ex.toString)
- throw new ToolBoxError(this, msg, ex)
+ throw ToolBoxError(msg, ex)
}
}
- // @Eugene: how do I make this work without casts?
- // lazy val importer = compiler.mkImporter(self)
- lazy val importer = compiler.mkImporter(self).asInstanceOf[compiler.Importer { val from: self.type }]
-
+ lazy val importer = compiler.mkImporter(u)
lazy val exporter = importer.reverse
+ lazy val classLoader = new AbstractFileClassLoader(virtualDirectory, mirror.classLoader)
- lazy val classLoader = new AbstractFileClassLoader(virtualDirectory, self.classLoader)
-
- def typeCheck(tree: Tree, expectedType: Type = WildcardType, freeTypes: Map[FreeType, Type] = Map[FreeType, Type](), silent: Boolean = false, withImplicitViewsDisabled: Boolean = false, withMacrosDisabled: Boolean = false): Tree = {
+ def typeCheck(tree: u.Tree, expectedType: u.Type, freeTypes: Map[u.FreeTypeSymbol, u.Type], silent: Boolean, withImplicitViewsDisabled: Boolean, withMacrosDisabled: Boolean): u.Tree = {
if (compiler.settings.verbose.value) println("typing "+tree+", expectedType = "+expectedType+", freeTypes = "+freeTypes)
var ctree: compiler.Tree = importer.importTree(tree)
var cexpectedType: compiler.Type = importer.importType(expectedType)
if (compiler.settings.verbose.value) println("substituting "+ctree+", expectedType = "+expectedType)
- val cfreeTypes: Map[compiler.FreeType, compiler.Type] = freeTypes map { case (k, v) => (importer.importSymbol(k).asInstanceOf[compiler.FreeType], importer.importType(v)) }
- ctree = compiler.substituteFreeTypes(ctree, cfreeTypes)
- cexpectedType = compiler.substituteFreeTypes(cexpectedType, cfreeTypes)
+ val cfreeTypes: Map[compiler.FreeTypeSymbol, compiler.Type] = freeTypes map { case (k, v) => (importer.importSymbol(k).asInstanceOf[compiler.FreeTypeSymbol], importer.importType(v)) }
+ ctree = ctree.substituteTypes(cfreeTypes.keys.toList, cfreeTypes.values.toList)
+ cexpectedType = cexpectedType.substituteTypes(cfreeTypes.keys.toList, cfreeTypes.values.toList)
if (compiler.settings.verbose.value) println("typing "+ctree+", expectedType = "+expectedType)
val ttree: compiler.Tree = compiler.typeCheckExpr(ctree, cexpectedType, silent = silent, withImplicitViewsDisabled = withImplicitViewsDisabled, withMacrosDisabled = withMacrosDisabled)
- val rmttree = exporter.importTree(ttree)
- rmttree
+ val uttree = exporter.importTree(ttree)
+ uttree
}
- def inferImplicitValue(pt: Type, silent: Boolean = true, withMacrosDisabled: Boolean = false): Tree =
+ def inferImplicitValue(pt: u.Type, silent: Boolean, withMacrosDisabled: Boolean): u.Tree =
// todo. implement this
???
- def inferImplicitView(tree: Tree, from: Type, to: Type, silent: Boolean = true, withMacrosDisabled: Boolean = false, reportAmbiguous: Boolean = true): Tree =
+ def inferImplicitView(tree: u.Tree, from: u.Type, to: u.Type, silent: Boolean, withMacrosDisabled: Boolean, reportAmbiguous: Boolean): u.Tree =
// todo. implement this
???
- def resetAllAttrs(tree: Tree): Tree = {
+ def resetAllAttrs(tree: u.Tree): u.Tree = {
val ctree: compiler.Tree = importer.importTree(tree)
val ttree: compiler.Tree = compiler.resetAllAttrs(ctree)
- exporter.importTree(ttree)
+ val uttree = exporter.importTree(ttree)
+ uttree
}
- def resetLocalAttrs(tree: Tree): Tree = {
+ def resetLocalAttrs(tree: u.Tree): u.Tree = {
val ctree: compiler.Tree = importer.importTree(tree)
val ttree: compiler.Tree = compiler.resetLocalAttrs(ctree)
- exporter.importTree(ttree)
+ val uttree = exporter.importTree(ttree)
+ uttree
}
- def showAttributed(tree: Tree, printTypes: Boolean = true, printIds: Boolean = true, printKinds: Boolean = false): String =
+ def showAttributed(tree: u.Tree, printTypes: Boolean = true, printIds: Boolean = true, printKinds: Boolean = false): String =
compiler.showAttributed(importer.importTree(tree), printTypes, printIds, printKinds)
- def runExpr(tree: Tree, freeTypes: Map[FreeType, Type] = Map[FreeType, Type]()): Any = {
+ def parseExpr(code: String): u.Tree = {
+ if (compiler.settings.verbose.value) println("parsing "+code)
+ val ctree: compiler.Tree = compiler.parseExpr(code)
+ val utree = exporter.importTree(ctree)
+ utree
+ }
+
+ def runExpr(tree: u.Tree, freeTypes: Map[u.FreeTypeSymbol, u.Type]): Any = {
if (compiler.settings.verbose.value) println("running "+tree+", freeTypes = "+freeTypes)
var ctree: compiler.Tree = importer.importTree(tree)
if (compiler.settings.verbose.value) println("substituting "+ctree)
- val cfreeTypes: Map[compiler.FreeType, compiler.Type] = freeTypes map { case (k, v) => (importer.importSymbol(k).asInstanceOf[compiler.FreeType], importer.importType(v)) }
- ctree = compiler.substituteFreeTypes(ctree, cfreeTypes)
+ val cfreeTypes: Map[compiler.FreeTypeSymbol, compiler.Type] = freeTypes map { case (k, v) => (importer.importSymbol(k).asInstanceOf[compiler.FreeTypeSymbol], importer.importType(v)) }
+ ctree = ctree.substituteTypes(cfreeTypes.keys.toList, cfreeTypes.values.toList)
if (compiler.settings.verbose.value) println("running "+ctree)
compiler.runExpr(ctree)
}
-
- class ToolBoxError(val toolBox: ToolBox, val message: String, val cause: Throwable = null) extends Throwable(message, cause)
-
- object ToolBoxError extends ToolBoxErrorExtractor {
- def unapply(error: ToolBoxError): Option[(ToolBox, String)] = Some((error.toolBox, error.message))
- }
}
}
+
diff --git a/src/compiler/scala/tools/reflect/package.scala b/src/compiler/scala/tools/reflect/package.scala
new file mode 100644
index 0000000000..a3778a3b69
--- /dev/null
+++ b/src/compiler/scala/tools/reflect/package.scala
@@ -0,0 +1,33 @@
+/* NSC -- new Scala compiler
+ * Copyright 2005-2011 LAMP/EPFL
+ * @author Paul Phillips
+ */
+
+package scala.tools
+
+import scala.reflect.api.JavaUniverse
+import language.implicitConversions
+
+package object reflect extends FrontEnds {
+ // [todo: can we generalize this?
+ import scala.reflect.runtime.{universe => ru}
+ implicit def ToolBox(mirror0: ru.Mirror): ToolBoxFactory[ru.type] =
+ new ToolBoxFactory[ru.type](mirror0.universe) {
+ lazy val mirror = mirror0
+ }
+
+ // todo. replace this with an implicit class, once the pesky warning is gone
+ implicit def Eval[T](expr: JavaUniverse # Expr[T]): Eval[T] = new Eval[T](expr)
+
+ // we don't provide `Eval` for trees, because it's unclear where to get an evaluation mirror from
+}
+
+package reflect {
+ class Eval[T](expr: JavaUniverse # Expr[T]) {
+ def eval: T = {
+ val factory = new ToolBoxFactory[JavaUniverse](expr.mirror.universe) { val mirror = expr.mirror.asInstanceOf[this.u.Mirror] }
+ val toolBox = factory.mkToolBox()
+ toolBox.runExpr(expr.tree.asInstanceOf[toolBox.u.Tree]).asInstanceOf[T]
+ }
+ }
+}