summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
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]
+ }
+ }
+}