summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/scala-compiler.jar.desired.sha12
-rw-r--r--lib/scala-library.jar.desired.sha12
-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.scala (renamed from src/library/scala/reflect/api/RequiredFile.scala)4
-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.scala (renamed from src/library/scala/reflect/ReflectionUtils.scala)14
-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
-rw-r--r--src/continuations/plugin/scala/tools/selectivecps/CPSUtils.scala16
-rw-r--r--src/continuations/plugin/scala/tools/selectivecps/SelectiveCPSTransform.scala2
-rw-r--r--src/library/scala/Predef.scala2
-rw-r--r--src/library/scala/ref/WeakReference.scala16
-rw-r--r--src/library/scala/reflect/ArrayTag.scala2
-rw-r--r--src/library/scala/reflect/ClassTag.scala8
-rw-r--r--src/library/scala/reflect/DummyMirror.scala783
-rw-r--r--src/library/scala/reflect/ErasureTag.scala23
-rw-r--r--src/library/scala/reflect/Manifest.scala1
-rw-r--r--src/library/scala/reflect/TagInterop.scala34
-rwxr-xr-xsrc/library/scala/reflect/api/AnnotationInfos.scala47
-rw-r--r--src/library/scala/reflect/api/Attachment.scala29
-rw-r--r--src/library/scala/reflect/api/ClassLoaders.scala16
-rwxr-xr-xsrc/library/scala/reflect/api/Constants.scala18
-rw-r--r--src/library/scala/reflect/api/Exprs.scala53
-rw-r--r--src/library/scala/reflect/api/FlagSets.scala112
-rw-r--r--src/library/scala/reflect/api/FreeVars.scala42
-rw-r--r--src/library/scala/reflect/api/FrontEnds.scala6
-rw-r--r--src/library/scala/reflect/api/Importers.scala2
-rw-r--r--src/library/scala/reflect/api/Mirror.scala100
-rw-r--r--src/library/scala/reflect/api/Mirrors.scala213
-rw-r--r--src/library/scala/reflect/api/Modifier.scala82
-rwxr-xr-xsrc/library/scala/reflect/api/Names.scala40
-rw-r--r--src/library/scala/reflect/api/Positions.scala62
-rwxr-xr-xsrc/library/scala/reflect/api/StandardDefinitions.scala169
-rw-r--r--src/library/scala/reflect/api/StandardNames.scala31
-rwxr-xr-xsrc/library/scala/reflect/api/Symbols.scala330
-rw-r--r--src/library/scala/reflect/api/ToolBoxes.scala90
-rw-r--r--src/library/scala/reflect/api/TreeBuildUtil.scala159
-rw-r--r--src/library/scala/reflect/api/TreePrinters.scala27
-rw-r--r--src/library/scala/reflect/api/Trees.scala1871
-rwxr-xr-xsrc/library/scala/reflect/api/Types.scala362
-rwxr-xr-xsrc/library/scala/reflect/api/Universe.scala33
-rw-r--r--src/library/scala/reflect/api/package.scala12
-rw-r--r--src/library/scala/reflect/base/AnnotationInfos.scala44
-rw-r--r--src/library/scala/reflect/base/Attachments.scala42
-rw-r--r--src/library/scala/reflect/base/Base.scala763
-rw-r--r--src/library/scala/reflect/base/BuildUtils.scala90
-rw-r--r--src/library/scala/reflect/base/Constants.scala20
-rw-r--r--src/library/scala/reflect/base/FlagSets.scala17
-rw-r--r--src/library/scala/reflect/base/MirrorOf.scala25
-rw-r--r--src/library/scala/reflect/base/Mirrors.scala12
-rw-r--r--src/library/scala/reflect/base/Names.scala53
-rw-r--r--src/library/scala/reflect/base/Positions.scala22
-rw-r--r--[-rwxr-xr-x]src/library/scala/reflect/base/Scopes.scala (renamed from src/library/scala/reflect/api/Scopes.scala)9
-rw-r--r--src/library/scala/reflect/base/StandardDefinitions.scala75
-rw-r--r--src/library/scala/reflect/base/StandardNames.scala29
-rw-r--r--src/library/scala/reflect/base/Symbols.scala272
-rw-r--r--src/library/scala/reflect/base/TagInterop.scala29
-rw-r--r--src/library/scala/reflect/base/TreeCreator.scala6
-rw-r--r--src/library/scala/reflect/base/Trees.scala1459
-rw-r--r--src/library/scala/reflect/base/TypeCreator.scala6
-rw-r--r--src/library/scala/reflect/base/TypeTags.scala (renamed from src/library/scala/reflect/api/TypeTags.scala)167
-rw-r--r--src/library/scala/reflect/base/Types.scala432
-rw-r--r--src/library/scala/reflect/base/Universe.scala18
-rw-r--r--src/library/scala/reflect/compat.scala29
-rw-r--r--src/library/scala/reflect/makro/Aliases.scala4
-rw-r--r--src/library/scala/reflect/makro/Context.scala5
-rw-r--r--src/library/scala/reflect/makro/Exprs.scala7
-rw-r--r--src/library/scala/reflect/makro/FrontEnds.scala4
-rw-r--r--src/library/scala/reflect/makro/Reifiers.scala4
-rw-r--r--src/library/scala/reflect/makro/Symbols.scala24
-rw-r--r--src/library/scala/reflect/makro/TreeBuilder.scala59
-rw-r--r--src/library/scala/reflect/makro/TypeTags.scala8
-rw-r--r--src/library/scala/reflect/makro/Universe.scala117
-rw-r--r--src/library/scala/reflect/makro/internal/package.scala13
-rw-r--r--src/library/scala/reflect/package.scala58
-rw-r--r--src/partest/scala/tools/partest/CompilerTest.scala6
190 files changed, 9001 insertions, 6403 deletions
diff --git a/lib/scala-compiler.jar.desired.sha1 b/lib/scala-compiler.jar.desired.sha1
index 624a57ada7..2656fe4776 100644
--- a/lib/scala-compiler.jar.desired.sha1
+++ b/lib/scala-compiler.jar.desired.sha1
@@ -1 +1 @@
-fbdefcf1a7a2bcd71373f08acd13e84d869ceeaf ?scala-compiler.jar
+388fae20e2e54836af67c752ffed8ff5540b82ea ?scala-compiler.jar
diff --git a/lib/scala-library.jar.desired.sha1 b/lib/scala-library.jar.desired.sha1
index 21e2ed8665..a17d53053e 100644
--- a/lib/scala-library.jar.desired.sha1
+++ b/lib/scala-library.jar.desired.sha1
@@ -1 +1 @@
-e19956225d174f0f3bc0a1d014f208b68d399d66 ?scala-library.jar
+6e68e00a30b7328b55de7362f902619066094de7 ?scala-library.jar
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/library/scala/reflect/api/RequiredFile.scala b/src/compiler/scala/reflect/internal/AbstractFileApi.scala
index 4a54595940..9f37f4536f 100644
--- a/src/library/scala/reflect/api/RequiredFile.scala
+++ b/src/compiler/scala/reflect/internal/AbstractFileApi.scala
@@ -1,7 +1,7 @@
package scala.reflect
-package api
+package internal
-trait RequiredFile {
+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/library/scala/reflect/ReflectionUtils.scala b/src/compiler/scala/reflect/runtime/ReflectionUtils.scala
index aa1285d5a0..4e82fe8ad2 100644
--- a/src/library/scala/reflect/ReflectionUtils.scala
+++ b/src/compiler/scala/reflect/runtime/ReflectionUtils.scala
@@ -3,7 +3,7 @@
* @author Paul Phillips
*/
-package scala.reflect
+package scala.reflect.runtime
import java.lang.{Class => jClass}
import java.lang.reflect.{ InvocationTargetException, UndeclaredThrowableException }
@@ -42,7 +42,7 @@ object ReflectionUtils {
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: api.RequiredFile}].root + "] and " + inferClasspath(cl.getParent)
+ "[" + cl.asInstanceOf[{val root: scala.reflect.internal.AbstractFileApi}].root + "] and " + inferClasspath(cl.getParent)
case null =>
inferBootClasspath
case _ =>
@@ -56,16 +56,6 @@ object ReflectionUtils {
}
}
- def defaultReflectionClassLoader() = {
- // say no to non-determinism of mirror classloaders
- // default classloader will be instantiated using current system classloader
- // if you wish so, you can rebind it by setting ``mirror.classLoader'' to whatever is necessary
-// val cl = Thread.currentThread.getContextClassLoader
-// if (cl == null) getClass.getClassLoader else cl
-// cl
- getClass.getClassLoader
- }
-
def singletonInstance(cl: ClassLoader, className: String): AnyRef = {
val name = if (className endsWith "$") className else className + "$"
val clazz = java.lang.Class.forName(name, true, cl)
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]
+ }
+ }
+}
diff --git a/src/continuations/plugin/scala/tools/selectivecps/CPSUtils.scala b/src/continuations/plugin/scala/tools/selectivecps/CPSUtils.scala
index 6f5284f75f..3a1dc87a6a 100644
--- a/src/continuations/plugin/scala/tools/selectivecps/CPSUtils.scala
+++ b/src/continuations/plugin/scala/tools/selectivecps/CPSUtils.scala
@@ -29,14 +29,14 @@ trait CPSUtils {
val shiftUnitR = newTermName("shiftUnitR")
}
- lazy val MarkerCPSSym = definitions.getRequiredClass("scala.util.continuations.cpsSym")
- lazy val MarkerCPSTypes = definitions.getRequiredClass("scala.util.continuations.cpsParam")
- lazy val MarkerCPSSynth = definitions.getRequiredClass("scala.util.continuations.cpsSynth")
- lazy val MarkerCPSAdaptPlus = definitions.getRequiredClass("scala.util.continuations.cpsPlus")
- lazy val MarkerCPSAdaptMinus = definitions.getRequiredClass("scala.util.continuations.cpsMinus")
-
- lazy val Context = definitions.getRequiredClass("scala.util.continuations.ControlContext")
- lazy val ModCPS = definitions.getRequiredModule("scala.util.continuations")
+ lazy val MarkerCPSSym = rootMirror.getRequiredClass("scala.util.continuations.cpsSym")
+ lazy val MarkerCPSTypes = rootMirror.getRequiredClass("scala.util.continuations.cpsParam")
+ lazy val MarkerCPSSynth = rootMirror.getRequiredClass("scala.util.continuations.cpsSynth")
+ lazy val MarkerCPSAdaptPlus = rootMirror.getRequiredClass("scala.util.continuations.cpsPlus")
+ lazy val MarkerCPSAdaptMinus = rootMirror.getRequiredClass("scala.util.continuations.cpsMinus")
+
+ lazy val Context = rootMirror.getRequiredClass("scala.util.continuations.ControlContext")
+ lazy val ModCPS = rootMirror.getRequiredModule("scala.util.continuations")
lazy val MethShiftUnit = definitions.getMember(ModCPS, cpsNames.shiftUnit)
lazy val MethShiftUnit0 = definitions.getMember(ModCPS, cpsNames.shiftUnit0)
diff --git a/src/continuations/plugin/scala/tools/selectivecps/SelectiveCPSTransform.scala b/src/continuations/plugin/scala/tools/selectivecps/SelectiveCPSTransform.scala
index dcb7cd601f..54a0079f40 100644
--- a/src/continuations/plugin/scala/tools/selectivecps/SelectiveCPSTransform.scala
+++ b/src/continuations/plugin/scala/tools/selectivecps/SelectiveCPSTransform.scala
@@ -347,7 +347,7 @@ abstract class SelectiveCPSTransform extends PluginComponent with
// val <lhs> = ctx.getTrivialValue; ... <--- TODO: try/catch ??? don't bother for the moment...
// else
// ctx.flatMap { <lhs> => ... }
- val ctxSym = currentOwner.newValue(vd.symbol.name append cpsNames.shiftSuffix).setInfo(rhs1.tpe)
+ val ctxSym = currentOwner.newValue(newTermName("" + vd.symbol.name + cpsNames.shiftSuffix)).setInfo(rhs1.tpe)
val ctxDef = localTyper.typed(ValDef(ctxSym, rhs1))
def ctxRef = localTyper.typed(Ident(ctxSym))
val argSym = currentOwner.newValue(vd.symbol.name).setInfo(tpe)
diff --git a/src/library/scala/Predef.scala b/src/library/scala/Predef.scala
index c08462ac1b..a6477f1709 100644
--- a/src/library/scala/Predef.scala
+++ b/src/library/scala/Predef.scala
@@ -113,7 +113,6 @@ object Predef extends LowPriorityImplicits {
// Tag types and companions, and incantations for summoning
type ArrayTag[T] = scala.reflect.ArrayTag[T]
- type ErasureTag[T] = scala.reflect.ErasureTag[T]
type ClassTag[T] = scala.reflect.ClassTag[T]
type TypeTag[T] = scala.reflect.TypeTag[T]
type ConcreteTypeTag[T] = scala.reflect.ConcreteTypeTag[T]
@@ -124,7 +123,6 @@ object Predef extends LowPriorityImplicits {
// [Eugene to Martin] it's really tedious to type "implicitly[...]" all the time, so I'm reintroducing these shortcuts
def arrayTag[T](implicit atag: ArrayTag[T]) = atag
- def erasureTag[T](implicit etag: ErasureTag[T]) = etag
def classTag[T](implicit ctag: ClassTag[T]) = ctag
def tag[T](implicit ttag: TypeTag[T]) = ttag
def typeTag[T](implicit ttag: TypeTag[T]) = ttag
diff --git a/src/library/scala/ref/WeakReference.scala b/src/library/scala/ref/WeakReference.scala
index 98cfb2c84b..322eab0be4 100644
--- a/src/library/scala/ref/WeakReference.scala
+++ b/src/library/scala/ref/WeakReference.scala
@@ -10,6 +10,9 @@
package scala.ref
/**
+ * A wrapper class for java.lag.ref.WeakReference
+ * The new functionality is (1) results are Option values, instead of using null.
+ * (2) There is an extractor that maps the weak reference itself into an option.
* @author Sean McDirmid
*/
class WeakReference[+T <: AnyRef](value: T, queue: ReferenceQueue[T]) extends ReferenceWrapper[T] {
@@ -18,6 +21,19 @@ class WeakReference[+T <: AnyRef](value: T, queue: ReferenceQueue[T]) extends Re
new WeakReferenceWithWrapper[T](value, queue, this)
}
+/** An extractor for weak reference values */
+object WeakReference {
+
+ /** Creates a weak reference pointing to `value` */
+ def apply[T <: AnyRef](value: T) = new WeakReference(value)
+
+ /** Optionally returns the referenced value, or `None` if that value no longer exists */
+ def unapply[T <: AnyRef](wr: WeakReference[T]): Option[T] = {
+ val x = wr.underlying.get
+ if (x != null) Some(x) else None
+ }
+}
+
/**
* @author Philipp Haller
*/
diff --git a/src/library/scala/reflect/ArrayTag.scala b/src/library/scala/reflect/ArrayTag.scala
index ba0c075723..3eba901f4f 100644
--- a/src/library/scala/reflect/ArrayTag.scala
+++ b/src/library/scala/reflect/ArrayTag.scala
@@ -13,7 +13,7 @@ package scala.reflect
* However other platforms (e.g. a Scala -> JS crosscompiler) may reimplement this trait as they see fit
* and then expose the implementation via an implicit macro.
*
- * @see [[scala.reflect.api.TypeTags]]
+ * @see [[scala.reflect.base.TypeTags]]
*/
@annotation.implicitNotFound(msg = "No ArrayTag available for ${T}")
trait ArrayTag[T] {
diff --git a/src/library/scala/reflect/ClassTag.scala b/src/library/scala/reflect/ClassTag.scala
index e485691747..ec66a42730 100644
--- a/src/library/scala/reflect/ClassTag.scala
+++ b/src/library/scala/reflect/ClassTag.scala
@@ -1,7 +1,6 @@
package scala.reflect
import java.lang.{ Class => jClass }
-import scala.reflect.{ mirror => rm }
import language.{implicitConversions, existentials}
import scala.runtime.ScalaRunTime.arrayClass
@@ -21,13 +20,16 @@ import scala.runtime.ScalaRunTime.arrayClass
* A ConcreteTypeTag member of the reflect.mirror object is convertible to a ClassTag via an implicit conversion
* (this is not possible to do in all reflection universes because an operation that converts a type to a Java class might not be available).
*
- * @see [[scala.reflect.api.TypeTags]]
+ * @see [[scala.reflect.base.TypeTags]]
*/
@annotation.implicitNotFound(msg = "No ClassTag available for ${T}")
-trait ClassTag[T] extends ArrayTag[T] with ErasureTag[T] with Equals with Serializable {
+trait ClassTag[T] extends ArrayTag[T] with Equals with Serializable {
// please, don't add any APIs here, like it was with `newWrappedArray` and `newArrayBuilder`
// class tags, and all tags in general, should be as minimalistic as possible
+ /** Returns an erasure of type `T` */
+ def erasure: jClass[_]
+
/** Produces a `ClassTag` that knows how to build `Array[Array[T]]` */
def wrap: ClassTag[Array[T]] = ClassTag[Array[T]](arrayClass(erasure))
diff --git a/src/library/scala/reflect/DummyMirror.scala b/src/library/scala/reflect/DummyMirror.scala
deleted file mode 100644
index aa731f62db..0000000000
--- a/src/library/scala/reflect/DummyMirror.scala
+++ /dev/null
@@ -1,783 +0,0 @@
-package scala.reflect
-
-import scala.reflect.api.AbsTreeGen
-import scala.reflect.api.Attachment
-import scala.reflect.api.Modifier
-import scala.reflect.api.Universe
-
-// todo. make Dummy objects not equal to themselves
-class DummyMirror(cl: ClassLoader) extends api.Mirror {
- // Members declared in scala.reflect.api.AnnotationInfos
- implicit def classfileAnnotArgTag: scala.reflect.ClassTag[ClassfileAnnotArg] = notSupported()
- type AnnotationInfo = DummyAnnotationInfo.type
- object DummyAnnotationInfo
- val AnnotationInfo: AnnotationInfoExtractor = DummyAnnotationInfoExtractor
- object DummyAnnotationInfoExtractor extends AnnotationInfoExtractor {
- def apply(atp: Type, args: List[Tree], assocs: List[(Name, ClassfileAnnotArg)]): AnnotationInfo = DummyAnnotationInfo
- def unapply(info: AnnotationInfo): Option[(Type, List[Tree], List[(Name, ClassfileAnnotArg)])] = notSupported()
- }
- type ClassfileAnnotArg = AnyRef
- type LiteralAnnotArg = DummyLiteralAnnotArg.type
- object DummyLiteralAnnotArg
- val LiteralAnnotArg: LiteralAnnotArgExtractor = DummyLiteralAnnotArgExtractor
- type ArrayAnnotArg = DummyArrayAnnotArg.type
- object DummyArrayAnnotArg
- val ArrayAnnotArg: ArrayAnnotArgExtractor = DummyArrayAnnotArgExtractor
- type NestedAnnotArg = DummyNestedAnnotArg.type
- object DummyNestedAnnotArg
- val NestedAnnotArg: NestedAnnotArgExtractor = DummyNestedAnnotArgExtractor
- object DummyLiteralAnnotArgExtractor extends LiteralAnnotArgExtractor {
- def apply(const: Constant): LiteralAnnotArg = DummyLiteralAnnotArg
- def unapply(arg: LiteralAnnotArg): Option[Constant] = notSupported()
- }
- object DummyArrayAnnotArgExtractor extends ArrayAnnotArgExtractor {
- def apply(const: Array[ClassfileAnnotArg]): ArrayAnnotArg = DummyArrayAnnotArg
- def unapply(arg: ArrayAnnotArg): Option[Array[ClassfileAnnotArg]] = notSupported()
- }
- object DummyNestedAnnotArgExtractor extends NestedAnnotArgExtractor {
- def apply(anninfo: AnnotationInfo): NestedAnnotArg = DummyNestedAnnotArg
- def unapply(arg: NestedAnnotArg): Option[AnnotationInfo] = notSupported()
- }
-
- // Members declared in scala.reflect.api.Constants
- type Constant = DummyConstant.type
- object DummyConstant extends AbsConstant {
- val value: Any = notSupported()
- def tpe: Type = notSupported()
- def isNaN: Boolean = notSupported()
- def booleanValue: Boolean = notSupported()
- def byteValue: Byte = notSupported()
- def shortValue: Short = notSupported()
- def charValue: Char = notSupported()
- def intValue: Int = notSupported()
- def longValue: Long = notSupported()
- def floatValue: Float = notSupported()
- def doubleValue: Double = notSupported()
- def stringValue: String = notSupported()
- def typeValue: Type = notSupported()
- def symbolValue: Symbol = notSupported()
- def convertTo(pt: Type): Constant = notSupported()
- }
- val Constant: ConstantExtractor = DummyConstantExtractor
- object DummyConstantExtractor extends ConstantExtractor {
- def apply(const: Any): Constant = DummyConstant
- def unapply(arg: Constant): Option[Any] = notSupported()
- }
-
- // Members declared in scala.reflect.api.FreeVars
- type FreeTerm = DummyFreeTerm.type
- val DummyFreeTerm = DummySymbol
- val FreeTerm: FreeTermExtractor = DummyFreeTermExtractor
- object DummyFreeTermExtractor extends FreeTermExtractor {
- def unapply(freeTerm: FreeTerm): Option[(TermName, Type, Any, String)] = notSupported()
- }
- type FreeType = DummyFreeType.type
- val DummyFreeType = DummySymbol
- val FreeType: FreeTypeExtractor = DummyFreeTypeExtractor
- object DummyFreeTypeExtractor extends FreeTypeExtractor {
- def unapply(freeType: FreeType): Option[(TypeName, Type, String)] = notSupported()
- }
- def freeTerms(tree: Tree): List[FreeTerm] = notSupported()
- def freeTypes(tree: Tree): List[FreeType] = notSupported()
- def substituteFreeTypes(tpe: Type,subs: Map[FreeType,Type]): Type = notSupported()
- def substituteFreeTypes(tree: Tree,subs: Map[FreeType,Type]): Tree = notSupported()
-
- // Members declared in scala.reflect.api.Importers
- def mkImporter(from0: scala.reflect.api.Universe): Importer{val from: from0.type} = notSupported()
-
- // Members declared in scala.reflect.api.Mirror
- def classLoader: ClassLoader = cl
- def classLoader_=(x$1: ClassLoader): Unit = notSupported()
- def classToSymbol(clazz: Class[_]): Symbol = notSupported()
- def classToType(clazz: Class[_]): Type = notSupported()
- def companionInstance(clazz: Symbol): AnyRef = notSupported()
- def getValueOfField(receiver: AnyRef,field: Symbol): Any = notSupported()
- def invoke(receiver: AnyRef,meth: Symbol)(args: Any*): Any = notSupported()
- def setValueOfField(receiver: AnyRef,field: Symbol,value: Any): Unit = notSupported()
- def symbolForName(name: String): Symbol = notSupported()
- def symbolOfInstance(instance: Any): Symbol = notSupported()
- def symbolToClass(sym: Symbol): Class[_] = notSupported()
- def typeOfInstance(instance: Any): Type = notSupported()
- def typeToClass(tpe: Type): Class[_] = notSupported()
-
- // Members declared in scala.reflect.api.Names
- type Name = DummyName.type
- type TypeName = DummyName.type
- type TermName = DummyName.type
- object DummyName extends AbsName {
- def isTermName: Boolean = notSupported()
- def isTypeName: Boolean = notSupported()
- def toTermName: TermName = notSupported()
- def toTypeName: TypeName = notSupported()
- def decoded: String = notSupported()
- def encoded: String = notSupported()
- def decodedName: Name = notSupported()
- def encodedName: Name = notSupported()
- }
- def newTermName(s: String): TermName = notSupported()
- def newTypeName(s: String): TypeName = notSupported()
-
- // Members declared in scala.reflect.api.Positions
- type Position = DummyPosition.type
- object DummyPosition extends api.Position {
- def pos: Position = notSupported()
- def withPos(newPos: scala.reflect.api.Position): Attachment = notSupported()
- def payload: Any = notSupported()
- def withPayload(newPayload: Any): Attachment = notSupported()
- def fileInfo: java.io.File = notSupported()
- def fileContent: Array[Char] = notSupported()
- def isDefined: Boolean = notSupported()
- def isTransparent: Boolean = notSupported()
- def isRange: Boolean = notSupported()
- def isOpaqueRange: Boolean = notSupported()
- def makeTransparent: Position = notSupported()
- def start: Int = notSupported()
- def startOrPoint: Int = notSupported()
- def point: Int = notSupported()
- def pointOrElse(default: Int): Int = notSupported()
- def end: Int = notSupported()
- def endOrPoint: Int = notSupported()
- def withStart(off: Int): Position = notSupported()
- def withEnd(off: Int): Position = notSupported()
- def withPoint(off: Int): Position = notSupported()
- def union(pos: scala.reflect.api.Position): Position = notSupported()
- def focusStart: Position = notSupported()
- def focus: Position = notSupported()
- def focusEnd: Position = notSupported()
- def includes(pos: scala.reflect.api.Position): Boolean = notSupported()
- def properlyIncludes(pos: scala.reflect.api.Position): Boolean = notSupported()
- def precedes(pos: scala.reflect.api.Position): Boolean = notSupported()
- def properlyPrecedes(pos: scala.reflect.api.Position): Boolean = notSupported()
- def overlaps(pos: scala.reflect.api.Position): Boolean = notSupported()
- def sameRange(pos: scala.reflect.api.Position): Boolean = notSupported()
- def line: Int = notSupported()
- def column: Int = notSupported()
- def toSingleLine: Position = notSupported()
- def lineContent: String = notSupported()
- def show: String = notSupported()
- }
- val NoPosition: Position = DummyPosition
- def atPos[T <: Tree](pos: Position)(tree: T): T = tree
- def ensureNonOverlapping(tree: Tree,others: List[Tree]): Unit = notSupported()
- def wrappingPos(trees: List[Tree]): Position = notSupported()
- def wrappingPos(default: Position,trees: List[Tree]): Position = notSupported()
-
- // Members declared in scala.reflect.api.FrontEnds
- def mkConsoleFrontEnd(minSeverity: Int): FrontEnd = notSupported()
-
- // Members declared in scala.reflect.api.Scopes
- type Scope = DummyScope.type
- object DummyScope extends Iterable[Symbol] {
- def iterator: Iterator[Symbol] = notSupported()
- }
- def newScope: Scope = DummyScope
- def newScopeWith(elems: Symbol*): Scope = DummyScope
- def newNestedScope(outer: Scope): Scope = DummyScope
-
- // Members declared in scala.reflect.api.StandardDefinitions
- val AnyRefTpe: Type = DummyType
- val AnyTpe: Type = DummyType
- val AnyValTpe: Type = DummyType
- val BooleanTpe: Type = DummyType
- val ByteTpe: Type = DummyType
- val CharTpe: Type = DummyType
- val DoubleTpe: Type = DummyType
- val FloatTpe: Type = DummyType
- val IntTpe: Type = DummyType
- val LongTpe: Type = DummyType
- val NothingTpe: Type = DummyType
- val NullTpe: Type = DummyType
- val ObjectTpe: Type = DummyType
- val ShortTpe: Type = DummyType
- val StringTpe: Type = DummyType
- val UnitTpe: Type = DummyType
- val definitions: AbsDefinitions = DummyDefinitions
- object DummyDefinitions extends AbsDefinitions {
- def ByNameParamClass = DummySymbol
- def JavaRepeatedParamClass = DummySymbol
- def RepeatedParamClass = DummySymbol
- def AnyClass = DummyClassSymbol
- def AnyRefClass = DummyTypeSymbol
- def AnyValClass = DummyClassSymbol
- def ArrayClass = DummyClassSymbol
- def ArrayModule = DummySymbol
- def ArrayModule_overloadedApply = DummySymbol
- def Array_apply = DummySymbol
- def Array_clone = DummySymbol
- def Array_length = DummySymbol
- def Array_update = DummySymbol
- def BooleanClass = DummyClassSymbol
- def ByteClass = DummyClassSymbol
- def CharClass = DummyClassSymbol
- def ClassClass = DummyClassSymbol
- def ClassTagClass = DummyClassSymbol
- def ClassTagModule = DummySymbol
- def ConcreteTypeTagClass = DummyClassSymbol
- def ConcreteTypeTagModule = DummySymbol
- def ConsClass = DummySymbol
- def DoubleClass = DummyClassSymbol
- def EmptyPackage = DummyPackageSymbol
- def EmptyPackageClass = DummySymbol
- def FloatClass = DummyClassSymbol
- def FunctionClass: Array[Symbol] = Array()
- def IntClass = DummyClassSymbol
- def IterableClass = DummySymbol
- def IteratorClass = DummySymbol
- def IteratorModule = DummySymbol
- def Iterator_apply = DummySymbol
- def JavaLangPackage = DummyPackageSymbol
- def JavaLangPackageClass = DummySymbol
- def ListClass = DummyClassSymbol
- def ListModule = DummyModuleSymbol
- def List_apply = DummySymbol
- def LongClass = DummyClassSymbol
- def NilModule = DummySymbol
- def NoneModule = DummySymbol
- def NothingClass = DummyClassSymbol
- def NullClass = DummyClassSymbol
- def ObjectClass = DummyClassSymbol
- def OptionClass = DummySymbol
- def PredefModule = DummyModuleSymbol
- def ProductClass: Array[Symbol] = Array()
- def RootClass = DummyClassSymbol
- def RootPackage = DummyPackageSymbol
- def ScalaPackage = DummyPackageSymbol
- def ScalaPackageClass = DummySymbol
- def ScalaPrimitiveValueClasses = Nil
- def SeqClass = DummySymbol
- def SeqModule = DummySymbol
- def ShortClass = DummyClassSymbol
- def SomeClass = DummySymbol
- def SomeModule = DummySymbol
- def StringBuilderClass = DummySymbol
- def StringClass = DummyClassSymbol
- def SymbolClass = DummySymbol
- def TraversableClass = DummySymbol
- def TupleClass: Array[Symbol] = Array()
- def TypeTagClass = DummyClassSymbol
- def TypeTagModule = DummySymbol
- def UnitClass = DummyClassSymbol
- def isNumericValueClass(sym: Symbol): Boolean = notSupported()
- def isPrimitiveValueClass(sym: Symbol): Boolean = notSupported()
- def vmClassType(arg: Type): Type = DummyType
- def vmSignature(sym: Symbol,info: Type): String = notSupported()
- }
-
- // Members declared in scala.reflect.api.StandardNames
- val nme: AbsTermNames = DummyAbsTermNames
- val tpnme: AbsTypeNames = DummyAbsTypeNames
- object DummyAbsTermNames extends AbsTermNames {
- type NameType = TermName
- val EMPTY: NameType = DummyName
- val ANON_FUN_NAME: NameType = DummyName
- val ANON_CLASS_NAME: NameType = DummyName
- val EMPTY_PACKAGE_NAME: NameType = DummyName
- val IMPORT: NameType = DummyName
- val MODULE_VAR_SUFFIX: NameType = DummyName
- val ROOT: NameType = DummyName
- val PACKAGE: NameType = DummyName
- val SPECIALIZED_SUFFIX: NameType = DummyName
- val ERROR: NameType = DummyName
- val NO_NAME: NameType = DummyName
- val WILDCARD: NameType = DummyName
- def flattenedName(segments: Name*): NameType = notSupported()
- val EXPAND_SEPARATOR_STRING: String = ""
- val ANYNAME: TermName = DummyName
- val CONSTRUCTOR: TermName = DummyName
- val FAKE_LOCAL_THIS: TermName = DummyName
- val INITIALIZER: TermName = DummyName
- val LAZY_LOCAL: TermName = DummyName
- val LOCAL_SUFFIX_STRING: String = ""
- val MIRROR_PREFIX: TermName = DummyName
- val MIRROR_SHORT: TermName = DummyName
- val MIRROR_FREE_PREFIX: TermName = DummyName
- val MIRROR_FREE_THIS_SUFFIX: TermName = DummyName
- val MIRROR_FREE_VALUE_SUFFIX: TermName = DummyName
- val MIRROR_SYMDEF_PREFIX: TermName = DummyName
- val MIXIN_CONSTRUCTOR: TermName = DummyName
- val MODULE_INSTANCE_FIELD: TermName = DummyName
- val OUTER: TermName = DummyName
- val OUTER_LOCAL: TermName = DummyName
- val OUTER_SYNTH: TermName = DummyName
- val SELECTOR_DUMMY: TermName = DummyName
- val SELF: TermName = DummyName
- val SPECIALIZED_INSTANCE: TermName = DummyName
- val STAR: TermName = DummyName
- val THIS: TermName = DummyName
- val BITMAP_NORMAL: TermName = DummyName
- val BITMAP_TRANSIENT: TermName = DummyName
- val BITMAP_CHECKINIT: TermName = DummyName
- val BITMAP_CHECKINIT_TRANSIENT: TermName = DummyName
- val INTERPRETER_IMPORT_WRAPPER: String = ""
- val INTERPRETER_LINE_PREFIX: String = ""
- val INTERPRETER_VAR_PREFIX: String = ""
- val INTERPRETER_WRAPPER_SUFFIX: String = ""
- val ROOTPKG: TermName = DummyName
- val ADD: TermName = DummyName
- val AND: TermName = DummyName
- val ASR: TermName = DummyName
- val DIV: TermName = DummyName
- val EQ: TermName = DummyName
- val EQL: TermName = DummyName
- val GE: TermName = DummyName
- val GT: TermName = DummyName
- val HASHHASH: TermName = DummyName
- val LE: TermName = DummyName
- val LSL: TermName = DummyName
- val LSR: TermName = DummyName
- val LT: TermName = DummyName
- val MINUS: TermName = DummyName
- val MOD: TermName = DummyName
- val MUL: TermName = DummyName
- val NE: TermName = DummyName
- val OR: TermName = DummyName
- val PLUS : TermName = DummyName
- val SUB: TermName = DummyName
- val XOR: TermName = DummyName
- val ZAND: TermName = DummyName
- val ZOR: TermName = DummyName
- val UNARY_~ : TermName = DummyName
- val UNARY_+ : TermName = DummyName
- val UNARY_- : TermName = DummyName
- val UNARY_! : TermName = DummyName
- val ??? : TermName = DummyName
- val MODULE_SUFFIX_NAME: TermName = DummyName
- val NAME_JOIN_NAME: TermName = DummyName
- val IMPL_CLASS_SUFFIX: String = ""
- val LOCALDUMMY_PREFIX: String = ""
- val PROTECTED_PREFIX: String = ""
- val PROTECTED_SET_PREFIX: String = ""
- val SINGLETON_SUFFIX: String = ""
- val SUPER_PREFIX_STRING: String = ""
- val TRAIT_SETTER_SEPARATOR_STRING: String = ""
- val SETTER_SUFFIX: TermName = DummyName
- def isConstructorName(name: Name): Boolean = notSupported()
- def isExceptionResultName(name: Name): Boolean = notSupported()
- def isImplClassName(name: Name): Boolean = notSupported()
- def isLocalDummyName(name: Name): Boolean = notSupported()
- def isLocalName(name: Name): Boolean = notSupported()
- def isLoopHeaderLabel(name: Name): Boolean = notSupported()
- def isProtectedAccessorName(name: Name): Boolean = notSupported()
- def isSuperAccessorName(name: Name): Boolean = notSupported()
- def isReplWrapperName(name: Name): Boolean = notSupported()
- def isSetterName(name: Name): Boolean = notSupported()
- def isTraitSetterName(name: Name): Boolean = notSupported()
- def isSingletonName(name: Name): Boolean = notSupported()
- def isModuleName(name: Name): Boolean = notSupported()
- def isOpAssignmentName(name: Name): Boolean = notSupported()
- def segments(name: String, assumeTerm: Boolean): List[Name] = notSupported()
- def originalName(name: Name): Name = notSupported()
- def stripModuleSuffix(name: Name): Name = notSupported()
- def unspecializedName(name: Name): Name = notSupported()
- def splitSpecializedName(name: Name): (Name, String, String) = notSupported()
- def dropLocalSuffix(name: Name): Name = notSupported()
- def expandedName(name: TermName, base: Symbol, separator: String = EXPAND_SEPARATOR_STRING): TermName = notSupported()
- def expandedSetterName(name: TermName, base: Symbol): TermName = notSupported()
- def protName(name: Name): TermName = notSupported()
- def protSetterName(name: Name): TermName = notSupported()
- def getterName(name: TermName): TermName = notSupported()
- def getterToLocal(name: TermName): TermName = notSupported()
- def getterToSetter(name: TermName): TermName = notSupported()
- def localToGetter(name: TermName): TermName = notSupported()
- def setterToGetter(name: TermName): TermName = notSupported()
- def defaultGetterName(name: Name, pos: Int): TermName = notSupported()
- def defaultGetterToMethod(name: Name): TermName = notSupported()
- def localDummyName(clazz: Symbol): TermName = notSupported()
- def superName(name: Name): TermName = notSupported()
- }
- object DummyAbsTypeNames extends AbsTypeNames {
- type NameType = TypeName
- val EMPTY: NameType = DummyName
- val ANON_FUN_NAME: NameType = DummyName
- val ANON_CLASS_NAME: NameType = DummyName
- val EMPTY_PACKAGE_NAME: NameType = DummyName
- val IMPORT: NameType = DummyName
- val MODULE_VAR_SUFFIX: NameType = DummyName
- val ROOT: NameType = DummyName
- val PACKAGE: NameType = DummyName
- val SPECIALIZED_SUFFIX: NameType = DummyName
- val ERROR: NameType = DummyName
- val NO_NAME: NameType = DummyName
- val WILDCARD: NameType = DummyName
- def flattenedName(segments: Name*): NameType = notSupported()
- val REFINE_CLASS_NAME: TypeName = DummyName
- val BYNAME_PARAM_CLASS_NAME: TypeName = DummyName
- val EQUALS_PATTERN_NAME: TypeName = DummyName
- val JAVA_REPEATED_PARAM_CLASS_NAME: TypeName = DummyName
- val LOCAL_CHILD: TypeName = DummyName
- val REPEATED_PARAM_CLASS_NAME: TypeName = DummyName
- val WILDCARD_STAR: TypeName = DummyName
-
- def dropSingletonName(name: Name): TypeName = notSupported()
- def singletonName(name: Name): TypeName = notSupported()
- def implClassName(name: Name): TypeName = notSupported()
- def interfaceName(implname: Name): TypeName = notSupported()
- }
-
- // Members declared in scala.reflect.api.Symbols
- val NoSymbol = DummySymbol
- type Symbol = DummySymbolApi
- object DummySymbol extends DummySymbolApi
- type TypeSymbol = DummyTypeSymbolApi
- object DummyTypeSymbol extends DummyTypeSymbolApi
- type TermSymbol = DummyTermSymbolApi
- object DummyTermSymbol extends DummyTermSymbolApi
- type MethodSymbol = DummyMethodSymbolApi
- object DummyMethodSymbol extends DummyMethodSymbolApi
- type ModuleSymbol = DummyModuleSymbolApi
- object DummyModuleSymbol extends DummyModuleSymbolApi
- type PackageSymbol = DummyPackageSymbolApi
- object DummyPackageSymbol extends DummyPackageSymbolApi
- type ClassSymbol = DummyClassSymbolApi
- object DummyClassSymbol extends DummyClassSymbolApi
- trait DummySymbolApi extends AbsSymbol {
- this: Symbol =>
-
- def pos: Position = notSupported()
- def modifiers: Set[Modifier] = notSupported()
- def hasModifier(mod: Modifier): Boolean = notSupported()
- def annotations: List[AnnotationInfo] = notSupported()
- def hasAnnotation(sym: Symbol): Boolean = notSupported()
- def owner: Symbol = notSupported()
- def name: Name = notSupported()
- def fullName: String = notSupported()
- def id: Int = notSupported()
- def orElse(alt: => Symbol): Symbol = notSupported()
- def filter(cond: Symbol => Boolean): Symbol = notSupported()
- def suchThat(cond: Symbol => Boolean): Symbol = notSupported()
- def privateWithin: Symbol = notSupported()
- def companionSymbol: Symbol = notSupported()
- def moduleClass: Symbol = notSupported()
- def enclosingTopLevelClass: Symbol = notSupported()
- def enclosingClass: Symbol = notSupported()
- def enclosingMethod: Symbol = notSupported()
- def enclosingPackageClass: Symbol = notSupported()
- def isTerm : Boolean = notSupported()
- def isPackage : Boolean = notSupported()
- def isMethod : Boolean = notSupported()
- def isOverloaded : Boolean = notSupported()
- def isFreeTerm : Boolean = notSupported()
- def isType : Boolean = notSupported()
- def isClass : Boolean = notSupported()
- def isPackageClass : Boolean = notSupported()
- def isPrimitiveValueClass: Boolean = notSupported()
- def isDerivedValueClass: Boolean = notSupported()
- def isAliasType : Boolean = notSupported()
- def isAbstractType : Boolean = notSupported()
- def isSkolem : Boolean = notSupported()
- def isExistential : Boolean = notSupported()
- def isFreeType : Boolean = notSupported()
- def isContravariant : Boolean = notSupported()
- def isCovariant : Boolean = notSupported()
- def isErroneous : Boolean = notSupported()
- def typeSignature: Type = notSupported()
- def typeSignatureIn(site: Type): Type = notSupported()
- def asType: Type = notSupported()
- def asTypeIn(site: Type): Type = notSupported()
- def asTypeConstructor: Type = notSupported()
- def thisPrefix: Type = notSupported()
- def selfType: Type = notSupported()
- def alternatives: List[Symbol] = notSupported()
- def resolveOverloaded(pre: Type = NoPrefix, targs: Seq[Type] = List(), actuals: Seq[Type]): Symbol = notSupported()
- def newNestedSymbol(name: Name, pos: Position, flags: Long, isClass: Boolean): Symbol = notSupported()
- def setInternalFlags(flags: Long): this.type = notSupported()
- def setTypeSignature(tpe: Type): this.type = notSupported()
- def setAnnotations(annots: AnnotationInfo*): this.type = notSupported()
- def kind: String = notSupported()
- }
- trait DummyTypeSymbolApi extends DummySymbolApi with TypeSymbolApi {
- this: TypeSymbol =>
- }
- trait DummyTermSymbolApi extends DummySymbolApi with TermSymbolApi {
- this: TermSymbol =>
- }
- trait DummyMethodSymbolApi extends DummyTermSymbolApi with MethodSymbolApi {
- this: MethodSymbol =>
- }
- trait DummyModuleSymbolApi extends DummyTermSymbolApi with ModuleSymbolApi {
- this: ModuleSymbol =>
- }
- trait DummyPackageSymbolApi extends DummyModuleSymbolApi with PackageSymbolApi {
- this: PackageSymbol =>
- }
- trait DummyClassSymbolApi extends DummyTypeSymbolApi with ClassSymbolApi {
- this: ClassSymbol =>
- }
-
- // Members declared in scala.reflect.api.ToolBoxes
- def mkToolBox(frontEnd: FrontEnd, options: String): AbsToolBox = notSupported()
-
- // Members declared in scala.reflect.api.TreeBuildUtil
- // type TreeGen = DummyTreeGen.type // [Eugene] cannot compile if uncomment this
- val gen: TreeGen{val global: DummyMirror.this.type} = DummyTreeGen.asInstanceOf[TreeGen{val global: DummyMirror.this.type}]
- def modifiersFromInternalFlags(flags: Long,privateWithin: Name,annotations: List[Tree]): Modifiers = DummyModifiers
- def newFreeExistential(name: String,info: Type,value: => Any,flags: Long,origin: String) = DummySymbol
- def newFreeTerm(name: String,info: Type,value: => Any,flags: Long,origin: String) = DummySymbol
- def newFreeType(name: String,info: Type,value: => Any,flags: Long,origin: String) = DummySymbol
- def selectOverloadedMethod(owner: Symbol,name: String,index: Int) = DummySymbol
- def selectOverloadedMethodIfDefined(owner: Symbol,name: String,index: Int) = DummySymbol
- def selectTerm(owner: Symbol,name: String) = DummySymbol
- def selectTermIfDefined(owner: Symbol,name: String) = DummySymbol
- def selectType(owner: Symbol,name: String) = DummySymbol
- def selectTypeIfDefined(owner: Symbol,name: String) = DummySymbol
- def staticClass(fullName: String) = DummySymbol
- def staticClassIfDefined(fullName: String) = DummySymbol
- def staticModule(fullName: String) = DummySymbol
- def staticModuleIfDefined(fullName: String) = DummySymbol
- def thisModuleType(fullName: String): Type = DummyType
- object DummyTreeGen extends AbsTreeGen {
- val global: Universe = DummyMirror.this
- type TreeGenTree = global.Tree
- type TreeGenType = global.Type
- type TreeGenSymbol = global.Symbol
- type TreeGenName = global.Name
- def mkAttributedQualifier(tpe: TreeGenType): TreeGenTree = notSupported()
- def mkAttributedQualifier(tpe: TreeGenType, termSym: TreeGenSymbol): TreeGenTree = notSupported()
- def mkAttributedRef(pre: TreeGenType, sym: TreeGenSymbol): TreeGenTree = notSupported()
- def mkAttributedRef(sym: TreeGenSymbol): TreeGenTree = notSupported()
- def mkAttributedThis(sym: TreeGenSymbol): TreeGenTree = notSupported()
- def mkAttributedIdent(sym: TreeGenSymbol): TreeGenTree = notSupported()
- def mkAttributedSelect(qual: TreeGenTree, sym: TreeGenSymbol): TreeGenTree = notSupported()
- def mkMethodCall(target: TreeGenTree,targs: List[TreeGenType],args: List[TreeGenTree]): TreeGenTree = notSupported()
- def mkMethodCall(receiver: TreeGenTree,method: TreeGenSymbol,targs: List[TreeGenType],args: List[TreeGenTree]): TreeGenTree = notSupported()
- def mkMethodCall(receiver: TreeGenSymbol,methodName: TreeGenName,args: List[TreeGenTree]): TreeGenTree = notSupported()
- def mkMethodCall(target: TreeGenTree,args: List[TreeGenTree]): TreeGenTree = notSupported()
- def mkMethodCall(method: TreeGenSymbol,args: List[TreeGenTree]): TreeGenTree = notSupported()
- def mkMethodCall(method: TreeGenSymbol,targs: List[TreeGenType],args: List[TreeGenTree]): TreeGenTree = notSupported()
- def mkMethodCall(receiver: TreeGenSymbol,methodName: TreeGenName,targs: List[TreeGenType],args: List[TreeGenTree]): TreeGenTree = notSupported()
- def mkNullaryCall(method: TreeGenSymbol,targs: List[TreeGenType]): TreeGenTree = notSupported()
- }
-
- // Members declared in scala.reflect.api.TreePrinters
- def newTreePrinter(out: java.io.PrintWriter): TreePrinter = notSupported()
-
- // Members declared in scala.reflect.api.Trees
- def Apply(sym: Symbol,args: Tree*): Tree = Apply(EmptyTree, Nil)
- def Bind(sym: Symbol,body: Tree): Bind = Bind(DummyName, EmptyTree)
- def Block(stats: Tree*): Block = Block()
- def CaseDef(pat: Tree,body: Tree): CaseDef = CaseDef(EmptyTree, EmptyTree, EmptyTree)
- def ClassDef(sym: Symbol,impl: Template): ClassDef = ClassDef(DummyModifiers, DummyName, Nil, Template(Nil, emptyValDef, Nil))
- def DefDef(sym: Symbol,rhs: List[List[Symbol]] => Tree): DefDef = DefDef(DummyModifiers, DummyName, Nil, Nil, EmptyTree, EmptyTree)
- def DefDef(sym: Symbol,rhs: Tree): DefDef = DefDef(DummyModifiers, DummyName, Nil, Nil, EmptyTree, EmptyTree)
- def DefDef(sym: Symbol,mods: Modifiers,rhs: Tree): DefDef = DefDef(DummyModifiers, DummyName, Nil, Nil, EmptyTree, EmptyTree)
- def DefDef(sym: Symbol,vparamss: List[List[ValDef]],rhs: Tree): DefDef = DefDef(DummyModifiers, DummyName, Nil, Nil, EmptyTree, EmptyTree)
- def DefDef(sym: Symbol,mods: Modifiers,vparamss: List[List[ValDef]],rhs: Tree): DefDef = DefDef(DummyModifiers, DummyName, Nil, Nil, EmptyTree, EmptyTree)
- def Ident(sym: Symbol): Ident = Ident(DummyName)
- def Ident(name: String): Ident = Ident(DummyName)
- def LabelDef(sym: Symbol,params: List[Symbol],rhs: Tree): LabelDef = LabelDef(DummyName, Nil, EmptyTree)
- type Modifiers = DummyModifiers.type
- val NoMods: Modifiers = DummyModifiers
- object DummyModifiers extends AbsModifiers {
- def modifiers: Set[Modifier] = notSupported()
- def hasModifier(mod: Modifier): Boolean = notSupported()
- def privateWithin: Name = notSupported()
- def annotations: List[Tree] = notSupported()
- def mapAnnotations(f: List[Tree] => List[Tree]): Modifiers = notSupported()
- }
- def Modifiers(mods: Set[scala.reflect.api.Modifier],privateWithin: Name,annotations: List[Tree]): Modifiers = DummyModifiers
- def ModuleDef(sym: Symbol,impl: Template): ModuleDef = ModuleDef(DummyModifiers, DummyName, Template(Nil, emptyValDef, Nil))
- def New(sym: Symbol,args: Tree*): Tree = New(EmptyTree)
- def New(tpe: Type,args: Tree*): Tree = New(EmptyTree)
- def New(tpt: Tree,argss: List[List[Tree]]): Tree = New(EmptyTree)
- def Select(qualifier: Tree,sym: Symbol): Select = Select(EmptyTree, DummyName)
- def Select(qualifier: Tree,name: String): Select = Select(EmptyTree, DummyName)
- def Super(sym: Symbol,mix: TypeName): Tree = Super(EmptyTree, DummyName)
- def This(sym: Symbol): Tree = This(DummyName)
- def Throw(tpe: Type,args: Tree*): Throw = Throw(EmptyTree)
- def Try(body: Tree,cases: (Tree, Tree)*): Try = Try(EmptyTree)
- def TypeDef(sym: Symbol): TypeDef = TypeDef(DummyModifiers, DummyName, Nil, EmptyTree)
- def TypeDef(sym: Symbol,rhs: Tree): TypeDef = TypeDef(DummyModifiers, DummyName, Nil, EmptyTree)
- def ValDef(sym: Symbol): ValDef = ValDef(DummyModifiers, DummyName, EmptyTree, EmptyTree)
- def ValDef(sym: Symbol,rhs: Tree): ValDef = ValDef(DummyModifiers, DummyName, EmptyTree, EmptyTree)
- protected def duplicateTree(tree: Tree): Tree = notSupported()
- object emptyValDef extends ValDef(DummyModifiers, DummyName, EmptyTree, EmptyTree) { override def isEmpty = true }
- type TreeCopier = DummyTreeCopier.type
- def newStrictTreeCopier: TreeCopier = DummyTreeCopier
- def newLazyTreeCopier: TreeCopier = DummyTreeCopier
- object DummyTreeCopier extends TreeCopierOps {
- def ClassDef(tree: Tree, mods: Modifiers, name: Name, tparams: List[TypeDef], impl: Template): ClassDef = notSupported()
- def PackageDef(tree: Tree, pid: RefTree, stats: List[Tree]): PackageDef = notSupported()
- def ModuleDef(tree: Tree, mods: Modifiers, name: Name, impl: Template): ModuleDef = notSupported()
- def ValDef(tree: Tree, mods: Modifiers, name: Name, tpt: Tree, rhs: Tree): ValDef = notSupported()
- def DefDef(tree: Tree, mods: Modifiers, name: Name, tparams: List[TypeDef], vparamss: List[List[ValDef]], tpt: Tree, rhs: Tree): DefDef = notSupported()
- def TypeDef(tree: Tree, mods: Modifiers, name: Name, tparams: List[TypeDef], rhs: Tree): TypeDef = notSupported()
- def LabelDef(tree: Tree, name: Name, params: List[Ident], rhs: Tree): LabelDef = notSupported()
- def Import(tree: Tree, expr: Tree, selectors: List[ImportSelector]): Import = notSupported()
- def Template(tree: Tree, parents: List[Tree], self: ValDef, body: List[Tree]): Template = notSupported()
- def Block(tree: Tree, stats: List[Tree], expr: Tree): Block = notSupported()
- def CaseDef(tree: Tree, pat: Tree, guard: Tree, body: Tree): CaseDef = notSupported()
- def Alternative(tree: Tree, trees: List[Tree]): Alternative = notSupported()
- def Star(tree: Tree, elem: Tree): Star = notSupported()
- def Bind(tree: Tree, name: Name, body: Tree): Bind = notSupported()
- def UnApply(tree: Tree, fun: Tree, args: List[Tree]): UnApply = notSupported()
- def ArrayValue(tree: Tree, elemtpt: Tree, trees: List[Tree]): ArrayValue = notSupported()
- def Function(tree: Tree, vparams: List[ValDef], body: Tree): Function = notSupported()
- def Assign(tree: Tree, lhs: Tree, rhs: Tree): Assign = notSupported()
- def AssignOrNamedArg(tree: Tree, lhs: Tree, rhs: Tree): AssignOrNamedArg = notSupported()
- def If(tree: Tree, cond: Tree, thenp: Tree, elsep: Tree): If = notSupported()
- def Match(tree: Tree, selector: Tree, cases: List[CaseDef]): Match = notSupported()
- def Return(tree: Tree, expr: Tree): Return = notSupported()
- def Try(tree: Tree, block: Tree, catches: List[CaseDef], finalizer: Tree): Try = notSupported()
- def Throw(tree: Tree, expr: Tree): Throw = notSupported()
- def New(tree: Tree, tpt: Tree): New = notSupported()
- def Typed(tree: Tree, expr: Tree, tpt: Tree): Typed = notSupported()
- def TypeApply(tree: Tree, fun: Tree, args: List[Tree]): TypeApply = notSupported()
- def Apply(tree: Tree, fun: Tree, args: List[Tree]): Apply = notSupported()
- def ApplyDynamic(tree: Tree, qual: Tree, args: List[Tree]): ApplyDynamic = notSupported()
- def Super(tree: Tree, qual: Tree, mix: TypeName): Super = notSupported()
- def This(tree: Tree, qual: Name): This = notSupported()
- def Select(tree: Tree, qualifier: Tree, selector: Name): Select = notSupported()
- def Ident(tree: Tree, name: Name): Ident = notSupported()
- def ReferenceToBoxed(tree: Tree, idt: Ident): ReferenceToBoxed = notSupported()
- def Literal(tree: Tree, value: Constant): Literal = notSupported()
- def TypeTree(tree: Tree): TypeTree = notSupported()
- def Annotated(tree: Tree, annot: Tree, arg: Tree): Annotated = notSupported()
- def SingletonTypeTree(tree: Tree, ref: Tree): SingletonTypeTree = notSupported()
- def SelectFromTypeTree(tree: Tree, qualifier: Tree, selector: Name): SelectFromTypeTree = notSupported()
- def CompoundTypeTree(tree: Tree, templ: Template): CompoundTypeTree = notSupported()
- def AppliedTypeTree(tree: Tree, tpt: Tree, args: List[Tree]): AppliedTypeTree = notSupported()
- def TypeBoundsTree(tree: Tree, lo: Tree, hi: Tree): TypeBoundsTree = notSupported()
- def ExistentialTypeTree(tree: Tree, tpt: Tree, whereClauses: List[Tree]): ExistentialTypeTree = notSupported()
- }
-
- // Members declared in scala.reflect.api.Types
- type Type = DummyType.type
- type SingletonType = DummyType.type
- type CompoundType = DummyType.type
- type AnnotatedType = DummyType.type
- val AnnotatedType: AnnotatedTypeExtractor = DummyAnnotatedTypeExtractor
- type BoundedWildcardType = DummyType.type
- val BoundedWildcardType: BoundedWildcardTypeExtractor = DummyBoundedWildcardTypeExtractor
- type ClassInfoType = DummyType.type
- val ClassInfoType: ClassInfoTypeExtractor = DummyClassInfoTypeExtractor
- type ConstantType = DummyType.type
- val ConstantType: ConstantTypeExtractor = DummyConstantTypeExtractor
- type ExistentialType = DummyType.type
- val ExistentialType: ExistentialTypeExtractor = DummyExistentialTypeExtractor
- type MethodType = DummyType.type
- val MethodType: MethodTypeExtractor = DummyMethodTypeExtractor
- val NoPrefix: Type = DummyType
- val NoType: Type = DummyType
- type NullaryMethodType = DummyType.type
- val NullaryMethodType: NullaryMethodTypeExtractor = DummyNullaryMethodTypeExtractor
- type PolyType = DummyType.type
- val PolyType: PolyTypeExtractor = DummyPolyTypeExtractor
- type RefinedType = DummyType.type
- val RefinedType: RefinedTypeExtractor = DummyRefinedTypeExtractor
- type SingleType = DummyType.type
- val SingleType: SingleTypeExtractor = DummySingleTypeExtractor
- type SuperType = DummyType.type
- val SuperType: SuperTypeExtractor = DummySuperTypeExtractor
- type ThisType = DummyType.type
- val ThisType: ThisTypeExtractor = DummyThisTypeExtractor
- type TypeBounds = DummyType.type
- val TypeBounds: TypeBoundsExtractor = DummyTypeBoundsExtractor
- type TypeRef = DummyType.type
- val TypeRef: TypeRefExtractor = DummyTypeRefExtractor
- val WildcardType: Type = DummyType
- def appliedType(tycon: Type,args: List[Type]): Type = DummyType
- def existentialAbstraction(tparams: List[Symbol],tpe0: Type): Type = DummyType
- def glb(ts: List[Type]): Type = DummyType
- def intersectionType(tps: List[Type],owner: Symbol): Type = DummyType
- def intersectionType(tps: List[Type]): Type = DummyType
- def lub(xs: List[Type]): Type = DummyType
- def polyType(tparams: List[Symbol],tpe: Type): Type = DummyType
- def refinedType(parents: List[Type],owner: Symbol): Type = DummyType
- def refinedType(parents: List[Type],owner: Symbol,decls: Scope,pos: Position): Type = DummyType
- def singleType(pre: Type,sym: Symbol): Type = DummyType
- def typeRef(pre: Type,sym: Symbol,args: List[Type]): Type = DummyType
- object DummyType extends AbsType {
- def =:=(that: Type): Boolean = notSupported()
- def <:<(that: Type): Boolean = notSupported()
- def asSeenFrom(pre: Type,clazz: Symbol): Type = notSupported()
- def baseClasses: List[Symbol] = notSupported()
- def baseType(clazz: Symbol): Type = notSupported()
- def contains(sym: Symbol): Boolean = notSupported()
- def declaration(name: Name): Symbol = notSupported()
- def declarations: Iterable[Symbol] = notSupported()
- def erasure: Type = notSupported()
- def exists(p: Type => Boolean): Boolean = notSupported()
- def find(p: Type => Boolean): Option[Type] = notSupported()
- def foreach(f: Type => Unit): Unit = notSupported()
- def isConcrete: Boolean = notSupported()
- def isHigherKinded: Boolean = notSupported()
- def isSpliceable: Boolean = notSupported()
- def kind: String = notSupported()
- def map(f: Type => Type): Type = notSupported()
- def member(name: Name): Symbol = notSupported()
- def members: Iterable[Symbol] = notSupported()
- def nonPrivateMember(name: Name): Symbol = notSupported()
- def nonPrivateMembers: Iterable[Symbol] = notSupported()
- def normalize: Type = notSupported()
- def parents: List[Type] = notSupported()
- def substituteTypes(from: List[Symbol],to: List[Type]): Type = notSupported()
- def typeArguments: List[Type] = notSupported()
- def typeConstructor: Type = notSupported()
- def typeParams: List[Symbol] = notSupported()
- def typeSymbol: Symbol = notSupported()
- def underlying: Type = notSupported()
- def widen: Type = notSupported()
- }
- object DummyAnnotatedTypeExtractor extends AnnotatedTypeExtractor {
- def apply(annotations: List[AnnotationInfo], underlying: Type, selfsym: Symbol): AnnotatedType = DummyType
- def unapply(tpe: AnnotatedType): Option[(List[AnnotationInfo], Type, Symbol)] = notSupported()
- }
- object DummyBoundedWildcardTypeExtractor extends BoundedWildcardTypeExtractor {
- def apply(bounds: TypeBounds): BoundedWildcardType = DummyType
- def unapply(tpe: BoundedWildcardType): Option[TypeBounds] = notSupported()
- }
- object DummyClassInfoTypeExtractor extends ClassInfoTypeExtractor {
- def apply(parents: List[Type], decls: Scope, clazz: Symbol): ClassInfoType = DummyType
- def unapply(tpe: ClassInfoType): Option[(List[Type], Scope, Symbol)] = notSupported()
- }
- object DummyConstantTypeExtractor extends ConstantTypeExtractor {
- def apply(value: Constant): ConstantType = DummyType
- def unapply(tpe: ConstantType): Option[Constant] = notSupported()
- }
- object DummyExistentialTypeExtractor extends ExistentialTypeExtractor {
- def apply(quantified: List[Symbol], underlying: Type): ExistentialType = DummyType
- def unapply(tpe: ExistentialType): Option[(List[Symbol], Type)] = notSupported()
- }
- object DummyMethodTypeExtractor extends MethodTypeExtractor {
- def apply(params: List[Symbol], resultType: Type): MethodType = DummyType
- def unapply(tpe: MethodType): Option[(List[Symbol], Type)] = notSupported()
- }
- object DummyNullaryMethodTypeExtractor extends NullaryMethodTypeExtractor {
- def apply(resultType: Type): NullaryMethodType = DummyType
- def unapply(tpe: NullaryMethodType): Option[(Type)] = notSupported()
- }
- object DummyPolyTypeExtractor extends PolyTypeExtractor {
- def apply(typeParams: List[Symbol], resultType: Type): PolyType = DummyType
- def unapply(tpe: PolyType): Option[(List[Symbol], Type)] = notSupported()
- }
- object DummyRefinedTypeExtractor extends RefinedTypeExtractor {
- def apply(parents: List[Type], decls: Scope): RefinedType = DummyType
- def apply(parents: List[Type], decls: Scope, clazz: Symbol): RefinedType = DummyType
- def unapply(tpe: RefinedType): Option[(List[Type], Scope)] = notSupported()
- }
- object DummySingleTypeExtractor extends SingleTypeExtractor {
- def apply(pre: Type, sym: Symbol): Type = DummyType
- def unapply(tpe: SingleType): Option[(Type, Symbol)] = notSupported()
- }
- object DummySuperTypeExtractor extends SuperTypeExtractor {
- def apply(thistpe: Type, supertpe: Type): Type = DummyType
- def unapply(tpe: SuperType): Option[(Type, Type)] = notSupported()
- }
- object DummyThisTypeExtractor extends ThisTypeExtractor {
- def apply(sym: Symbol): Type = DummyType
- def unapply(tpe: ThisType): Option[Symbol] = notSupported()
- }
- object DummyTypeBoundsExtractor extends TypeBoundsExtractor {
- def apply(lo: Type, hi: Type): TypeBounds = DummyType
- def unapply(tpe: TypeBounds): Option[(Type, Type)] = notSupported()
- }
- object DummyTypeRefExtractor extends TypeRefExtractor {
- def apply(pre: Type, sym: Symbol, args: List[Type]): Type = DummyType
- def unapply(tpe: TypeRef): Option[(Type, Symbol, List[Type])] = notSupported()
- }
-
- // Utils
- def notSupported() = {
- throw new UnsupportedOperationException("Scala reflection not available on this platform." + mirrorDiagnostics(cl))
- }
-} \ No newline at end of file
diff --git a/src/library/scala/reflect/ErasureTag.scala b/src/library/scala/reflect/ErasureTag.scala
deleted file mode 100644
index f95451fab2..0000000000
--- a/src/library/scala/reflect/ErasureTag.scala
+++ /dev/null
@@ -1,23 +0,0 @@
-package scala.reflect
-
-import java.lang.{Class => jClass}
-
-/** An `ErasureTag[T]` is a descriptor that is requested by the compiler every time
- * when it needs to persist an erasure of a type.
- *
- * Scala library provides a standard implementation of this trait,
- * `TypeTag[T]` that carries the `java.lang.Class` erasure for arbitrary types.
- *
- * However other platforms may reimplement this trait as they see fit
- * and then expose the implementation via an implicit macro.
- *
- * If you need to guarantee that the type does not contain
- * references to type parameters or abstract types, use `ClassTag[T]`.
- *
- * @see [[scala.reflect.api.TypeTags]]
- */
-@annotation.implicitNotFound(msg = "No ErasureTag available for ${T}")
-trait ErasureTag[T] {
- /** Returns an erasure of type `T` */
- def erasure: jClass[_]
-}
diff --git a/src/library/scala/reflect/Manifest.scala b/src/library/scala/reflect/Manifest.scala
index da029f046d..559b82b177 100644
--- a/src/library/scala/reflect/Manifest.scala
+++ b/src/library/scala/reflect/Manifest.scala
@@ -9,7 +9,6 @@
package scala.reflect
import scala.collection.mutable.{ ArrayBuilder, WrappedArray }
-import mirror._
/** A `Manifest[T]` is an opaque descriptor for type T. Its supported use
* is to give access to the erasure of the type as a `Class` instance, as
diff --git a/src/library/scala/reflect/TagInterop.scala b/src/library/scala/reflect/TagInterop.scala
deleted file mode 100644
index 6c6bfcc2f2..0000000000
--- a/src/library/scala/reflect/TagInterop.scala
+++ /dev/null
@@ -1,34 +0,0 @@
-package scala.reflect
-
-import scala.runtime.ScalaRunTime._
-import mirror._
-import definitions._
-
-object TagInterop {
- def arrayTagToClassManifest[T](tag: ArrayTag[T]): ClassManifest[T] = {
- val erasure = arrayElementClass(tag)
- if (erasure.isArray) {
- val elementClass = arrayElementClass(erasure)
- val elementManifest = arrayTagToClassManifest(ClassTag(elementClass))
- ClassManifest.arrayType(elementManifest).asInstanceOf[ClassManifest[T]]
- } else {
- ClassManifest.fromClass(erasure.asInstanceOf[Class[T]])
- }
- }
-
- def concreteTypeTagToManifest[T](tag: ConcreteTypeTag[T]): Manifest[T] = {
- // todo. reproduce manifest generation code here. toolboxes are too slow.
- val implicitly = PredefModule.typeSignature.member(newTermName("implicitly"))
- val taggedTpe = appliedType(staticClass("scala.reflect.Manifest").asTypeConstructor, List(tag.tpe))
- val materializer = TypeApply(Ident(implicitly), List(TypeTree(taggedTpe)))
- try mkToolBox().runExpr(materializer).asInstanceOf[Manifest[T]]
- catch { case ex: Throwable => Manifest.classType(tag.erasure).asInstanceOf[Manifest[T]] }
- }
-
- def manifestToConcreteTypeTag[T](tag: Manifest[T]): ConcreteTypeTag[T] = {
- val tpe =
- if (tag.typeArguments.isEmpty) classToType(tag.erasure)
- else appliedType(classToType(tag.erasure).typeConstructor, tag.typeArguments map (manifestToConcreteTypeTag(_)) map (_.tpe))
- ConcreteTypeTag(tpe, tag.erasure)
- }
-} \ No newline at end of file
diff --git a/src/library/scala/reflect/api/AnnotationInfos.scala b/src/library/scala/reflect/api/AnnotationInfos.scala
index cc1c4d2b6b..d9f35024d9 100755
--- a/src/library/scala/reflect/api/AnnotationInfos.scala
+++ b/src/library/scala/reflect/api/AnnotationInfos.scala
@@ -1,42 +1,27 @@
package scala.reflect
package api
-trait AnnotationInfos { self: Universe =>
+trait AnnotationInfos extends base.AnnotationInfos { self: Universe =>
- type AnnotationInfo <: AnyRef
- val AnnotationInfo: AnnotationInfoExtractor
-
- abstract class AnnotationInfoExtractor {
- def apply(atp: Type, args: List[Tree], assocs: List[(Name, ClassfileAnnotArg)]): AnnotationInfo
- def unapply(info: AnnotationInfo): Option[(Type, List[Tree], List[(Name, ClassfileAnnotArg)])]
+ override type AnnotationInfo >: Null <: AnyRef with AnnotationInfoApi
+ trait AnnotationInfoApi {
+ def atp: Type
+ def args: List[Tree]
+ def assocs: List[(Name, ClassfileAnnotArg)]
}
- type ClassfileAnnotArg <: AnyRef
- implicit def classfileAnnotArgTag: ArrayTag[ClassfileAnnotArg] // need a precise tag to pass to UnPickle's toArray call
-
- type LiteralAnnotArg <: ClassfileAnnotArg
- val LiteralAnnotArg: LiteralAnnotArgExtractor
-
- type ArrayAnnotArg <: ClassfileAnnotArg
- val ArrayAnnotArg: ArrayAnnotArgExtractor
-
- type NestedAnnotArg <: ClassfileAnnotArg
- val NestedAnnotArg: NestedAnnotArgExtractor
-
- abstract class LiteralAnnotArgExtractor {
- def apply(const: Constant): LiteralAnnotArg
- def unapply(arg: LiteralAnnotArg): Option[Constant]
+ override type LiteralAnnotArg >: Null <: ClassfileAnnotArg with LiteralAnnotArgApi
+ trait LiteralAnnotArgApi {
+ def const: Constant
}
- abstract class ArrayAnnotArgExtractor {
- def apply(const: Array[ClassfileAnnotArg]): ArrayAnnotArg
- def unapply(arg: ArrayAnnotArg): Option[Array[ClassfileAnnotArg]]
+ override type ArrayAnnotArg >: Null <: ClassfileAnnotArg with ArrayAnnotArgApi
+ trait ArrayAnnotArgApi {
+ def args: Array[ClassfileAnnotArg]
}
- abstract class NestedAnnotArgExtractor {
- def apply(anninfo: AnnotationInfo): NestedAnnotArg
- def unapply(arg: NestedAnnotArg): Option[AnnotationInfo]
+ override type NestedAnnotArg >: Null <: ClassfileAnnotArg with NestedAnnotArgApi
+ trait NestedAnnotArgApi {
+ def annInfo: AnnotationInfo
}
-}
-
-
+} \ No newline at end of file
diff --git a/src/library/scala/reflect/api/Attachment.scala b/src/library/scala/reflect/api/Attachment.scala
deleted file mode 100644
index 50f55b4aa5..0000000000
--- a/src/library/scala/reflect/api/Attachment.scala
+++ /dev/null
@@ -1,29 +0,0 @@
-package scala.reflect
-package api
-
-/** Attachment is a generalisation of Position.
- * Typically it stores a Position of a tree, but this can be extended to encompass arbitrary payloads.
- *
- * Attachments have to carry positions, because we don't want to introduce even a single additional field in Tree
- * imposing an unnecessary memory tax because of something that will not be used in most cases.
- */
-trait Attachment {
- /** Gets the underlying position */
- def pos: Position
-
- /** Creates a copy of this attachment with its position updated */
- def withPos(newPos: Position): Attachment
-
- /** Gets the underlying payload */
- def payload: Any
-
- /** Creates a copy of this attachment with its payload updated */
- def withPayload(newPayload: Any): Attachment
-}
-
-// [Eugene] with the introduction of `attach` and `attachment[T]` users don't need to create custom attachments anymore
-// however, we cannot move attachments to scala.reflect.internal, because they are used in Trees, which are implemented completely in scala.reflect.api
-private[scala] case class NontrivialAttachment(pos: api.Position, payload: collection.mutable.ListBuffer[Any]) extends Attachment {
- def withPos(newPos: api.Position) = copy(pos = newPos, payload = payload)
- def withPayload(newPayload: Any) = copy(pos = pos, payload = newPayload.asInstanceOf[collection.mutable.ListBuffer[Any]])
-} \ No newline at end of file
diff --git a/src/library/scala/reflect/api/ClassLoaders.scala b/src/library/scala/reflect/api/ClassLoaders.scala
deleted file mode 100644
index 7be402d3df..0000000000
--- a/src/library/scala/reflect/api/ClassLoaders.scala
+++ /dev/null
@@ -1,16 +0,0 @@
-package scala.reflect
-package api
-
-trait ClassLoaders { self: Universe =>
-
- /** The symbol corresponding to the globally accessible class with the
- * given fully qualified name `fullName`.
- */
- def staticClass(fullName: String): Symbol
-
- /** The symbol corresponding to the globally accessible object with the
- * given fully qualified name `fullName`.
- */
- def staticModule(fullName: String): Symbol
-
-} \ No newline at end of file
diff --git a/src/library/scala/reflect/api/Constants.scala b/src/library/scala/reflect/api/Constants.scala
index 42a0fa8a27..7862ab0d25 100755
--- a/src/library/scala/reflect/api/Constants.scala
+++ b/src/library/scala/reflect/api/Constants.scala
@@ -6,13 +6,12 @@
package scala.reflect
package api
-import java.lang.Integer.toOctalString
-import annotation.switch
-
-trait Constants {
+trait Constants extends base.Constants {
self: Universe =>
- abstract class AbsConstant {
+ override type Constant >: Null <: AnyRef with ConstantApi
+
+ abstract class ConstantApi {
val value: Any
def tpe: Type
def isNaN: Boolean
@@ -31,13 +30,4 @@ trait Constants {
def convertTo(pt: Type): Constant
}
-
- type Constant <: AbsConstant
-
- val Constant: ConstantExtractor
-
- abstract class ConstantExtractor {
- def apply(const: Any): Constant
- def unapply(arg: Constant): Option[Any]
- }
}
diff --git a/src/library/scala/reflect/api/Exprs.scala b/src/library/scala/reflect/api/Exprs.scala
index b8db64422e..dd09d8e7c6 100644
--- a/src/library/scala/reflect/api/Exprs.scala
+++ b/src/library/scala/reflect/api/Exprs.scala
@@ -6,14 +6,57 @@
package scala.reflect
package api
import language.implicitConversions
+import scala.reflect.base.TreeCreator
trait Exprs { self: Universe =>
/** An expression tree tagged with its type */
- case class Expr[+T: TypeTag](tree: Tree) {
- def tpe: Type = implicitly[TypeTag[T]].tpe
- def eval: T = mkToolBox().runExpr(tree).asInstanceOf[T]
- lazy val value: T = eval
- override def toString = "Expr["+tpe+"]("+tree+")"
+ trait Expr[+T] extends Equals with Serializable {
+ val mirror: Mirror
+ def in[U <: Universe with Singleton](otherMirror: MirrorOf[U]): U # Expr[T]
+
+ def tree: Tree
+ def staticTpe: Type
+ def actualTpe: Type
+
+ def splice: T
+ val value: T
+
+ /** case class accessories */
+ override def canEqual(x: Any) = x.isInstanceOf[Expr[_]]
+ override def equals(x: Any) = x.isInstanceOf[Expr[_]] && this.mirror == x.asInstanceOf[Expr[_]].mirror && this.tree == x.asInstanceOf[Expr[_]].tree
+ override def hashCode = mirror.hashCode * 31 + tree.hashCode
+ override def toString = "Expr["+staticTpe+"]("+tree+")"
+ }
+
+ object Expr {
+ def apply[T: TypeTag](mirror: MirrorOf[self.type], treec: TreeCreator): Expr[T] = new ExprImpl[T](mirror.asInstanceOf[Mirror], treec)
+ def unapply[T](expr: Expr[T]): Option[Tree] = Some(expr.tree)
+ }
+
+ private class ExprImpl[+T: TypeTag](val mirror: Mirror, val treec: TreeCreator) extends Expr[T] {
+ def in[U <: Universe with Singleton](otherMirror: MirrorOf[U]): U # Expr[T] = {
+ val otherMirror1 = otherMirror.asInstanceOf[MirrorOf[otherMirror.universe.type]]
+ val tag1 = (implicitly[TypeTag[T]] in otherMirror).asInstanceOf[otherMirror.universe.TypeTag[T]]
+ otherMirror.universe.Expr[T](otherMirror1, treec)(tag1)
+ }
+
+ lazy val tree: Tree = treec[Exprs.this.type](mirror)
+ // [Eugene++] this is important
+ // !!! remove when we have improved type inference for singletons
+ // search for .type] to find other instances
+ lazy val staticTpe: Type = implicitly[TypeTag[T]].tpe
+ def actualTpe: Type = tree.tpe
+
+ def splice: T = throw new UnsupportedOperationException("""
+ |the function you're calling has not been spliced by the compiler.
+ |this means there is a cross-stage evaluation involved, and it needs to be invoked explicitly.
+ |if you're sure this is not an oversight, add scala-compiler.jar to the classpath,
+ |import `scala.tools.reflect.Eval` and call `<your expr>.eval` instead.""".trim.stripMargin)
+ lazy val value: T = throw new UnsupportedOperationException("""
+ |the value you're calling is only meant to be used in cross-stage path-dependent types.
+ |if you want to splice the underlying expression, use `<your expr>.splice`.
+ |if you want to get a value of the underlying expression, add scala-compiler.jar to the classpath,
+ |import `scala.tools.reflect.Eval` and call `<your expr>.eval` instead.""".trim.stripMargin)
}
} \ No newline at end of file
diff --git a/src/library/scala/reflect/api/FlagSets.scala b/src/library/scala/reflect/api/FlagSets.scala
new file mode 100644
index 0000000000..969176d641
--- /dev/null
+++ b/src/library/scala/reflect/api/FlagSets.scala
@@ -0,0 +1,112 @@
+package scala.reflect
+package api
+
+import scala.language.implicitConversions
+
+trait FlagSets { self: Universe =>
+
+ type FlagSet
+
+ trait FlagOps extends Any {
+ def | (right: FlagSet): FlagSet
+ def & (right: FlagSet): FlagSet
+ def containsAll (right: FlagSet): Boolean
+ }
+
+ implicit def addFlagOps(left: FlagSet): FlagOps
+
+ val Flag: FlagValues
+
+ type FlagValues >: Null <: FlagValuesApi
+
+ // [Eugene++] any other flags we would like to expose?
+
+ trait FlagValuesApi {
+
+ /** Flag indicating that symbol or tree represents a trait */
+ val TRAIT: FlagSet
+
+ /** Flag indicating that symbol or tree represents a module or its internal module class */
+ val MODULE: FlagSet
+
+ /** Flag indicating that symbol or tree represents a mutable variable */
+ val MUTABLE: FlagSet
+
+ /** Flag indicating that symbol or tree represents a package or its internal package class */
+ val PACKAGE: FlagSet
+
+ /** Flag indicating that symbol or tree represents a method */
+ val METHOD: FlagSet
+
+ /** Flag indicating that symbol or tree represents a macro definition. */
+ val MACRO: FlagSet
+
+ /** Flag indicating that symbol or tree represents an abstract type, method, or value */
+ val DEFERRED: FlagSet
+
+ /** Flag indicating that symbol or tree represents an abstract class */
+ val ABSTRACT: FlagSet
+
+ /** Flag indicating that symbol or tree has `final` modifier set */
+ val FINAL: FlagSet
+
+ /** Flag indicating that symbol or tree has `sealed` modifier set */
+ val SEALED: FlagSet
+
+ /** Flag indicating that symbol or tree has `implicit` modifier set */
+ val IMPLICIT: FlagSet
+
+ /** Flag indicating that symbol or tree has `lazy` modifier set */
+ val LAZY: FlagSet
+
+ /** Flag indicating that symbol or tree has `override` modifier set */
+ val OVERRIDE: FlagSet
+
+ /** Flag indicating that symbol or tree has `private` modifier set */
+ val PRIVATE: FlagSet
+
+ /** Flag indicating that symbol or tree has `protected` modifier set */
+ val PROTECTED: FlagSet
+
+ /** Flag indicating that symbol or tree has `case` modifier set */
+ val CASE: FlagSet
+
+ /** Flag indicating that symbol or tree has `abstract` and `override` modifiers set */
+ val ABSOVERRIDE: FlagSet
+
+ /** Flag indicating that symbol or tree represents a by-name parameter */
+ val BYNAMEPARAM: FlagSet
+
+ /** Flag indicating that symbol or tree represents a class or parameter.
+ * Both type and value parameters carry the flag. */
+ val PARAM: FlagSet
+
+ /** Flag indicating that symbol or tree represents a field of a class
+ * that was generated from a parameter of that class */
+ val PARAMACCESSOR: FlagSet
+
+ /** Flag indicating that symbol or tree represents a field of a case class
+ * that corresponds to a parameter in the first parameter list of the
+ * primary constructor of that class */
+ val CASEACCESSOR: FlagSet
+
+ /** Flag indicating that symbol or tree represents a contravariant
+ * type parameter (marked with `+`). */
+ val COVARIANT: FlagSet
+
+ /** Flag indicating that symbol or tree represents a contravariant
+ * type parameter (marked with `-`). */
+ val CONTRAVARIANT: FlagSet
+
+ /** Flag indicating that parameter has a default value */
+ val DEFAULTPARAM: FlagSet
+
+ /** Flag indicating that trait has neither method implementations nor fields.
+ * This means the trait can be represented as a Java interface. */
+ val INTERFACE: FlagSet
+
+ def union(flags: FlagSet*): FlagSet
+ def intersection(flag: FlagSet*): FlagSet
+ def containsAll(superset: FlagSet, subset: FlagSet): Boolean
+ }
+}
diff --git a/src/library/scala/reflect/api/FreeVars.scala b/src/library/scala/reflect/api/FreeVars.scala
deleted file mode 100644
index 0bef099a55..0000000000
--- a/src/library/scala/reflect/api/FreeVars.scala
+++ /dev/null
@@ -1,42 +0,0 @@
-package scala.reflect
-package api
-
-trait FreeVars {
- self: Universe =>
-
- /** Represents a free term captured by reification.
- */
- type FreeTerm <: Symbol
-
- val FreeTerm: FreeTermExtractor
-
- abstract class FreeTermExtractor {
- def unapply(freeTerm: FreeTerm): Option[(TermName, Type, Any, String)]
- }
-
- /** Extracts free terms from a tree that is reified or contains reified subtrees.
- */
- def freeTerms(tree: Tree): List[FreeTerm]
-
- /** Represents a free type captured by reification.
- */
- type FreeType <: Symbol
-
- val FreeType: FreeTypeExtractor
-
- abstract class FreeTypeExtractor {
- def unapply(freeType: FreeType): Option[(TypeName, Type, String)]
- }
-
- /** Extracts free types from a tree that is reified or contains reified subtrees.
- */
- def freeTypes(tree: Tree): List[FreeType]
-
- /** Substitutes free types in a reified tree.
- */
- def substituteFreeTypes(tree: Tree, subs: Map[FreeType, Type]): Tree
-
- /** Substitutes free types in a reified type.
- */
- def substituteFreeTypes(tpe: Type, subs: Map[FreeType, Type]): Type
-}
diff --git a/src/library/scala/reflect/api/FrontEnds.scala b/src/library/scala/reflect/api/FrontEnds.scala
index 2c1f3feff6..a201b83444 100644
--- a/src/library/scala/reflect/api/FrontEnds.scala
+++ b/src/library/scala/reflect/api/FrontEnds.scala
@@ -1,7 +1,11 @@
package scala.reflect
package api
-trait FrontEnds { self: Universe =>
+// [Martin to Eugene] Todo: Needs to be evicted from API
+// [Eugene++ to Martin] but how? we need them for macros
+trait FrontEnds {
+
+ type Position >: Null
trait FrontEnd {
object severity extends Enumeration
diff --git a/src/library/scala/reflect/api/Importers.scala b/src/library/scala/reflect/api/Importers.scala
index 1d8890b7db..69d6414f4f 100644
--- a/src/library/scala/reflect/api/Importers.scala
+++ b/src/library/scala/reflect/api/Importers.scala
@@ -1,6 +1,8 @@
package scala.reflect
package api
+// [Martin] Importers need to be made mirror aware.
+// [Eugene++] this is important
trait Importers { self: Universe =>
def mkImporter(from0: Universe): Importer { val from: from0.type }
diff --git a/src/library/scala/reflect/api/Mirror.scala b/src/library/scala/reflect/api/Mirror.scala
deleted file mode 100644
index ed8ead7aaf..0000000000
--- a/src/library/scala/reflect/api/Mirror.scala
+++ /dev/null
@@ -1,100 +0,0 @@
-package scala.reflect
-package api
-
-/** A mirror establishes connections of
- * runtime entities such as class names and object instances
- * with a reflexive universe.
- */
-trait Mirror extends Universe {
-
- /** Class loader that is a mastermind behind the reflexive mirror.
- *
- * By default it is set to system classloader (more precisely, to the classloader that loads the `scala.reflect.package` class).
- * However, sometimes it is useful to have a mirror services by a custom classloader.
- *
- * There are two ways to customize the `classLoader`:
- * 1) Create a new mirror using the `scala.reflect.mkMirror(classLoader: ClassLoader)` method
- * 2) Set `classLoader` to the new value
- *
- * The first, immutable, way should be strongly preferred in most situation.
- * However sometimes it is necessary to migrate the default reflexive mirror (`scala.reflect.mirror`) to a new classloader.
- * In that and only that case, use the setter, but be very careful not to introduce inconsistencies.
- */
- var classLoader: ClassLoader
-
- /** The Scala class symbol that has given fully qualified name
- * @param name The fully qualified name of the class to be returned
- * @throws java.lang.ClassNotFoundException if no class with that name exists
- * to do: throws anything else?
- */
- def symbolForName(name: String): Symbol
-
- /** Return a reference to the companion object of the given class symbol.
- */
- def companionInstance(clazz: Symbol): AnyRef
-
- /** The Scala class symbol corresponding to the runtime class of the given instance.
- * @param instance The instance
- * @return The class Symbol for the instance
- * @throws ?
- */
- def symbolOfInstance(instance: Any): Symbol
-
- /** The Scala type corresponding to the runtime type of given instance.
- * If the underlying class is parameterized, this will be an existential type,
- * with unknown type arguments.
- *
- * @param instance The instance.
- * @return The Type of the given instance.
- * @throws ?
- */
- def typeOfInstance(instance: Any): Type
-
- /** The value of a field on a receiver instance.
- * @param receiver The receiver instance
- * @param field The field
- * @return The value contained in `receiver.field`.
- */
- def getValueOfField(receiver: AnyRef, field: Symbol): Any
-
- /** Sets the value of a field on a receiver instance.
- * @param receiver The receiver instance
- * @param field The field
- * @param value The new value to be stored in the field.
- */
- def setValueOfField(receiver: AnyRef, field: Symbol, value: Any): Unit
-
- /** Invokes a method on a receiver instance with some arguments
- * @param receiver The receiver instance
- * @param meth The method
- * @param args The method call's arguments
- * @return The result of invoking `receiver.meth(args)`
- */
- def invoke(receiver: AnyRef, meth: Symbol)(args: Any*): Any
-
- /** Maps a Java class to a Scala type reference
- * @param clazz The Java class object
- * @return A type (of kind `TypeRef`, or `ExistentialType` if `clazz` is polymorphic)
- * that represents the class with all type parameters unknown
- * (i.e. any type parameters of `clazz` are existentially quantified).
- * */
- def classToType(clazz: java.lang.Class[_]): Type
-
- /** Maps a Java class to a Scala class symbol
- * @param clazz The Java class object
- * @return A symbol that represents the Scala view of the class.
- */
- def classToSymbol(clazz: java.lang.Class[_]): Symbol
-
- /** Maps a Scala type to the corresponding Java class object
- */
- def typeToClass(tpe: Type): java.lang.Class[_]
-
- /** Maps a Scala symbol to the corresponding Java class object
- * @throws ClassNotFoundException if there is no Java class
- * corresponding to the given Scala symbol.
- * Note: If the Scala symbol is ArrayClass, a ClassNotFound exception is thrown
- * because there is no unique Java class corresponding to a Scala generic array
- */
- def symbolToClass(sym: Symbol): java.lang.Class[_]
-}
diff --git a/src/library/scala/reflect/api/Mirrors.scala b/src/library/scala/reflect/api/Mirrors.scala
new file mode 100644
index 0000000000..2fcee8f227
--- /dev/null
+++ b/src/library/scala/reflect/api/Mirrors.scala
@@ -0,0 +1,213 @@
+package scala.reflect
+package api
+
+trait Mirrors { self: Universe =>
+
+ type RuntimeClass >: Null
+
+ // [Eugene++ to Martin] how do we reflect against inner classes?
+ // presumably, we should add `reflectClass` to both InstanceMirror (inner classes) and TemplateMirror (nested classes)
+ // in the former case, the resulting ClassMirror should remember the outer instance that spawned it to use it in reflective construction
+
+ // [Eugene] also, it might make sense to provide shortcuts for the API
+ //
+ // for example, right now to invoke the same method for several different instances, you need:
+ // 1) get the method symbol
+ // 2) get the instance mirror for every instance
+ // 3) call reflectMethod on the instance mirrors for every instance
+ // 4) call apply for every instance (okay, this can be united with step #3, but still)
+ //
+ // I have several suggestions that we can discuss later:
+ // 1) For every `reflectXXX(sym: Symbol): XXXMirror`, add `reflectXXX(name: String, types: Type*): XXXMirror` and `reflectXXXs(): List[XXXMirror]`
+ // 2) Provide a way to skip obtaining InstanceMirror (step #2 in the outline provided above)
+
+ // [Eugene] another improvement would be have mirrors reproduce the structure of the reflection domain
+ // e.g. a ClassMirror could also have a list of fields, methods, constructors and so on
+ // read up more on the proposed design in "Reflecting Scala" by Y. Coppel
+
+ /** A mirror that reflects a runtime value */
+ trait InstanceMirror {
+
+ /** The instance value reflected by this mirror */
+ def instance: Any
+
+ /** The mirror corresponding to the run-time class of the reflected instance. */
+ def reflectClass: ClassMirror
+
+ /** Get value of field in reflected instance.
+ * @field A field symbol that should represent a field of the instance class.
+ * @return The value associated with that field in the reflected instance
+ * @throws ???
+ */
+ def reflectField(field: TermSymbol): FieldMirror
+
+ /** Invokes a method on the reflected instance.
+ * @param meth A method symbol that should represent a method of the instance class
+ * @param args The arguments to pass to the method
+ * @return The result of invoking `meth(args)` on the reflected instance.
+ * @throws ???
+ */
+ def reflectMethod(method: MethodSymbol): MethodMirror
+ }
+
+ /** A mirror that reflects a field */
+ trait FieldMirror {
+
+ /** The object containing the field */
+ def receiver: AnyRef
+
+ /** The field symbol representing the field */
+ def field: TermSymbol
+
+ /** Retrieves the value stored in the field */
+ def get: Any
+
+ /** Updates the value stored in the field */
+ def set(value: Any): Unit
+ }
+
+ /** A mirror that reflects a method handle */
+ trait MethodMirror {
+
+ /** The receiver object of the method */
+ def receiver: AnyRef
+
+ /** The method symbol representing the method */
+ def method: MethodSymbol
+
+ /** The result of applying the method to the given arguments */
+ def apply(args: Any*): Any
+ }
+
+ /** A mirror that reflects the instance or static parts of a runtime class */
+ trait TemplateMirror {
+
+ /** The runtime class reflected by this mirror */
+ def runtimeClass: RuntimeClass
+
+ /** True if the mirror represents the static part
+ * if a runtime class or the companion object of a Scala class.
+ * One has:
+ *
+ * this.isStatic == this.isInstanceOf[ModuleMirror]
+ * !this.isStatic == this.isInstanceOf[ClassMirror]
+ */
+ def isStatic: Boolean
+
+ /** The Scala symbol corresponding to the reflected runtime class or module. */
+ def symbol: Symbol
+
+ // [Eugene++ to Martin] I've removed `typeSignature`, because we can obtain it via `symbol.typeSignature`
+
+ /** Optionally, the mirror of the companion reflected by this mirror.
+ * If this mirror reflects a Scala object, the mirror for the companion class, or None
+ * if the mirror represents a Scala object that comes without a class.
+ * Otherwise, if the mirror represents the static part of a runtime class, the
+ * mirror representing the instance part of the same class.
+ * Otherwise, if the mirror represents a Scala instance class, the mirror for the companion
+ * object of that class, or None if no such object exists.
+ * Otherwise, if the mirror represents a runtime instance class, a mirror representing the static
+ * part of the same class.
+ */
+ def companion: Option[TemplateMirror]
+ }
+
+ /** A mirror that reflects a Scala object definition or the static parts of a runtime class */
+ trait ModuleMirror extends TemplateMirror {
+
+ /** The Scala module symbol corresponding to the reflected module. */
+ override def symbol: ModuleSymbol
+
+ /** If the reflected runtime class corresponds to a Scala object definition,
+ * returns the single instance representing that object.
+ * If this mirror reflects the static part of a runtime class, returns `null`.
+ */
+ def instance: Any
+
+ /** Optionally, the mirror of the companion class if the object reflected by this mirror.
+ * If this mirror reflects a Scala object, the mirror for the companion class, or None
+ * if the mirror represents a Scala object that comes without a class.
+ * Otherwise, if the mirror represents the static part of a runtime class, the
+ * mirror representing the instance part of the same class.
+ */
+ def companion: Option[ClassMirror]
+ }
+
+ /** A mirror that reflects the instance parts of a runtime class */
+ trait ClassMirror extends TemplateMirror {
+
+ /** The Scala class symbol corresponding to the reflected class. */
+ override def symbol: ClassSymbol
+
+ /** Returns a fresh instance of by invoking that constructor.
+ * @throws InstantiationException if the class does not have a public
+ * constructor with an empty parameter list.
+ * @throws IllegalAccessException if the class or its constructor is not accessible.
+ * @throws ExceptionInInitializerError if the initialization of the constructor fails.
+ * @throws SecurityException if creating a new instance is not permitted.
+ */
+ def reflectConstructor(constructor: MethodSymbol): MethodMirror
+
+ /** Optionally, the mirror of the companion object of the class reflected by this mirror.
+ * If this mirror represents a Scala instance class, the mirror for the companion
+ * object of that class, or None if no such object exists.
+ * Otherwise, if the mirror represents a runtime instance class, a mirror representing the static
+ * part of the same class.
+ */
+ def companion: Option[ModuleMirror]
+ }
+
+ /** The API of a mirror for a reflective universe */
+ trait RuntimeMirror extends MirrorOf[Mirrors.this.type] { self =>
+
+ /** A reflective mirror for the given object
+ * @param obj An arbitrary value
+ * @return The mirror for `obj`.
+ */
+ def reflect(obj: Any): InstanceMirror
+
+ /** A reflective mirror for the given Runtime class
+ * @param runtimeClass A Runtime class object
+ * @return The mirror for `runtimeClass`
+ */
+ def reflectClass(runtimeClass: RuntimeClass): ClassMirror
+
+ /** A reflective mirror for the Runtime class with the given name in the
+ * current classloader.
+ * @param name The fully qualified name of the class
+ * @return The mirror for the runtime class with fully qualified name
+ * `name` in the current class loader.
+ * @throws java.lang.ClassNotFoundException if no class with that name exists
+ * to do: throws anything else?
+ */
+ def reflectClass(fullName: String): ClassMirror
+
+ /** A reflective mirror for the given Runtime class
+ * @param runtimeClass A Runtime class object
+ * @return The mirror for `runtimeClass`
+ */
+ def reflectModule(runtimeClass: RuntimeClass): ModuleMirror
+
+ /** A reflective mirror for the Runtime class with the given name in the
+ * current classloader.
+ * @param name The fully qualified name of the class
+ * @return The mirror for the runtime class with fully qualified name
+ * `name` in the current class loader.
+ * @throws java.lang.ClassNotFoundException if no class with that name exists
+ * to do: throws anything else?
+ */
+ def reflectModule(fullName: String): ModuleMirror
+
+ /** Maps a Scala type to the corresponding Java class object
+ */
+ def runtimeClass(tpe: Type): RuntimeClass
+
+ /** Maps a Scala class symbol to the corresponding Java class object
+ * @throws ClassNotFoundException if there is no Java class
+ * corresponding to the given Scala class symbol.
+ * Note: If the Scala symbol is ArrayClass, a ClassNotFound exception is thrown
+ * because there is no unique Java class corresponding to a Scala generic array
+ */
+ def runtimeClass(cls: ClassSymbol): RuntimeClass
+ }
+}
diff --git a/src/library/scala/reflect/api/Modifier.scala b/src/library/scala/reflect/api/Modifier.scala
deleted file mode 100644
index 1b67929e15..0000000000
--- a/src/library/scala/reflect/api/Modifier.scala
+++ /dev/null
@@ -1,82 +0,0 @@
-package scala.reflect.api
-
-import collection.{ immutable, mutable }
-
-abstract class Modifier private[api] () {
- def name: String
- def isKeyword: Boolean
- def sourceString: String = if (isKeyword) "`" + name + "`" else name
-
- override def equals(that: Any) = this eq that.asInstanceOf[AnyRef]
- override def hashCode = name.hashCode
- override def toString = name
-}
-final class SymbolModifier private (val name: String, val isKeyword: Boolean) extends Modifier {
- def this(name: String) = this(name, false)
-}
-final class SourceModifier private (val name: String) extends Modifier {
- def isKeyword = true
-}
-
-object SymbolModifier {
- private val seen = mutable.ListBuffer[SymbolModifier]()
- private[api] def apply(name: String): SymbolModifier = {
- val mod = name match {
- case "case" | "trait" => new SymbolModifier(name, isKeyword = true)
- case _ => new SymbolModifier(name)
- }
- seen += mod
- mod
- }
- private[api] def all = seen.toList
-}
-object SourceModifier {
- private val seen = mutable.ListBuffer[SourceModifier]()
- private[api] def apply(name: String): SourceModifier = {
- val mod = new SourceModifier(name)
- seen += mod
- mod
- }
- private[api] def all = seen.toList
-}
-
-object Modifier extends immutable.Set[Modifier] {
- val `abstract` = SourceModifier("abstract")
- val `final` = SourceModifier("final")
- val `implicit` = SourceModifier("implicit")
- val `lazy` = SourceModifier("lazy")
- val `macro` = SourceModifier("macro")
- val `override` = SourceModifier("override")
- val `private` = SourceModifier("private")
- val `protected` = SourceModifier("protected")
- val `sealed` = SourceModifier("sealed")
-
- val `case` = SymbolModifier("case")
- val `trait` = SymbolModifier("trait")
- val abstractOverride = SymbolModifier("abstractOverride")
- val bynameParameter = SymbolModifier("bynameParameter")
- val caseAccessor = SymbolModifier("caseAccessor")
- val contravariant = SymbolModifier("contravariant")
- val covariant = SymbolModifier("covariant")
- val defaultInit = SymbolModifier("defaultInit")
- val defaultParameter = SymbolModifier("defaultParameter")
- val deferred = SymbolModifier("deferred")
- val interface = SymbolModifier("interface")
- val java = SymbolModifier("java")
- val local = SymbolModifier("local")
- val mutable = SymbolModifier("mutable")
- val paramAccessor = SymbolModifier("paramAccessor")
- val parameter = SymbolModifier("parameter")
- val preSuper = SymbolModifier("preSuper")
- val static = SymbolModifier("static")
-
- val sourceModifiers: Set[SourceModifier] = SourceModifier.all.toSet
- val symbolModifiers: Set[SymbolModifier] = SymbolModifier.all.toSet
- val allModifiers: Set[Modifier] = sourceModifiers ++ symbolModifiers
- def values = allModifiers
-
- def contains(key: Modifier) = allModifiers(key)
- def iterator = allModifiers.iterator
- def -(elem: Modifier) = allModifiers - elem
- def +(elem: Modifier) = allModifiers + elem
-}
diff --git a/src/library/scala/reflect/api/Names.scala b/src/library/scala/reflect/api/Names.scala
index 96651ffa88..222ee5024b 100755
--- a/src/library/scala/reflect/api/Names.scala
+++ b/src/library/scala/reflect/api/Names.scala
@@ -10,28 +10,18 @@ package api
* Names are interned. That is, for two names `name11 and `name2`,
* `name1 == name2` implies `name1 eq name2`.
*/
-trait Names {
- /** The abstract type of names */
- type Name >: Null <: AbsName
-
- /** The abstract type of names representing terms */
- type TypeName <: Name
-
- /** The abstract type of names representing types */
- type TermName <: Name
+trait Names extends base.Names {
- abstract class AbsName {
- /** Is this name a term name? */
- def isTermName: Boolean
-
- /** Is this name a type name? */
- def isTypeName: Boolean
+ /** The abstract type of names */
+ type Name >: Null <: NameApi
- /** Returns a term name that represents the same string as this name */
- def toTermName: TermName
+ /** The extended API of names that's supported on reflect mirror via an
+ * implicit conversion in reflect.ops
+ */
+ abstract class NameApi extends NameBase {
- /** Returns a type name that represents the same string as this name */
- def toTypeName: TypeName
+ // [Eugene++] this functionality should be in base
+ // this is because stuff will be reified in mangled state, and people will need a way to figure it out
/** Replaces all occurrences of \$op_names in this name by corresponding operator symbols.
* Example: `foo_\$plus\$eq` becomes `foo_+=`
@@ -51,16 +41,4 @@ trait Names {
*/
def encodedName: Name
}
-
- /** Create a new term name.
- */
- def newTermName(s: String): TermName
-
- /** Creates a new type name.
- */
- def newTypeName(s: String): TypeName
-
- def EmptyTermName: TermName = newTermName("")
-
- def EmptyTypeName: TypeName = EmptyTermName.toTypeName
}
diff --git a/src/library/scala/reflect/api/Positions.scala b/src/library/scala/reflect/api/Positions.scala
index 8f01e0ced1..9d3d90d9f8 100644
--- a/src/library/scala/reflect/api/Positions.scala
+++ b/src/library/scala/reflect/api/Positions.scala
@@ -1,16 +1,11 @@
package scala.reflect
package api
-trait Positions {
+trait Positions extends base.Positions {
self: Universe =>
- // [Eugene] in quite a lot of situations (mostly related to error reporting) we need positions in the API
- // however it seems that neither runtime compilation, nor macros need facilities to create positions from scratch
- // both emit ASTs, which can be automatically transformed into synthetic sources and assigned with synthetic positions
- // hence I added possibilities to inspect everything we can, but add any position factories
- // this simplified a lot of things, the biggest of them is that we don't need to expose SourceFile/AbstractFile
- type Position <: scala.reflect.api.Position
- val NoPosition: Position
+ /** .. */
+ type Position >: Null <: PositionApi { type Pos = Position }
/** A position that wraps a set of trees.
* The point of the wrapping position is the point of the default position.
@@ -31,11 +26,8 @@ trait Positions {
* shortening the range or assigning TransparentPositions
* to some of the nodes in `tree`.
*/
- def ensureNonOverlapping(tree: Tree, others: List[Tree])
-
- /** Assigns a given position to all position-less nodes of a given AST.
- */
- def atPos[T <: Tree](pos: Position)(tree: T): T
+ //def ensureNonOverlapping(tree: Tree, others: List[Tree])
+ // [Eugene++] can this method be of use for macros?
}
/** The Position class and its subclasses represent positions of ASTs and symbols.
@@ -82,7 +74,9 @@ trait Positions {
* pos.makeTransparent converts an opaque range position into a transparent one.
* returns all other positions unchanged.
*/
-trait Position extends Attachment {
+trait PositionApi extends Attachments {
+
+ type Pos >: Null <: PositionApi
/** Java file corresponding to the source file of this position.
*/
@@ -97,17 +91,17 @@ trait Position extends Attachment {
*/
def isDefined: Boolean
- /** Is this position a transparent position? */
- def isTransparent: Boolean
-
/** Is this position a range position? */
def isRange: Boolean
+ /** Is this position a transparent position? */
+ def isTransparent: Boolean
+
/** Is this position a non-transparent range position? */
def isOpaqueRange: Boolean
/** if opaque range, make this position transparent */
- def makeTransparent: Position
+ def makeTransparent: Pos
/** The start of the position's range, error if not a range position */
def start: Int
@@ -128,73 +122,73 @@ trait Position extends Attachment {
def endOrPoint: Int
/** The same position with a different start value (if a range) */
- def withStart(off: Int): Position
+ def withStart(off: Int): Pos
/** The same position with a different end value (if a range) */
- def withEnd(off: Int): Position
+ def withEnd(off: Int): Pos
/** The same position with a different point value (if a range or offset) */
- def withPoint(off: Int): Position
+ def withPoint(off: Int): Pos
/** If this is a range, the union with the other range, with the point of this position.
* Otherwise, this position
*/
- def union(pos: Position): Position
+ def union(pos: Pos): Pos
- /** If this is a range position, the offset position of its start.
+ /** If this is a range position, the offset position of its point.
* Otherwise the position itself
*/
- def focusStart: Position
+ def focus: Pos
- /** If this is a range position, the offset position of its point.
+ /** If this is a range position, the offset position of its start.
* Otherwise the position itself
*/
- def focus: Position
+ def focusStart: Pos
/** If this is a range position, the offset position of its end.
* Otherwise the position itself
*/
- def focusEnd: Position
+ def focusEnd: Pos
/** Does this position include the given position `pos`.
* 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: Position): Boolean
+ def includes(pos: Pos): Boolean
/** Does this position properly include the given position `pos` ("properly" meaning their
* ranges are not the same)?
*/
- def properlyIncludes(pos: Position): Boolean
+ def properlyIncludes(pos: Pos): Boolean
/** 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: Position): Boolean
+ def precedes(pos: Pos): Boolean
/** Does this position properly precede the given position `pos` ("properly" meaning their ranges
* do not share a common point).
*/
- def properlyPrecedes(pos: Position): Boolean
+ def properlyPrecedes(pos: Pos): Boolean
/** 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: Position): Boolean
+ def overlaps(pos: Pos): Boolean
/** Does this position cover the same range as that position?
* Holds only if both position are ranges
*/
- def sameRange(pos: Position): Boolean
+ def sameRange(pos: Pos): Boolean
def line: Int
def column: Int
/** Convert this to a position around `point` that spans a single source line */
- def toSingleLine: Position
+ def toSingleLine: Pos
def lineContent: String
diff --git a/src/library/scala/reflect/api/StandardDefinitions.scala b/src/library/scala/reflect/api/StandardDefinitions.scala
index 21f7c9283b..c2a89f92dd 100755
--- a/src/library/scala/reflect/api/StandardDefinitions.scala
+++ b/src/library/scala/reflect/api/StandardDefinitions.scala
@@ -2,144 +2,47 @@
* Copyright 2005-2011 LAMP/EPFL
* @author Martin Odersky
*/
-
package scala.reflect
package api
-trait StandardTypes {
- self: Universe =>
-
- val ByteTpe: Type
- val ShortTpe: Type
- val CharTpe: Type
- val IntTpe: Type
- val LongTpe: Type
- val FloatTpe: Type
- val DoubleTpe: Type
- val BooleanTpe: Type
- val UnitTpe: Type
-
- val AnyTpe: Type
- val AnyValTpe: Type
- val AnyRefTpe: Type
- val ObjectTpe: Type
-
- val NothingTpe: Type
- val NullTpe: Type
- val StringTpe: Type
-}
-
-trait StandardDefinitions extends StandardTypes {
+trait StandardDefinitions extends base.StandardDefinitions {
self: Universe =>
- val definitions: AbsDefinitions
-
- // I intend to pull everything in here out of the public API.
- trait AbsDefinitionsInternal {
- def ArrayModule: Symbol
- def ArrayModule_overloadedApply: Symbol
- def Array_apply: Symbol
- def Array_clone: Symbol
- def Array_length: Symbol
- def Array_update: Symbol
- def ByNameParamClass: Symbol
- def ClassTagModule: Symbol
- def ConcreteTypeTagModule: Symbol
- def ConsClass: Symbol
- def EmptyPackageClass: Symbol
- def FunctionClass : Array[Symbol]
- def IterableClass: Symbol
- def IteratorClass: Symbol
- def IteratorModule: Symbol
- def Iterator_apply: Symbol
- def JavaLangPackageClass: Symbol
- def JavaRepeatedParamClass: Symbol
- def ListModule: Symbol
- def List_apply: Symbol
- def NilModule: Symbol
- def NoneModule: Symbol
- def OptionClass: Symbol
- def ProductClass : Array[Symbol]
- def RepeatedParamClass: Symbol
- def ScalaPackageClass: Symbol
- def SeqClass: Symbol
- def SeqModule: Symbol
- def SomeClass: Symbol
- def SomeModule: Symbol
- def StringBuilderClass: Symbol
- def SymbolClass : Symbol
- def TraversableClass: Symbol
- def TupleClass : Array[Symbol]
- def TypeTagModule: Symbol
- def ScalaPrimitiveValueClasses: List[ClassSymbol]
- }
-
- trait AbsDefinitions extends AbsDefinitionsInternal {
- // packages
- def RootClass: ClassSymbol
- def RootPackage: PackageSymbol
- def EmptyPackage: PackageSymbol
- def ScalaPackage: PackageSymbol
- def JavaLangPackage: PackageSymbol
-
- // top types
- def AnyClass : ClassSymbol
- def AnyValClass: ClassSymbol
- def ObjectClass: ClassSymbol
- def AnyRefClass: TypeSymbol
-
- // bottom types
- def NullClass : ClassSymbol
- def NothingClass: ClassSymbol
-
- // the scala value classes
- def UnitClass : ClassSymbol
- def ByteClass : ClassSymbol
- def ShortClass : ClassSymbol
- def CharClass : ClassSymbol
- def IntClass : ClassSymbol
- def LongClass : ClassSymbol
- def FloatClass : ClassSymbol
- def DoubleClass : ClassSymbol
- def BooleanClass: ClassSymbol
-
- // some special classes
- def StringClass : ClassSymbol
- def ClassClass : ClassSymbol
- def ArrayClass: ClassSymbol
-
- // collections classes
- def ListClass: ClassSymbol
+ val definitions: DefinitionsApi
+
+ trait DefinitionsApi extends DefinitionsBase {
+ def JavaLangPackageClass: ClassSymbol
+ def JavaLangPackage: ModuleSymbol
+ def ArrayModule: ModuleSymbol
+ def ArrayModule_overloadedApply: TermSymbol // todo. fix the bug in Definitions.getMemberMethod
+ def Array_apply: TermSymbol // todo. fix the bug in Definitions.getMemberMethod
+ def Array_clone: TermSymbol // todo. fix the bug in Definitions.getMemberMethod
+ def Array_length: TermSymbol // todo. fix the bug in Definitions.getMemberMethod
+ def Array_update: TermSymbol // todo. fix the bug in Definitions.getMemberMethod
+ def ByNameParamClass: ClassSymbol
+ def ConsClass: ClassSymbol
+ def FunctionClass : Array[ClassSymbol]
+ def IterableClass: ClassSymbol
+ def IteratorClass: ClassSymbol
+ def IteratorModule: ModuleSymbol
+ def Iterator_apply: TermSymbol // todo. fix the bug in Definitions.getMemberMethod
+ def JavaRepeatedParamClass: ClassSymbol
def ListModule: ModuleSymbol
-
- // collections modules
- def PredefModule: ModuleSymbol
-
- // type tags
- def ClassTagClass: ClassSymbol
- def TypeTagClass: ClassSymbol
- def ConcreteTypeTagClass: ClassSymbol
-
- /** Given a type T, returns the type corresponding to the VM's
- * representation: ClassClass's type constructor applied to `arg`.
- */
- def vmClassType(arg: Type): Type // !!! better name?
- // [Eugene] we already have arg.erasure, right?
- //
- // [Paul] You misunderstand the method (it could be better named).
- // Given List[String], it returns java.lang.Class[List[String]]
- // (or the .Net equivalent), not the erasure of List[String].
- // See def ClassType in definitions - that's what it was called before,
- // and obviously that name has to go.
-
- /** The string representation used by the given type in the VM.
- */
- def vmSignature(sym: Symbol, info: Type): String
-
- /** Is symbol one of the value classes? */
- def isPrimitiveValueClass(sym: Symbol): Boolean // !!! better name?
-
- /** Is symbol one of the numeric value classes? */
- def isNumericValueClass(sym: Symbol): Boolean // !!! better name?
+ def List_apply: TermSymbol // todo. fix the bug in Definitions.getMemberMethod
+ def NilModule: ModuleSymbol
+ def NoneModule: ModuleSymbol
+ def OptionClass: ClassSymbol
+ def ProductClass : Array[ClassSymbol]
+ def RepeatedParamClass: ClassSymbol
+ def SeqClass: ClassSymbol
+ def SeqModule: ModuleSymbol
+ def SomeClass: ClassSymbol
+ def SomeModule: ModuleSymbol
+ def StringBuilderClass: ClassSymbol
+ def SymbolClass : ClassSymbol
+ def TraversableClass: ClassSymbol
+ def TupleClass: Array[Symbol] // cannot make it Array[ClassSymbol], because TupleClass(0) is supposed to be NoSymbol. weird
+ def ScalaPrimitiveValueClasses: List[ClassSymbol]
+ def ScalaNumericValueClasses: List[ClassSymbol]
}
}
diff --git a/src/library/scala/reflect/api/StandardNames.scala b/src/library/scala/reflect/api/StandardNames.scala
index a17ea216f7..80aed04073 100644
--- a/src/library/scala/reflect/api/StandardNames.scala
+++ b/src/library/scala/reflect/api/StandardNames.scala
@@ -2,36 +2,30 @@
* Copyright 2005-2011 LAMP/EPFL
* @author Martin Odersky
*/
-
package scala.reflect
package api
-trait StandardNames {
+trait StandardNames extends base.StandardNames {
self: Universe =>
- val nme: AbsTermNames
- val tpnme: AbsTypeNames
-
- trait AbsNames {
- type NameType <: Name
+ val nme: TermNamesApi
+ val tpnme: TypeNamesApi
+ trait NamesApi extends NamesBase {
val ANON_CLASS_NAME: NameType
val ANON_FUN_NAME: NameType
val EMPTY: NameType
- val EMPTY_PACKAGE_NAME: NameType
val ERROR: NameType
val IMPORT: NameType
val MODULE_VAR_SUFFIX: NameType
- val NO_NAME: NameType
val PACKAGE: NameType
val ROOT: NameType
val SPECIALIZED_SUFFIX: NameType
- val WILDCARD: NameType
def flattenedName(segments: Name*): NameType
}
- trait AbsTermNames extends AbsNames {
+ trait TermNamesApi extends NamesApi with TermNamesBase {
val EXPAND_SEPARATOR_STRING: String
val IMPL_CLASS_SUFFIX: String
val INTERPRETER_IMPORT_WRAPPER: String
@@ -50,16 +44,15 @@ trait StandardNames {
val TRAIT_SETTER_SEPARATOR_STRING: String
val ANYNAME: TermName
- val CONSTRUCTOR: TermName
val FAKE_LOCAL_THIS: TermName
val INITIALIZER: TermName
val LAZY_LOCAL: TermName
- val MIRROR_FREE_PREFIX: TermName
- val MIRROR_FREE_THIS_SUFFIX: TermName
- val MIRROR_FREE_VALUE_SUFFIX: TermName
- val MIRROR_PREFIX: TermName
- val MIRROR_SHORT: TermName
- val MIRROR_SYMDEF_PREFIX: TermName
+ val MIRROR_FREE_PREFIX: NameType
+ val MIRROR_FREE_THIS_SUFFIX: NameType
+ val MIRROR_FREE_VALUE_SUFFIX: NameType
+ val MIRROR_PREFIX: NameType
+ val MIRROR_SHORT: NameType
+ val MIRROR_SYMDEF_PREFIX: NameType
val MIXIN_CONSTRUCTOR: TermName
val MODULE_INSTANCE_FIELD: TermName
val OUTER: TermName
@@ -146,7 +139,7 @@ trait StandardNames {
def splitSpecializedName(name: Name): (Name, String, String)
}
- trait AbsTypeNames extends AbsNames {
+ trait TypeNamesApi extends NamesApi with TypeNamesBase {
val BYNAME_PARAM_CLASS_NAME: TypeName
val EQUALS_PATTERN_NAME: TypeName
val JAVA_REPEATED_PARAM_CLASS_NAME: TypeName
diff --git a/src/library/scala/reflect/api/Symbols.scala b/src/library/scala/reflect/api/Symbols.scala
index 32faee2512..1d266dc778 100755
--- a/src/library/scala/reflect/api/Symbols.scala
+++ b/src/library/scala/reflect/api/Symbols.scala
@@ -1,149 +1,55 @@
package scala.reflect
package api
-trait Symbols { self: Universe =>
-
- type Symbol >: Null <: AbsSymbol
- type TypeSymbol <: Symbol with TypeSymbolApi
- type TermSymbol <: Symbol with TermSymbolApi
- type MethodSymbol <: TermSymbol with MethodSymbolApi
- type ModuleSymbol <: TermSymbol with ModuleSymbolApi
- type PackageSymbol <: ModuleSymbol with PackageSymbolApi
- type ClassSymbol <: TypeSymbol with ClassSymbolApi
-
- val NoSymbol: Symbol
-
- trait TypeSymbolApi {
- self: TypeSymbol =>
-
- def name: TypeName
- }
- trait TermSymbolApi {
- self: TermSymbol =>
-
- def name: TermName
- }
- trait MethodSymbolApi extends TermSymbolApi {
- self: MethodSymbol =>
- }
- trait ClassSymbolApi extends TypeSymbolApi {
- self: ClassSymbol =>
- }
- trait ModuleSymbolApi extends TermSymbolApi {
- self: ModuleSymbol =>
- }
- trait PackageSymbolApi extends ModuleSymbolApi {
- self: PackageSymbol =>
- }
-
- // I intend to pull everything in here out of the public API.
- trait AbsSymbolInternal {
- this: Symbol =>
-
- /** A fresh symbol with given name `name`, position `pos` and flags `flags` that has
- * the current symbol as its owner.
- */
- def newNestedSymbol(name: Name, pos: Position, flags: Long, isClass: Boolean): Symbol
- // needed by LiftCode !!! not enough reason to have in the api
-
- /** Low-level operation to set the symbol's flags
- * @return the symbol itself
- */
- def setInternalFlags(flags: Long): this.type
- // needed by LiftCode !!! not enough reason to have in the api
-
- /** Set symbol's type signature to given type
- * @return the symbol itself
- */
- def setTypeSignature(tpe: Type): this.type
- // needed by LiftCode !!! not enough reason to have in the api
-
- /** Set symbol's annotations to given annotations `annots`.
- */
- def setAnnotations(annots: AnnotationInfo*): this.type
- // needed by LiftCode !!! not enough reason to have in the api
-
- /** Does this symbol represent the definition of a skolem?
- * Skolems are used during typechecking to represent type parameters viewed from inside their scopes.
- * If yes, `isType` is also guaranteed to be true.
- */
- def isSkolem : Boolean
-
- /** Does this symbol represent a free type captured by reification?
- */
- // needed for ones who wish to inspect reified trees
- def isFreeType : Boolean
-
- /** The type signature of this symbol.
- * Note if the symbol is a member of a class, one almost always is interested
- * in `typeSignatureIn` with a site type instead.
- */
- def typeSignature: Type // !!! Since one should almost never use this, let's give it a different name.
-
- /** A type reference that refers to this type symbol
- * Note if symbol is a member of a class, one almost always is interested
- * in `asTypeIn` with a site type instead.
- *
- * Example: Given a class declaration `class C[T] { ... } `, that generates a symbol
- * `C`. Then `C.asType` is the type `C[T]`.
- *
- * By contrast, `C.typeSignature` would be a type signature of form
- * `PolyType(ClassInfoType(...))` that describes type parameters, value
- * parameters, parent types, and members of `C`.
- */
- def asType: Type // !!! Same as typeSignature.
-
- /** The kind of this symbol; used for debugging */
- def kind: String
+trait Symbols extends base.Symbols { self: Universe =>
+
+ override type Symbol >: Null <: SymbolApi
+ override type TypeSymbol >: Null <: Symbol with TypeSymbolApi
+ override type TermSymbol >: Null <: Symbol with TermSymbolApi
+ override type MethodSymbol >: Null <: TermSymbol with MethodSymbolApi
+ override type ModuleSymbol >: Null <: TermSymbol with ModuleSymbolApi
+ override type ClassSymbol >: Null <: TypeSymbol with ClassSymbolApi
+ override type FreeTermSymbol >: Null <: TermSymbol with FreeTermSymbolApi
+ override type FreeTypeSymbol >: Null <: TypeSymbol with FreeTypeSymbolApi
+
+ trait HasFlagsApi {
+ def flags: FlagSet
+ def hasFlag(fs: FlagSet): Boolean
+ def hasAllFlags(fs: FlagSet): Boolean
+ def flagString: String
}
- trait AbsSymbol extends AbsSymbolInternal {
- this: Symbol =>
+ /** The API of symbols */
+ trait SymbolApi extends SymbolBase with HasFlagsApi { this: Symbol =>
/** The position of this symbol
*/
def pos: Position
- /** The modifiers of this symbol
- */
- def modifiers: Set[Modifier]
-
- /** Does this symbol have given modifier?
- */
- def hasModifier(mod: Modifier): Boolean
-
/** A list of annotations attached to this Symbol.
*/
- def annotations: List[self.AnnotationInfo]
+ // [Eugene++] we cannot expose the `annotations` method because it doesn't auto-initialize a symbol (see SI-5423)
+ // there was an idea to use the `isCompilerUniverse` flag and auto-initialize symbols in `annotations` whenever this flag is false
+ // but it doesn't work, because the unpickler (that is shared between reflective universes and global universes) is very picky about initialization
+ // scala.reflect.internal.Types$TypeError: bad reference while unpickling scala.collection.immutable.Nil: type Nothing not found in scala.type not found.
+ // at scala.reflect.internal.pickling.UnPickler$Scan.toTypeError(UnPickler.scala:836)
+ // at scala.reflect.internal.pickling.UnPickler$Scan$LazyTypeRef.complete(UnPickler.scala:849) // auto-initialize goes boom
+ // at scala.reflect.internal.Symbols$Symbol.info(Symbols.scala:1140)
+ // at scala.reflect.internal.Symbols$Symbol.initialize(Symbols.scala:1272) // this triggers auto-initialize
+ // at scala.reflect.internal.Symbols$Symbol.annotations(Symbols.scala:1438) // unpickler first tries to get pre-existing annotations
+ // at scala.reflect.internal.Symbols$Symbol.addAnnotation(Symbols.scala:1458) // unpickler tries to add the annotation being read
+ // at scala.reflect.internal.pickling.UnPickler$Scan.readSymbolAnnotation(UnPickler.scala:489) // unpickler detects an annotation
+ // at scala.reflect.internal.pickling.UnPickler$Scan.run(UnPickler.scala:88)
+ // at scala.reflect.internal.pickling.UnPickler.unpickle(UnPickler.scala:37)
+ // at scala.reflect.runtime.JavaMirrors$JavaMirror.unpickleClass(JavaMirrors.scala:253) // unpickle from within a reflexive mirror
+ // def annotations: List[AnnotationInfo]
+ def getAnnotations: List[AnnotationInfo]
/** Whether this symbol carries an annotation for which the given
* symbol is its typeSymbol.
*/
def hasAnnotation(sym: Symbol): Boolean
- /** The owner of this symbol. This is the symbol
- * that directly contains the current symbol's definition.
- * The `NoSymbol` symbol does not have an owner, and calling this method
- * on one causes an internal error.
- * The owner of the Scala root class [[scala.reflect.api.mirror.RootClass]]
- * and the Scala root object [[scala.reflect.api.mirror.RootPackage]] is `NoSymbol`.
- * Every other symbol has a chain of owners that ends in
- * [[scala.reflect.api.mirror.RootClass]].
- */
- def owner: Symbol
-
- /** The name of the symbol as a member of the `Name` type.
- */
- def name: Name
-
- /** The encoded full path name of this symbol, where outer names and inner names
- * are separated by periods.
- */
- def fullName: String
-
- /** An id number which is unique for all symbols in this universe */
- def id: Int
-
/** ...
*/
def orElse(alt: => Symbol): Symbol
@@ -152,6 +58,11 @@ trait Symbols { self: Universe =>
*/
def filter(cond: Symbol => Boolean): Symbol
+ /** If this is a NoSymbol, returns NoSymbol, otherwise
+ * returns the result of applying `f` to this symbol.
+ */
+ def map(f: Symbol => Symbol): Symbol
+
/** ...
*/
def suchThat(cond: Symbol => Boolean): Symbol
@@ -189,82 +100,57 @@ trait Symbols { self: Universe =>
*/
def companionSymbol: Symbol
- /** If symbol is an object definition, its implied associated class,
- * otherwise NoSymbol
+ /** If this symbol is a package class, this symbol; otherwise the next enclosing
+ * package class, or `NoSymbol` if none exists.
*/
- def moduleClass: Symbol // needed for LiftCode
+ def enclosingPackageClass: Symbol
/** If this symbol is a top-level class, this symbol; otherwise the next enclosing
* top-level class, or `NoSymbol` if none exists.
*/
def enclosingTopLevelClass: Symbol
- /** If this symbol is a class, this symbol; otherwise the next enclosing
- * class, or `NoSymbol` if none exists.
- */
- def enclosingClass: Symbol
-
- /** If this symbol is a method, this symbol; otherwise the next enclosing
- * method, or `NoSymbol` if none exists.
- */
- def enclosingMethod: Symbol
-
- /** If this symbol is a package class, this symbol; otherwise the next enclosing
- * package class, or `NoSymbol` if none exists.
+ /** Does this symbol represent a value, i.e. not a module and not a method?
+ * If yes, `isTerm` is also guaranteed to be true.
+ * [Eugene++] I need a review of the implementation
*/
- def enclosingPackageClass: Symbol
+ def isValue: Boolean
- /** Does this symbol represent the definition of term?
- * Note that every symbol is either a term or a type.
- * So for every symbol `sym`, either `sym.isTerm` is true
- * or `sym.isType` is true.
+ /** Does this symbol represent a mutable value?
+ * If yes, `isTerm` and `isValue` are also guaranteed to be true.
*/
- def isTerm : Boolean
+ def isVariable: Boolean
- /** Does this symbol represent a package?
+ /** Does this symbol represent the definition of a package?
* If yes, `isTerm` is also guaranteed to be true.
*/
- def isPackage : Boolean
+ def isPackage: Boolean
- /** Does this symbol represent the definition of method?
- * If yes, `isTerm` is also guaranteed to be true.
+ /** Does this symbol represent a package class?
+ * If yes, `isClass` is also guaranteed to be true.
*/
- def isMethod : Boolean
+ def isPackageClass: Boolean
/** Is this symbol an overloaded method?
*/
def isOverloaded : Boolean
- /** Does this symbol represent a free term captured by reification?
- */
- // needed for ones who wish to inspect reified trees
- def isFreeTerm : Boolean
-
- /** Does this symbol represent the definition of type?
- * Note that every symbol is either a term or a type.
- * So for every symbol `sym`, either `sym.isTerm` is true
- * or `sym.isType` is true.
- */
- def isType : Boolean
-
- /** Does this symbol represent the definition of class?
- * If yes, `isType` is also guaranteed to be true.
- */
- def isClass : Boolean
-
- /** Does this symbol represent a package class?
- * If yes, `isClass` is also guaranteed to be true.
- */
- def isPackageClass : Boolean
-
/** Does this symbol represent the definition of a primitive class?
* Namely, is it one of [[scala.Double]], [[scala.Float]], [[scala.Long]], [[scala.Int]], [[scala.Char]],
* [[scala.Short]], [[scala.Byte]], [[scala.Unit]] or [[scala.Boolean]]?
*/
def isPrimitiveValueClass: Boolean
+ /** Does this symbol represent the definition of a numeric value class?
+ * Namely, is it one of [[scala.Double]], [[scala.Float]], [[scala.Long]], [[scala.Int]], [[scala.Char]],
+ * [[scala.Short]], [[scala.Byte]], [[scala.Unit]] or [[scala.Boolean]]?
+ */
+ def isNumericValueClass: Boolean
+
/** Does this symbol represent the definition of a custom value class?
* Namely, is AnyVal among its parent classes?
+ * TODO: Why not just have in reflect.internal?
+ * [Eugene++] because it's useful for macros
*/
def isDerivedValueClass: Boolean
@@ -283,6 +169,38 @@ trait Symbols { self: Universe =>
*/
def isExistential : Boolean
+ /** Does this symbol represent a free type captured by reification?
+ */
+ def isFreeType : Boolean
+
+ /** Does this symbol or its underlying type represent a typechecking error?
+ */
+ def isErroneous : Boolean
+
+ /** The type signature of this symbol seen as a member of given type `site`.
+ */
+ def typeSignatureIn(site: Type): Type
+
+ /** The type signature of this symbol.
+ * Note if the symbol is a member of a class, one almost always is interested
+ * in `typeSignatureIn` with a site type instead.
+ */
+ def typeSignature: Type
+
+ /** The string discriminator of this symbol; useful for debugging */
+ def kind: String
+ }
+
+ /** The API of term symbols */
+ trait TermSymbolApi extends SymbolApi with HasFlagsApi with TermSymbolBase { this: TermSymbol =>
+ /** The overloaded alternatives of this symbol */
+ def alternatives: List[Symbol]
+
+ def resolveOverloaded(pre: Type = NoPrefix, targs: Seq[Type] = List(), actuals: Seq[Type]): Symbol
+ }
+
+ /** The API of type symbols */
+ trait TypeSymbolApi extends SymbolApi with HasFlagsApi with TypeSymbolBase { this: TypeSymbol =>
/** Is the type parameter represented by this symbol contravariant?
*/
def isContravariant : Boolean
@@ -291,40 +209,60 @@ trait Symbols { self: Universe =>
*/
def isCovariant : Boolean
- /** Does this symbol or its underlying type represent a typechecking error?
- */
- def isErroneous : Boolean
-
- /** The type signature of this symbol seen as a member of given type `site`.
+ /** Does this symbol represent the definition of a skolem?
+ * Skolems are used during typechecking to represent type parameters viewed from inside their scopes.
+ * If yes, `isType` is also guaranteed to be true.
*/
- def typeSignatureIn(site: Type): Type
+ def isSkolem : Boolean
/** A type reference that refers to this type symbol seen
* as a member of given type `site`.
*/
def asTypeIn(site: Type): Type
- /** The type constructor corresponding to this type symbol.
- * This is different from `asType` in that type parameters
- * are part of results of `asType`, but not of `asTypeConstructor`.
- *
- * Example: Given a class declaration `class C[T] { ... } `, that generates a symbol
- * `C`. Then `C.asType` is the type `C[T]`, but `C.asTypeConstructor` is `C`.
- */
- def asTypeConstructor: Type // needed by LiftCode
+ /** A type reference that refers to this type symbol
+ * Note if symbol is a member of a class, one almost always is interested
+ * in `asTypeIn` with a site type instead.
+ *
+ * Example: Given a class declaration `class C[T] { ... } `, that generates a symbol
+ * `C`. Then `C.asType` is the type `C[T]`.
+ *
+ * By contrast, `C.typeSignature` would be a type signature of form
+ * `PolyType(ClassInfoType(...))` that describes type parameters, value
+ * parameters, parent types, and members of `C`.
+ */
+ def asType: Type // !!! Same as typeSignature.
+ }
- /** If this symbol is a class, the type `C.this`, otherwise `NoPrefix`.
- */
- def thisPrefix: Type
+ /** The API of method symbols */
+ type MethodSymbolApi = MethodSymbolBase
+ /** The API of module symbols */
+ type ModuleSymbolApi = ModuleSymbolBase
+
+ /** The API of class symbols */
+ trait ClassSymbolApi extends TypeSymbolApi with ClassSymbolBase { this: ClassSymbol =>
/** If this symbol is a class or trait, its self type, otherwise the type
* of the symbol itself.
*/
def selfType: Type
- /** The overloaded alternatives of this symbol */
- def alternatives: List[Symbol]
+ /** The type `C.this`, where `C` is the current class */
+ def thisPrefix: Type
+ }
- def resolveOverloaded(pre: Type = NoPrefix, targs: Seq[Type] = List(), actuals: Seq[Type]): Symbol
+ /** The API of free term symbols */
+ trait FreeTermSymbolApi extends TermSymbolApi with FreeTermSymbolBase { this: FreeTermSymbol =>
+ /** The place where this symbol has been spawned */
+ def origin: String
+
+ /** The valus this symbol refers to */
+ def value: Any
+ }
+
+ /** The API of free term symbols */
+ trait FreeTypeSymbolApi extends TypeSymbolApi with FreeTypeSymbolBase { this: FreeTypeSymbol =>
+ /** The place where this symbol has been spawned */
+ def origin: String
}
}
diff --git a/src/library/scala/reflect/api/ToolBoxes.scala b/src/library/scala/reflect/api/ToolBoxes.scala
deleted file mode 100644
index 15c9fcc403..0000000000
--- a/src/library/scala/reflect/api/ToolBoxes.scala
+++ /dev/null
@@ -1,90 +0,0 @@
-package scala.reflect
-package api
-
-trait ToolBoxes { self: Universe =>
-
- type ToolBox <: AbsToolBox
-
- def mkToolBox(frontEnd: FrontEnd = mkSilentFrontEnd(), options: String = ""): AbsToolBox
-
- // [Eugene] what do you think about the interface? namely about the ``freeTypes'' part.
- trait AbsToolBox {
-
- /** 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 ``FreeType'' 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: Tree, pt: Type = WildcardType, freeTypes: Map[FreeType, Type] = Map[FreeType, Type](), silent: Boolean = false, withImplicitViewsDisabled: Boolean = false, withMacrosDisabled: Boolean = false): 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: Type, silent: Boolean = true, withMacrosDisabled: Boolean = false): 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: Tree, from: Type, to: Type, silent: Boolean = true, withMacrosDisabled: Boolean = false, reportAmbiguous: Boolean = true): 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: Tree): 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: Tree): Tree
-
- /** Compiles and runs a tree using this ToolBox.
- *
- * If the tree has unresolved type variables (represented as instances of ``FreeType'' 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: Tree, freeTypes: Map[FreeType, Type] = Map[FreeType, Type]()): Any
-
- /** Represents an error during toolboxing
- */
- type ToolBoxError <: Throwable
- val ToolBoxError: ToolBoxErrorExtractor
- abstract class ToolBoxErrorExtractor {
- def unapply(error: ToolBoxError): Option[(ToolBox, String)]
- }
- }
-} \ No newline at end of file
diff --git a/src/library/scala/reflect/api/TreeBuildUtil.scala b/src/library/scala/reflect/api/TreeBuildUtil.scala
deleted file mode 100644
index 87790b3812..0000000000
--- a/src/library/scala/reflect/api/TreeBuildUtil.scala
+++ /dev/null
@@ -1,159 +0,0 @@
-package scala.reflect
-package api
-
-trait TreeBuildUtil { self: Universe =>
-
- /** The symbol corresponding to the globally accessible class with the given fully qualified name `fullName`.
- * Unlike `staticClassIfDefined`, throws `MissingRequirementError` is requested class cannot be found.
- */
- def staticClass(fullName: String): Symbol
-
- /** The symbol corresponding to the globally accessible class with the given fully qualified name `fullName`.
- * Unlike `staticClass`, doesn't throw `MissingRequirementError` (returns NoSymbol) is requested class cannot be found.
- */
- def staticClassIfDefined(fullName: String): Symbol
-
- /** The symbol corresponding to the globally accessible object with the given fully qualified name `fullName`.
- * Unlike `staticModuleIfDefined`, throws `MissingRequirementError` is requested object cannot be found.
- */
- def staticModule(fullName: String): Symbol
-
- /** The symbol corresponding to the globally accessible object with the given fully qualified name `fullName`.
- * Unlike `staticModule`, doesn't throw `MissingRequirementError` (returns NoSymbol) is requested object cannot be found.
- */
- def staticModuleIfDefined(fullName: String): Symbol
-
- /** The this-ptype of the globally accessible object with the
- * given fully qualified name `fullName`.
- */
- def thisModuleType(fullName: String): Type
-
- /** Selects type symbol with given simple name `name` from the defined members of `owner`.
- * Unlike `selectTypeIfDefined`, throws `MissingRequirementError` is requested type symbol cannot be found.
- */
- def selectType(owner: Symbol, name: String): Symbol
-
- /** Selects type symbol with given simple name `name` from the defined members of `owner`.
- * Unlike `selectType`, doesn't throw `MissingRequirementError` (returns NoSymbol) is requested type symbol cannot be found.
- */
- def selectTypeIfDefined(owner: Symbol, name: String): Symbol
-
- /** Selects term symbol with given name and type from the defined members of prefix type
- * Unlike `selectTermIfDefined`, throws `MissingRequirementError` is requested term symbol cannot be found.
- */
- def selectTerm(owner: Symbol, name: String): Symbol
-
- /** Selects term symbol with given name and type from the defined members of prefix type
- * Unlike `selectTerm`, doesn't throw `MissingRequirementError` (returns NoSymbol) is requested term symbol cannot be found.
- */
- def selectTermIfDefined(owner: Symbol, name: String): Symbol
-
- /** Selects overloaded method symbol with given name and index
- * Unlike `selectOverloadedMethodIfDefined`, throws `MissingRequirementError` is requested overloaded method cannot be found.
- */
- def selectOverloadedMethod(owner: Symbol, name: String, index: Int): Symbol
-
- /** Selects overloaded method symbol with given name and index
- * Unlike `selectOverloadedMethod`, doesn't throw `MissingRequirementError` (returns NoSymbol) is requested overloaded method cannot be found.
- */
- def selectOverloadedMethodIfDefined(owner: Symbol, name: String, index: Int): Symbol
-
- /** Create a fresh free term symbol.
- * @param name the name of the free variable
- * @param info the type signature of the free variable
- * @param value the value of the free variable at runtime
- * @param flags (optional) flags of the free variable
- * @param origin debug information that tells where this symbol comes from
- */
- def newFreeTerm(name: String, info: Type, value: => Any, flags: Long = 0L, origin: String = null): Symbol
-
- /** Create a fresh free non-existential type symbol.
- * @param name the name of the free variable
- * @param info the type signature of the free variable
- * @param value a type tag that captures the value of the free variable
- * is completely phantom, since the captured type cannot be propagated to the runtime
- * if it could be, we wouldn't be creating a free type to begin with
- * the only usage for it is preserving the captured symbol for compile-time analysis
- * @param flags (optional) flags of the free variable
- * @param origin debug information that tells where this symbol comes from
- */
- def newFreeType(name: String, info: Type, value: => Any, flags: Long = 0L, origin: String = null): Symbol
-
- /** Create a fresh free existential type symbol.
- * @param name the name of the free variable
- * @param info the type signature of the free variable
- * @param value a type tag that captures the value of the free variable
- * is completely phantom, since the captured type cannot be propagated to the runtime
- * if it could be, we wouldn't be creating a free type to begin with
- * the only usage for it is preserving the captured symbol for compile-time analysis
- * @param flags (optional) flags of the free variable
- * @param origin (optional) debug information that tells where this symbol comes from
- */
- def newFreeExistential(name: String, info: Type, value: => Any, flags: Long = 0L, origin: String = null): Symbol
-
- /** Create a Modiiers structure given internal flags, qualifier, annotations */
- def modifiersFromInternalFlags(flags: Long, privateWithin: Name, annotations: List[Tree]): Modifiers
-
- val gen: TreeGen { val global: TreeBuildUtil.this.type }
-
- type TreeGen <: AbsTreeGen
-}
-
-// [Eugene to Paul] we need to expose some of the functionality provided by TreeGen
-// I added some stuff that was necessary for typetag materialization macros
-// but we should think it over and pick other generally useful stuff
-// same goes for tree traversers/transformers, type maps, etc
-// and once we expose all that, there's another question: how do we stay in sync?
-trait AbsTreeGen {
- val global: Universe
-
- import global._
- import definitions._
-
- /** Builds a reference to value whose type is given stable prefix.
- * The type must be suitable for this. For example, it
- * must not be a TypeRef pointing to an abstract type variable.
- */
- def mkAttributedQualifier(tpe: Type): Tree
-
- /** Builds a reference to value whose type is given stable prefix.
- * If the type is unsuitable, e.g. it is a TypeRef for an
- * abstract type variable, then an Ident will be made using
- * termSym as the Ident's symbol. In that case, termSym must
- * not be NoSymbol.
- */
- def mkAttributedQualifier(tpe: Type, termSym: Symbol): Tree
-
- /** Builds a typed reference to given symbol with given stable prefix. */
- def mkAttributedRef(pre: Type, sym: Symbol): Tree
-
- /** Builds a typed reference to given symbol. */
- def mkAttributedRef(sym: Symbol): Tree
-
- /** Builds a typed This reference to given symbol. */
- def mkAttributedThis(sym: Symbol): Tree
-
- /** Builds a typed Ident with an underlying symbol. */
- def mkAttributedIdent(sym: Symbol): Tree
-
- /** Builds a typed Select with an underlying symbol. */
- def mkAttributedSelect(qual: Tree, sym: Symbol): Tree
-
- /** A creator for method calls, e.g. fn[T1, T2, ...](v1, v2, ...)
- * There are a number of variations.
- *
- * @param receiver symbol of the method receiver
- * @param methodName name of the method to call
- * @param targs type arguments (if Nil, no TypeApply node will be generated)
- * @param args value arguments
- * @return the newly created trees.
- */
- def mkMethodCall(receiver: Symbol, methodName: Name, targs: List[Type], args: List[Tree]): Tree
- def mkMethodCall(method: Symbol, targs: List[Type], args: List[Tree]): Tree
- def mkMethodCall(method: Symbol, args: List[Tree]): Tree
- def mkMethodCall(target: Tree, args: List[Tree]): Tree
- def mkMethodCall(receiver: Symbol, methodName: Name, args: List[Tree]): Tree
- def mkMethodCall(receiver: Tree, method: Symbol, targs: List[Type], args: List[Tree]): Tree
- def mkMethodCall(target: Tree, targs: List[Type], args: List[Tree]): Tree
- def mkNullaryCall(method: Symbol, targs: List[Type]): Tree
-}
diff --git a/src/library/scala/reflect/api/TreePrinters.scala b/src/library/scala/reflect/api/TreePrinters.scala
index 3d64ec8e40..08a08e7b90 100644
--- a/src/library/scala/reflect/api/TreePrinters.scala
+++ b/src/library/scala/reflect/api/TreePrinters.scala
@@ -13,7 +13,9 @@ trait TreePrinters { self: Universe =>
def withUniqueIds: this.type = { uniqueIds = true; this }
}
- def show(tree: Tree, mkPrinter: PrintWriter => TreePrinter = newTreePrinter): String = {
+ def show(tree: Tree): String = show(tree, newTreePrinter)
+
+ def show(tree: Tree, mkPrinter: PrintWriter => TreePrinter): String = {
val buffer = new StringWriter()
val writer = new PrintWriter(buffer)
val printer = mkPrinter(writer)
@@ -29,13 +31,12 @@ trait TreePrinters { self: Universe =>
def newTreePrinter(out: PrintWriter): TreePrinter
// emits more or less verbatim representation of the provided tree
+ // [Eugene] todo. needs to be refined
+ // http://groups.google.com/group/scala-user/browse_thread/thread/de5a5be2e083cf8e
class RawTreePrinter(out: PrintWriter) extends TreePrinter {
- val EmptyValDef = self.emptyValDef
def print(args: Any*): Unit = args foreach {
case EmptyTree =>
print("EmptyTree")
- case EmptyValDef =>
- print("emptyValDef")
case tree @ TypeTree() =>
print("TypeTree()")
if (tree.tpe != null)
@@ -45,7 +46,7 @@ trait TreePrinters { self: Universe =>
case Literal(Constant(s: String)) =>
print("Literal(Constant(\"" + s + "\"))")
case tree: Tree =>
- print(tree.printingPrefix+"(")
+ print(tree.productPrefix+"(")
val it = tree.productIterator
while (it.hasNext) {
it.next() match {
@@ -69,16 +70,12 @@ trait TreePrinters { self: Universe =>
print(")")
case mods: Modifiers =>
val parts = collection.mutable.ListBuffer[String]()
- parts += "Set(" + mods.modifiers.map(_.sourceString).mkString(", ") + ")"
- parts += "newTypeName(\"" + mods.privateWithin.toString + "\")"
- parts += "List(" + mods.annotations.map{showRaw}.mkString(", ") + ")"
-
- var keep = 3
- if (keep == 3 && mods.annotations.isEmpty) keep -= 1
- if (keep == 2 && mods.privateWithin == EmptyTypeName) keep -= 1
- if (keep == 1 && mods.modifiers.isEmpty) keep -= 1
-
- print("Modifiers(", parts.take(keep).mkString(", "), ")")
+ parts += mods.flagString
+ if (mods.privateWithin.toString.nonEmpty)
+ parts += "newTypeName(\"" + mods.privateWithin.toString + "\")"
+ if (mods.annotations.nonEmpty)
+ parts += mods.annotations map showRaw mkString ("List(", ", ", ")")
+ print(parts mkString ("Modifiers(", ", ", ")"))
case name: Name =>
if (name.isTermName) print("newTermName(\"") else print("newTypeName(\"")
print(name.toString)
diff --git a/src/library/scala/reflect/api/Trees.scala b/src/library/scala/reflect/api/Trees.scala
index 3427136fde..2d130daa4e 100644
--- a/src/library/scala/reflect/api/Trees.scala
+++ b/src/library/scala/reflect/api/Trees.scala
@@ -2,169 +2,22 @@
* Copyright 2005-2011 LAMP/EPFL
* @author Martin Odersky
*/
-
package scala.reflect
package api
-import scala.collection.mutable.ListBuffer
-
// Syncnote: Trees are currently not thread-safe.
-trait Trees { self: Universe =>
+trait Trees extends base.Trees { self: Universe =>
- private[scala] var nodeCount = 0
+ override type Tree >: Null <: TreeApi
- type Modifiers >: Null <: AbsModifiers
- val NoMods: Modifiers
+ /** ... */
+ trait TreeApi extends TreeBase { this: Tree =>
- // TODO - Where do I put this?
- object BackquotedIdentifier
+ /** ... */
+ def pos: Position
- abstract class AbsModifiers {
- def modifiers: Set[Modifier]
- def hasModifier(mod: Modifier): Boolean
- def privateWithin: Name // default: EmptyTypeName
- def annotations: List[Tree] // default: List()
- def mapAnnotations(f: List[Tree] => List[Tree]): Modifiers
- }
-
- def Modifiers(mods: Set[Modifier] = Set(),
- privateWithin: Name = EmptyTypeName,
- annotations: List[Tree] = List()): Modifiers
-
- /** Tree is the basis for scala's abstract syntax. The nodes are
- * implemented as case classes, and the parameters which initialize
- * a given tree are immutable: however Trees have several mutable
- * fields which are manipulated in the course of typechecking,
- * including pos, symbol, and tpe.
- *
- * Newly instantiated trees have tpe set to null (though it
- * may be set immediately thereafter depending on how it is
- * constructed.) When a tree is passed to the typer, typically via
- * `typer.typed(tree)`, under normal circumstances the tpe must be
- * null or the typer will ignore it. Furthermore, the typer is not
- * required to return the same tree it was passed.
- *
- * Trees can be easily traversed with e.g. foreach on the root node;
- * for a more nuanced traversal, subclass Traverser. Transformations
- * can be considerably trickier: see the numerous subclasses of
- * Transformer found around the compiler.
- *
- * Copying Trees should be done with care depending on whether
- * it need be done lazily or strictly (see LazyTreeCopier and
- * StrictTreeCopier) and on whether the contents of the mutable
- * fields should be copied. The tree copiers will copy the mutable
- * attributes to the new tree; calling Tree#duplicate will copy
- * symbol and tpe, but all the positions will be focused.
- *
- * Trees can be coarsely divided into four mutually exclusive categories:
- *
- * - TermTrees, representing terms
- * - TypTrees, representing types. Note that is `TypTree`, not `TypeTree`.
- * - SymTrees, which may represent types or terms.
- * - Other Trees, which have none of those as parents.
- *
- * SymTrees include important nodes Ident and Select, which are
- * used as both terms and types; they are distinguishable based on
- * whether the Name is a TermName or TypeName. The correct way for
- * to test for a type or a term (on any Tree) are the isTerm/isType
- * methods on Tree.
- *
- * "Others" are mostly syntactic or short-lived constructs. Examples
- * include CaseDef, which wraps individual match cases: they are
- * neither terms nor types, nor do they carry a symbol. Another
- * example is Parens, which is eliminated during parsing.
- */
- abstract class Tree extends Product {
- val id = nodeCount
- nodeCount += 1
-
- /** Prefix under which to print this tree type. Defaults to product
- * prefix (e.g. DefTree) but because that is used in reification
- * it cannot be altered without breaking reflection.
- */
- def printingPrefix = productPrefix
-
- def pos: Position = rawatt.pos.asInstanceOf[Position] // [Eugene] how do we get rid of this cast?
- def pos_=(pos: Position): Unit = rawatt = (rawatt withPos pos) // the "withPos" part is crucial to robustness
- def setPos(newpos: Position): this.type = { pos = newpos; this }
-
- // [Eugene] can we make this more type-safe
- private var rawatt: Attachment = NoPosition
- def attach(att: Any): Unit =
- rawatt match {
- case NontrivialAttachment(pos, payload) =>
- val index = payload.indexWhere(p => p.getClass == att.getClass)
- if (index == -1) payload += att
- else payload(index) = att
- case _ =>
- rawatt = NontrivialAttachment(pos, collection.mutable.ListBuffer[Any](att))
- }
-
- // a) why didn't this method already exist
- // b) what is all this "Any" business?
- // c) am I reverse-engineering this correctly? It shouldn't be hard
- // to figure out what is attached.
- def attachments: List[Any] = rawatt match {
- case NoPosition => Nil
- case NontrivialAttachment(pos, atts) => pos :: atts.toList
- case x => List(x)
- }
- // Writing "Any" repeatedly to work within this structure
- // is making my skin crawl.
- def hasAttachment(x: Any) = attachments contains x
-
- def withAttachment(att: Any): this.type = { attach(att); this }
- def detach(att: Any): Unit =
- detach(att.getClass)
- def detach(clazz: java.lang.Class[_]): Unit =
- rawatt match {
- case NontrivialAttachment(pos, payload) =>
- val index = payload.indexWhere(p => p.getClass == clazz)
- if (index != -1) payload.remove(index)
- case _ =>
- // do nothing
- }
- def withoutAttachment(att: Any): this.type = { detach(att); this }
- def attachment[T: ClassTag]: T = attachmentOpt[T] getOrElse { throw new Error("no attachment of type %s".format(classTag[T].erasure)) }
- def attachmentOpt[T: ClassTag]: Option[T] =
- firstAttachment { case attachment if attachment.getClass == classTag[T].erasure => attachment.asInstanceOf[T] }
-
- def firstAttachment[T](p: PartialFunction[Any, T]): Option[T] =
- rawatt match {
- case NontrivialAttachment(pos, payload) => payload.collectFirst(p)
- case _ => None
- }
-
- private[this] var rawtpe: Type = _
-
- def tpe = rawtpe
- def tpe_=(t: Type) = rawtpe = t
-
- def resetType(): this.type = { tpe = null ; this }
- def resetSymbol(): this.type = { if (hasSymbol) symbol = NoSymbol ; this }
-
- /** Set tpe to give `tp` and return this.
- */
- def setType(tp: Type): this.type = { rawtpe = tp; this }
-
- /** Like `setType`, but if this is a previously empty TypeTree that
- * fact is remembered so that resetAllAttrs will snap back.
- *
- * @PP: Attempting to elaborate on the above, I find: If defineType
- * is called on a TypeTree whose type field is null or NoType,
- * this is recorded as "wasEmpty = true". That value is used in
- * ResetAttrs, which nulls out the type field of TypeTrees
- * for which wasEmpty is true, leaving the others alone.
- *
- * resetAllAttrs is used in situations where some speculative
- * typing of a tree takes place, fails, and the tree needs to be
- * returned to its former state to try again. So according to me:
- * using `defineType` instead of `setType` is how you communicate
- * that the type being set does not depend on any previous state,
- * and therefore should be abandoned if the current line of type
- * inquiry doesn't work out.
- */
- def defineType(tp: Type): this.type = setType(tp)
+ /** ... */
+ def tpe: Type
/** Note that symbol is fixed as null at this level. In SymTrees,
* it is overridden and implemented with a var, initialized to NoSymbol.
@@ -181,887 +34,528 @@ trait Trees { self: Universe =>
* Attempting to set the symbol of a Tree which does not support
* it will induce an exception.
*/
- 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 symbol: Symbol
- def hasSymbol = false
- def isDef = false
- def isEmpty = false
- @inline final def orElse(alt: => Tree) = if (!isEmpty) this else alt
- @inline final def andAlso(f: Tree => Unit): Tree = { if (!this.isEmpty) f(this) ; this }
+ /** ... */
+ def hasSymbol: Boolean
- def hasAssignedType = (tpe ne null) && (tpe ne NoType)
- def hasAssignedSymbol = (symbol ne null) && (symbol ne NoSymbol)
-
- @inline final def hasSymbolWhich(f: Symbol => Boolean) = hasAssignedSymbol && f(symbol)
- @inline final def hasTypeWhich(f: Type => Boolean) = hasAssignedType && f(tpe)
-
- /** The canonical way to test if a Tree represents a term.
+ /** Provides an alternate if tree is empty
+ * @param alt The alternate tree
+ * @return If this tree is non empty, this tree, otherwise `alt`.
*/
- 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
- }
+ def orElse(alt: => Tree): Tree
/** Apply `f` to each subtree */
- def foreach(f: Tree => Unit) { new ForeachTreeTraverser(f).traverse(this) }
+ def foreach(f: Tree => Unit): Unit
- /** Find all subtrees matching predicate `p` */
- def withFilter(f: Tree => Boolean): List[Tree] = {
- val ft = new FilterTreeTraverser(f)
- ft.traverse(this)
- ft.hits.toList
- }
- def filter(f: Tree => Boolean): List[Tree] = withFilter(f)
+ /** Find all subtrees matching predicate `p`. Same as `filter` */
+ def withFilter(f: Tree => Boolean): List[Tree]
- /** Apply `pf' to each subtree on which the function is defined */
- def collect[T](pf: PartialFunction[Tree, T]): List[T] = {
- val ctt = new CollectTreeTraverser[T](pf)
- ctt.traverse(this)
- ctt.results.toList
- }
+ /** Find all subtrees matching predicate `p`. Same as `withFilter` */
+ def filter(f: Tree => Boolean): List[Tree]
+
+ /** Apply `pf' to each subtree on which the function is defined and collect the results.
+ */
+ def collect[T](pf: PartialFunction[Tree, T]): List[T]
/** Returns optionally first tree (in a preorder traversal) which satisfies predicate `p`,
* or None if none exists.
*/
- def find(p: Tree => Boolean): Option[Tree] = {
- val ft = new FindTreeTraverser(p)
- ft.traverse(this)
- ft.result
- }
+ def find(p: Tree => Boolean): Option[Tree]
/** Is there exists a part of this tree which satisfies predicate `p`? */
- def exists(p: Tree => Boolean): Boolean = !find(p).isEmpty
+ def exists(p: Tree => Boolean): Boolean
/** Do all parts of this tree satisfy predicate `p`? */
- def forAll(p: Tree => Boolean): Boolean = find(!p(_)).isEmpty
-
- def equalsStructure(that : Tree) = equalsStructure0(that)(_ eq _)
- def equalsStructure0(that: Tree)(f: (Tree,Tree) => Boolean): Boolean =
- f(this, that) || ((this.productArity == that.productArity) && {
- def equals0(this0: Any, that0: Any): Boolean = (this0, that0) match {
- case (x: Tree, y: Tree) => f(x, y) || (x equalsStructure0 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 equalsStructure0 y.original)(f)
- case _ =>
- true
- }
-
- (this.productIterator zip that.productIterator forall { case (x, y) => equals0(x, y) }) && compareOriginals()
- })
+ def forAll(p: Tree => Boolean): Boolean
+
+ /** Tests whether two trees are structurall equal.
+ * Note that `==` on trees is reference equality.
+ */
+ def equalsStructure(that : Tree): Boolean
/** The direct child trees of this tree.
* EmptyTrees are always omitted. Lists are flattened.
*/
- 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
- }
+ def children: List[Tree]
+
+ /** Extracts free term symbols from a tree that is reified or contains reified subtrees.
+ */
+ def freeTerms: List[FreeTermSymbol]
+
+ /** Extracts free type symbols from a tree that is reified or contains reified subtrees.
+ */
+ def freeTypes: List[FreeTypeSymbol]
+
+ /** Substitute symbols in `to` for corresponding occurrences of references to
+ * symbols `from` in this type.
+ */
+ def substituteSymbols(from: List[Symbol], to: List[Symbol]): Tree
+
+ /** Substitute types in `to` for corresponding occurrences of references to
+ * symbols `from` in this tree.
+ */
+ def substituteTypes(from: List[Symbol], to: List[Type]): Tree
+
+ /** Substitute given tree `to` for occurrences of nodes that represent
+ * `C.this`, where `C` referes to the given class `clazz`.
+ */
+ def substituteThis(clazz: Symbol, to: Tree): Tree
/** Make a copy of this tree, keeping all attributes,
* except that all positions are focused (so nothing
* in this tree will be found when searching by position).
*/
- def duplicate: this.type =
- duplicateTree(this).asInstanceOf[this.type]
-
- private[scala] def copyAttrs(tree: Tree): this.type = {
- rawatt = tree.rawatt
- tpe = tree.tpe
- if (hasSymbol) symbol = tree.symbol
- this
- }
+ def duplicate: this.type
+ }
+
+ override type TermTree >: Null <: Tree with TermTreeApi
- override def toString: String = show(this)
- override def hashCode(): Int = System.identityHashCode(this)
- override def equals(that: Any) = this eq that.asInstanceOf[AnyRef]
+ /** The API that all term trees support */
+ trait TermTreeApi extends TreeApi { this: TermTree =>
}
- /** A tree for a term. Not all terms are TermTrees; use isTerm
- * to reliably identify terms.
- */
- trait TermTree extends Tree
+ override type TypTree >: Null <: Tree with TypTreeApi
- /** A tree for a type. Not all types are TypTrees; use isType
- * to reliably identify types.
- */
- trait TypTree extends Tree
+ /** The API that all typ trees support */
+ trait TypTreeApi extends TreeApi { this: TypTree =>
+ }
- /** A tree with a mutable symbol field, initialized to NoSymbol.
- */
- trait SymTree extends Tree {
- override def hasSymbol = true
- override var symbol: Symbol = NoSymbol
+ override type SymTree >: Null <: Tree with SymTreeApi
+
+ /** The API that all sym trees support */
+ trait SymTreeApi extends TreeApi { this: SymTree =>
+ def symbol: Symbol
}
- /** A tree with a name - effectively, a DefTree or RefTree.
- */
- trait NameTree extends Tree {
+ override type NameTree >: Null <: Tree with NameTreeApi
+
+ /** The API that all name trees support */
+ trait NameTreeApi extends TreeApi { this: NameTree =>
def name: Name
}
- /** A tree which references a symbol-carrying entity.
- * References one, as opposed to defining one; definitions
- * are in DefTrees.
- */
- trait RefTree extends SymTree with NameTree {
+ override type RefTree >: Null <: SymTree with NameTree with RefTreeApi
+
+ /** The API that all ref trees support */
+ trait RefTreeApi extends SymTreeApi with NameTreeApi { this: RefTree =>
def qualifier: Tree // empty for Idents
def name: Name
}
- /** A tree which defines a symbol-carrying entity.
- */
- abstract class DefTree extends SymTree with NameTree {
+ override type DefTree >: Null <: SymTree with NameTree with DefTreeApi
+
+ /** The API that all def trees support */
+ trait DefTreeApi extends SymTreeApi with NameTreeApi { this: DefTree =>
def name: Name
- override def isDef = true
}
-// ----- tree node alternatives --------------------------------------
-
- /** The empty tree */
- 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
- override def resetType(): this.type = this
- }
+ override type MemberDef >: Null <: DefTree with MemberDefApi
- /** Common base class for all member definitions: types, classes,
- * objects, packages, vals and vars, defs.
- */
- abstract class MemberDef extends DefTree {
+ /** The API that all member defs support */
+ trait MemberDefApi extends DefTreeApi { this: MemberDef =>
def mods: Modifiers
- def keyword: String = this match {
- case TypeDef(_, _, _, _) => "type"
- case ClassDef(mods, _, _, _) => if (mods hasModifier Modifier.`trait`) "trait" else "class"
- case DefDef(_, _, _, _, _, _) => "def"
- case ModuleDef(_, _, _) => "object"
- case PackageDef(_, _) => "package"
- case ValDef(mods, _, _, _) => if (mods hasModifier Modifier.mutable) "var" else "val"
- case _ => ""
- }
}
- /** A packaging, such as `package pid { stats }`
- */
- case class PackageDef(pid: RefTree, stats: List[Tree])
- extends MemberDef {
- def name = pid.name
- def mods = Modifiers()
+ override type PackageDef >: Null <: MemberDef with PackageDefApi
+
+ /** The API that all package defs support */
+ trait PackageDefApi extends MemberDefApi { this: PackageDef =>
+ val pid: RefTree
+ val stats: List[Tree]
}
- /** A common base class for class and object definitions.
- */
- abstract class ImplDef extends MemberDef {
- def impl: Template
+ override type ImplDef >: Null <: MemberDef with ImplDefApi
+
+ /** The API that all impl defs support */
+ trait ImplDefApi extends MemberDefApi { this: ImplDef =>
+ val impl: Template
}
- /** A class definition.
- */
- case class ClassDef(mods: Modifiers, name: TypeName, tparams: List[TypeDef], impl: Template)
- extends ImplDef
+ override type ClassDef >: Null <: ImplDef with ClassDefApi
- /** @param sym the class symbol
- * @return the implementation template
- */
- def ClassDef(sym: Symbol, impl: Template): ClassDef
+ /** The API that all class defs support */
+ trait ClassDefApi extends ImplDefApi { this: ClassDef =>
+ val mods: Modifiers
+ val name: TypeName
+ val tparams: List[TypeDef]
+ val impl: Template
+ }
- /** An object definition, e.g. `object Foo`. Internally, objects are
- * quite frequently called modules to reduce ambiguity.
- */
- case class ModuleDef(mods: Modifiers, name: TermName, impl: Template)
- extends ImplDef
+ override type ModuleDef >: Null <: ImplDef with ModuleDefApi
- /**
- * @param sym the class symbol
- * @param impl the implementation template
- */
- def ModuleDef(sym: Symbol, impl: Template): ModuleDef
+ /** The API that all module defs support */
+ trait ModuleDefApi extends ImplDefApi { this: ModuleDef =>
+ val mods: Modifiers
+ val name: TermName
+ val impl: Template
+ }
- /** A common base class for ValDefs and DefDefs.
- */
- abstract class ValOrDefDef extends MemberDef {
+ override type ValOrDefDef >: Null <: MemberDef with ValOrDefDefApi
+
+ /** The API that all val defs and def defs support */
+ trait ValOrDefDefApi extends MemberDefApi { this: ValOrDefDef =>
def name: Name // can't be a TermName because macros can be type names.
def tpt: Tree
def rhs: Tree
}
- /** Broadly speaking, a value definition. All these are encoded as ValDefs:
- *
- * - immutable values, e.g. "val x"
- * - mutable values, e.g. "var x" - the MUTABLE flag set in mods
- * - lazy values, e.g. "lazy val x" - the LAZY flag set in mods
- * - method parameters, see vparamss in DefDef - the PARAM flag is set in mods
- * - explicit self-types, e.g. class A { self: Bar => } - !!! not sure what is set.
- */
- case class ValDef(mods: Modifiers, name: TermName, tpt: Tree, rhs: Tree) extends ValOrDefDef
+ override type ValDef >: Null <: ValOrDefDef with ValDefApi
- def ValDef(sym: Symbol, rhs: Tree): ValDef
+ /** The API that all val defs support */
+ trait ValDefApi extends ValOrDefDefApi { this: ValDef =>
+ val mods: Modifiers
+ val name: TermName
+ val tpt: Tree
+ val rhs: Tree
+ }
- def ValDef(sym: Symbol): ValDef
+ override type DefDef >: Null <: ValOrDefDef with DefDefApi
- /** A method or macro definition.
- * @param name The name of the method or macro. Can be a type name in case this is a type macro
- */
- case class DefDef(mods: Modifiers, name: Name, tparams: List[TypeDef],
- vparamss: List[List[ValDef]], tpt: Tree, rhs: Tree) extends ValOrDefDef
+ /** The API that all def defs support */
+ trait DefDefApi extends ValOrDefDefApi { this: DefDef =>
+ val mods: Modifiers
+ val name: Name
+ val tparams: List[TypeDef]
+ val vparamss: List[List[ValDef]]
+ val tpt: Tree
+ val rhs: Tree
+ }
- def DefDef(sym: Symbol, mods: Modifiers, vparamss: List[List[ValDef]], rhs: Tree): DefDef
+ override type TypeDef >: Null <: MemberDef with TypeDefApi
- def DefDef(sym: Symbol, vparamss: List[List[ValDef]], rhs: Tree): DefDef
+ /** The API that all type defs support */
+ trait TypeDefApi extends MemberDefApi { this: TypeDef =>
+ val mods: Modifiers
+ val name: TypeName
+ val tparams: List[TypeDef]
+ val rhs: Tree
+ }
- def DefDef(sym: Symbol, mods: Modifiers, rhs: Tree): DefDef
+ override type LabelDef >: Null <: DefTree with TermTree with LabelDefApi
- def DefDef(sym: Symbol, rhs: Tree): DefDef
+ /** The API that all label defs support */
+ trait LabelDefApi extends DefTreeApi with TermTreeApi { this: LabelDef =>
+ val name: TermName
+ val params: List[Ident]
+ val rhs: Tree
+ }
- def DefDef(sym: Symbol, rhs: List[List[Symbol]] => Tree): DefDef
+ override type ImportSelector >: Null <: ImportSelectorApi
- /** An abstract type, a type parameter, or a type alias.
- */
- case class TypeDef(mods: Modifiers, name: TypeName, tparams: List[TypeDef], rhs: Tree)
- extends MemberDef
-
- /** A TypeDef node which defines given `sym` with given tight hand side `rhs`. */
- def TypeDef(sym: Symbol, rhs: Tree): TypeDef
-
- /** A TypeDef node which defines abstract type or type parameter for given `sym` */
- def TypeDef(sym: Symbol): TypeDef
-
- /** A labelled expression. Not expressible in language syntax, but
- * generated by the compiler to simulate while/do-while loops, and
- * also by the pattern matcher.
- *
- * The label acts much like a nested function, where `params` represents
- * the incoming parameters. The symbol given to the LabelDef should have
- * a MethodType, as if it were a nested function.
- *
- * Jumps are apply nodes attributed with a label's symbol. The
- * arguments from the apply node will be passed to the label and
- * assigned to the Idents.
- *
- * Forward jumps within a block are allowed.
- */
- case class LabelDef(name: TermName, params: List[Ident], rhs: Tree)
- extends DefTree with TermTree
-
- def LabelDef(sym: Symbol, params: List[Symbol], rhs: Tree): LabelDef
-
- /** Import selector
- *
- * Representation of an imported name its optional rename and their optional positions
- *
- * @param name the imported name
- * @param namePos its position or -1 if undefined
- * @param rename the name the import is renamed to (== name if no renaming)
- * @param renamePos the position of the rename or -1 if undefined
- */
- case class ImportSelector(name: Name, namePos: Int, rename: Name, renamePos: Int)
-
- /** Import clause
- *
- * @param expr
- * @param selectors
- */
- case class Import(expr: Tree, selectors: List[ImportSelector])
- extends SymTree
- // The symbol of an Import is an import symbol @see Symbol.newImport
- // It's used primarily as a marker to check that the import has been typechecked.
-
- /** Instantiation template of a class or trait
- *
- * @param parents
- * @param body
- */
- case class Template(parents: List[Tree], self: ValDef, body: List[Tree])
- extends SymTree {
- // the symbol of a template is a local dummy. @see Symbol.newLocalDummy
- // the owner of the local dummy is the enclosing trait or class.
- // the local dummy is itself the owner of any local blocks
- // For example:
- //
- // class C {
- // def foo // owner is C
- // {
- // def bar // owner is local dummy
- // }
+ /** The API that all import selectors support */
+ trait ImportSelectorApi { this: ImportSelector =>
+ val name: Name
+ val namePos: Int
+ val rename: Name
+ val renamePos: Int
}
- /** Block of expressions (semicolon separated expressions) */
- case class Block(stats: List[Tree], expr: Tree)
- extends TermTree
+ override type Import >: Null <: SymTree with ImportApi
- /** Block factory that flattens directly nested blocks.
- */
- def Block(stats: Tree*): Block
+ /** The API that all imports support */
+ trait ImportApi extends SymTreeApi { this: Import =>
+ val expr: Tree
+ val selectors: List[ImportSelector]
+ }
- /** Case clause in a pattern match, eliminated during explicitouter
- * (except for occurrences in switch statements)
- */
- case class CaseDef(pat: Tree, guard: Tree, body: Tree)
- extends Tree
+ override type Template >: Null <: SymTree with TemplateApi
- /** casedef shorthand */
- def CaseDef(pat: Tree, body: Tree): CaseDef
+ /** The API that all templates support */
+ trait TemplateApi extends SymTreeApi { this: Template =>
+ val parents: List[Tree]
+ val self: ValDef
+ val body: List[Tree]
+ }
- /** Alternatives of patterns, eliminated by explicitouter, except for
- * occurrences in encoded Switch stmt (=remaining Match(CaseDef(...))
- */
- case class Alternative(trees: List[Tree])
- extends TermTree
+ override type Block >: Null <: TermTree with BlockApi
- /** Repetition of pattern, eliminated by explicitouter */
- case class Star(elem: Tree)
- extends TermTree
+ /** The API that all blocks support */
+ trait BlockApi extends TermTreeApi { this: Block =>
+ val stats: List[Tree]
+ val expr: Tree
+ }
- /** Bind of a variable to a rhs pattern, eliminated by explicitouter
- *
- * @param name
- * @param body
- */
- case class Bind(name: Name, body: Tree)
- extends DefTree
+ override type CaseDef >: Null <: Tree with CaseDefApi
- def Bind(sym: Symbol, body: Tree): Bind
+ /** The API that all case defs support */
+ trait CaseDefApi extends TreeApi { this: CaseDef =>
+ val pat: Tree
+ val guard: Tree
+ val body: Tree
+ }
- case class UnApply(fun: Tree, args: List[Tree])
- extends TermTree
+ override type Alternative >: Null <: TermTree with AlternativeApi
- /** Array of expressions, needs to be translated in backend,
- */
- case class ArrayValue(elemtpt: Tree, elems: List[Tree])
- extends TermTree
+ /** The API that all alternatives support */
+ trait AlternativeApi extends TermTreeApi { this: Alternative =>
+ val trees: List[Tree]
+ }
- /** Anonymous function, eliminated by analyzer */
- case class Function(vparams: List[ValDef], body: Tree)
- extends TermTree with SymTree
- // The symbol of a Function is a synthetic value of name nme.ANON_FUN_NAME
- // It is the owner of the function's parameters.
+ override type Star >: Null <: TermTree with StarApi
- /** Assignment */
- case class Assign(lhs: Tree, rhs: Tree)
- extends TermTree
+ /** The API that all stars support */
+ trait StarApi extends TermTreeApi { this: Star =>
+ val elem: Tree
+ }
- /** Either an assignment or a named argument. Only appears in argument lists,
- * eliminated by typecheck (doTypedApply)
- */
- case class AssignOrNamedArg(lhs: Tree, rhs: Tree)
- extends TermTree
-
- /** Conditional expression */
- case class If(cond: Tree, thenp: Tree, elsep: Tree)
- extends TermTree
-
- /** - Pattern matching expression (before explicitouter)
- * - Switch statements (after explicitouter)
- *
- * After explicitouter, cases will satisfy the following constraints:
- *
- * - all guards are `EmptyTree`,
- * - all patterns will be either `Literal(Constant(x:Int))`
- * or `Alternative(lit|...|lit)`
- * - except for an "otherwise" branch, which has pattern
- * `Ident(nme.WILDCARD)`
- */
- case class Match(selector: Tree, cases: List[CaseDef])
- extends TermTree
+ override type Bind >: Null <: DefTree with BindApi
- /** Return expression */
- case class Return(expr: Tree)
- extends TermTree with SymTree
- // The symbol of a Return node is the enclosing method.
+ /** The API that all binds support */
+ trait BindApi extends DefTreeApi { this: Bind =>
+ val name: Name
+ val body: Tree
+ }
- case class Try(block: Tree, catches: List[CaseDef], finalizer: Tree)
- extends TermTree
+ override type UnApply >: Null <: TermTree with UnApplyApi
- def Try(body: Tree, cases: (Tree, Tree)*): Try
+ /** The API that all unapplies support */
+ trait UnApplyApi extends TermTreeApi { this: UnApply =>
+ val fun: Tree
+ val args: List[Tree]
+ }
- /** Throw expression */
- case class Throw(expr: Tree)
- extends TermTree
+ override type ArrayValue >: Null <: TermTree with ArrayValueApi
- def Throw(tpe: Type, args: Tree*): Throw
+ /** The API that all array values support */
+ trait ArrayValueApi extends TermTreeApi { this: ArrayValue =>
+ val elemtpt: Tree
+ val elems: List[Tree]
+ }
- /** Object instantiation
- * One should always use factory method below to build a user level new.
- *
- * @param tpt a class type
- */
- case class New(tpt: Tree) extends TermTree
+ override type Function >: Null <: TermTree with SymTree with FunctionApi
- /** Factory method for object creation `new tpt(args_1)...(args_n)`
- * A `New(t, as)` is expanded to: `(new t).<init>(as)`
- */
- def New(tpt: Tree, argss: List[List[Tree]]): Tree
+ /** The API that all functions support */
+ trait FunctionApi extends TermTreeApi with SymTreeApi { this: Function =>
+ val vparams: List[ValDef]
+ val body: Tree
+ }
- /** 0-1 argument list new, based on a type.
- */
- def New(tpe: Type, args: Tree*): Tree
+ override type Assign >: Null <: TermTree with AssignApi
- def New(sym: Symbol, args: Tree*): Tree
+ /** The API that all assigns support */
+ trait AssignApi extends TermTreeApi { this: Assign =>
+ val lhs: Tree
+ val rhs: Tree
+ }
- /** Type annotation, eliminated by explicit outer */
- case class Typed(expr: Tree, tpt: Tree)
- extends TermTree
+ override type AssignOrNamedArg >: Null <: TermTree with AssignOrNamedArgApi
- /** Common base class for Apply and TypeApply. This could in principle
- * be a SymTree, but whether or not a Tree is a SymTree isn't used
- * to settle any interesting questions, and it would add a useless
- * field to all the instances (useless, since GenericApply forwards to
- * the underlying fun.)
- */
- abstract class GenericApply extends TermTree {
- val fun: Tree
- val args: List[Tree]
+ /** The API that all assigns support */
+ trait AssignOrNamedArgApi extends TermTreeApi { this: AssignOrNamedArg =>
+ val lhs: Tree
+ val rhs: Tree
}
- /** Explicit type application.
- * @PP: All signs point toward it being a requirement that args.nonEmpty,
- * but I can't find that explicitly stated anywhere. Unless your last name
- * is odersky, you should probably treat it as true.
- */
- case class TypeApply(fun: Tree, args: List[Tree])
- extends GenericApply {
+ override type If >: Null <: TermTree with IfApi
- // Testing the above theory re: args.nonEmpty.
- require(args.nonEmpty, this)
- override def symbol: Symbol = fun.symbol
- override def symbol_=(sym: Symbol) { fun.symbol = sym }
+ /** The API that all ifs support */
+ trait IfApi extends TermTreeApi { this: If =>
+ val cond: Tree
+ val thenp: Tree
+ val elsep: Tree
}
- /** Value application */
- case class Apply(fun: Tree, args: List[Tree])
- extends GenericApply {
- override def symbol: Symbol = fun.symbol
- override def symbol_=(sym: Symbol) { fun.symbol = sym }
+ override type Match >: Null <: TermTree with MatchApi
+
+ /** The API that all matches support */
+ trait MatchApi extends TermTreeApi { this: Match =>
+ val selector: Tree
+ val cases: List[CaseDef]
}
- def Apply(sym: Symbol, args: Tree*): Tree
+ override type Return >: Null <: TermTree with SymTree with ReturnApi
- // 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)
+ /** The API that all returns support */
+ trait ReturnApi extends TermTreeApi { this: Return =>
+ val expr: Tree
+ }
- // 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)
+ override type Try >: Null <: TermTree with TryApi
- // TODO: use a factory method, not a class (???)
- // as a case in point of the comment that should go here by similarity to ApplyToImplicitArgs,
- // this tree is considered in importers, but not in treecopier
- class ApplyConstructor(tpt: Tree, args: List[Tree]) extends Apply(Select(New(tpt), nme.CONSTRUCTOR), args) {
- override def printingPrefix = "ApplyConstructor"
+ /** The API that all tries support */
+ trait TryApi extends TermTreeApi { this: Try =>
+ val block: Tree
+ val catches: List[CaseDef]
+ val finalizer: Tree
}
- /** Dynamic value application.
- * In a dynamic application q.f(as)
- * - q is stored in qual
- * - as is stored in args
- * - f is stored as the node's symbol field.
- */
- case class ApplyDynamic(qual: Tree, args: List[Tree])
- extends TermTree with SymTree
- // The symbol of an ApplyDynamic is the function symbol of `qual`, or NoSymbol, if there is none.
+ override type Throw >: Null <: TermTree with ThrowApi
- /** Super reference, qual = corresponding this reference
- * A super reference C.super[M] is represented as Super(This(C), M).
- */
- case class Super(qual: Tree, mix: TypeName) extends TermTree {
- // The symbol of a Super is the class _from_ which the super reference is made.
- // For instance in C.super(...), it would be C.
- override def symbol: Symbol = qual.symbol
- override def symbol_=(sym: Symbol) { qual.symbol = sym }
+ /** The API that all tries support */
+ trait ThrowApi extends TermTreeApi { this: Throw =>
+ val expr: Tree
}
- def Super(sym: Symbol, mix: TypeName): Tree
-
- /** Self reference */
- case class This(qual: TypeName)
- extends TermTree with SymTree
- // The symbol of a This is the class to which the this refers.
- // For instance in C.this, it would be C.
+ override type New >: Null <: TermTree with NewApi
- def This(sym: Symbol): Tree
+ /** The API that all news support */
+ trait NewApi extends TermTreeApi { this: New =>
+ val tpt: Tree
+ }
- /** Designator <qualifier> . <name> */
- case class Select(qualifier: Tree, name: Name)
- extends RefTree
+ override type Typed >: Null <: TermTree with TypedApi
- def Select(qualifier: Tree, name: String): Select
+ /** The API that all typeds support */
+ trait TypedApi extends TermTreeApi { this: Typed =>
+ val expr: Tree
+ val tpt: Tree
+ }
- def Select(qualifier: Tree, sym: Symbol): Select
+ override type GenericApply >: Null <: TermTree with GenericApplyApi
- /** Identifier <name> */
- case class Ident(name: Name) extends RefTree {
- def qualifier: Tree = EmptyTree
- def isBackquoted = this hasAttachment BackquotedIdentifier
+ /** The API that all applies support */
+ trait GenericApplyApi extends TermTreeApi { this: GenericApply =>
+ val fun: Tree
+ val args: List[Tree]
}
- def Ident(name: String): Ident
+ override type TypeApply >: Null <: GenericApply with TypeApplyApi
- def Ident(sym: Symbol): Ident
-
- /** Marks underlying reference to id as boxed.
- * @pre id must refer to a captured variable
- * A reference such marked will refer to the boxed entity, no dereferencing
- * with `.elem` is done on it.
- * This tree node can be emitted by macros such as reify that call referenceCapturedVariable.
- * It is eliminated in LambdaLift, where the boxing conversion takes place.
- */
- case class ReferenceToBoxed(ident: Ident) extends TermTree {
- override def symbol: Symbol = ident.symbol
- override def symbol_=(sym: Symbol) { ident.symbol = sym }
+ /** The API that all type applies support */
+ trait TypeApplyApi extends GenericApplyApi { this: TypeApply =>
}
- /** Literal */
- case class Literal(value: Constant)
- extends TermTree {
- assert(value ne null)
+ override type Apply >: Null <: GenericApply with ApplyApi
+
+ /** The API that all applies support */
+ trait ApplyApi extends GenericApplyApi { this: Apply =>
}
-// @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))
+ override type ApplyDynamic >: Null <: TermTree with SymTree with ApplyDynamicApi
- /** A tree that has an annotation attached to it. Only used for annotated types and
- * annotation ascriptions, annotations on definitions are stored in the Modifiers.
- * Eliminated by typechecker (typedAnnotated), the annotations are then stored in
- * an AnnotatedType.
- */
- case class Annotated(annot: Tree, arg: Tree) extends Tree
+ /** The API that all apply dynamics support */
+ trait ApplyDynamicApi extends TermTreeApi with SymTreeApi { this: ApplyDynamic =>
+ val qual: Tree
+ val args: List[Tree]
+ }
- /** Singleton type, eliminated by RefCheck */
- case class SingletonTypeTree(ref: Tree)
- extends TypTree
+ override type Super >: Null <: TermTree with SuperApi
- /** Type selection <qualifier> # <name>, eliminated by RefCheck */
- case class SelectFromTypeTree(qualifier: Tree, name: TypeName)
- extends TypTree with RefTree
+ /** The API that all supers support */
+ trait SuperApi extends TermTreeApi { this: Super =>
+ val qual: Tree
+ val mix: TypeName
+ }
- /** Intersection type <parent1> with ... with <parentN> { <decls> }, eliminated by RefCheck */
- case class CompoundTypeTree(templ: Template)
- extends TypTree
+ override type This >: Null <: TermTree with SymTree with ThisApi
- /** Applied type <tpt> [ <args> ], eliminated by RefCheck */
- case class AppliedTypeTree(tpt: Tree, args: List[Tree])
- extends TypTree {
- override def symbol: Symbol = tpt.symbol
- override def symbol_=(sym: Symbol) { tpt.symbol = sym }
+ /** The API that all thises support */
+ trait ThisApi extends TermTreeApi with SymTreeApi { this: This =>
+ val qual: TypeName
}
- case class TypeBoundsTree(lo: Tree, hi: Tree)
- extends TypTree
-
- case class ExistentialTypeTree(tpt: Tree, whereClauses: List[Tree])
- extends TypTree
-
- /** A synthetic tree holding an arbitrary type. Not to be confused with
- * with TypTree, the trait for trees that are only used for type trees.
- * TypeTree's are inserted in several places, but most notably in
- * `RefCheck`, where the arbitrary type trees are all replaced by
- * TypeTree's. */
- case class TypeTree() extends TypTree {
- 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)
- this setPos tree.pos
- }
+ override type Select >: Null <: RefTree with SelectApi
- override def defineType(tp: Type): this.type = {
- wasEmpty = isEmpty
- setType(tp)
- }
+ /** The API that all selects support */
+ trait SelectApi extends RefTreeApi { this: Select =>
+ val qualifier: Tree
+ val name: Name
}
- def TypeTree(tp: Type): TypeTree = TypeTree() setType tp
+ override type Ident >: Null <: RefTree with IdentApi
- /** An empty deferred value definition corresponding to:
- * val _: _
- * This is used as a placeholder in the `self` parameter Template if there is
- * no definition of a self value of self type.
- */
- def emptyValDef: ValDef
-
- // ------ traversers, copiers, and transformers ---------------------------------------------
-
- val treeCopy = newLazyTreeCopier
-
- 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)
+ /** The API that all idents support */
+ trait IdentApi extends RefTreeApi { this: Ident =>
+ val name: Name
}
- 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)
+
+ override type ReferenceToBoxed >: Null <: TermTree with ReferenceToBoxedApi
+
+ /** The API that all references support */
+ trait ReferenceToBoxedApi extends TermTreeApi { this: ReferenceToBoxed =>
+ val ident: Tree
}
- 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)
+ override type Literal >: Null <: TermTree with LiteralApi
+
+ /** The API that all literals support */
+ trait LiteralApi extends TermTreeApi { this: Literal =>
+ val value: Constant
}
- 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)
+
+ override type Annotated >: Null <: Tree with AnnotatedApi
+
+ /** The API that all annotateds support */
+ trait AnnotatedApi extends TreeApi { this: Annotated =>
+ val annot: Tree
+ val arg: Tree
}
- 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)
+
+ override type SingletonTypeTree >: Null <: TypTree with SingletonTypeTreeApi
+
+ /** The API that all singleton type trees support */
+ trait SingletonTypeTreeApi extends TypTreeApi { this: SingletonTypeTree =>
+ val ref: Tree
}
- 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)
+
+ override type SelectFromTypeTree >: Null <: TypTree with RefTree with SelectFromTypeTreeApi
+
+ /** The API that all selects from type trees support */
+ trait SelectFromTypeTreeApi extends TypTreeApi with RefTreeApi { this: SelectFromTypeTree =>
+ val qualifier: Tree
+ val name: TypeName
}
- 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)
+
+ override type CompoundTypeTree >: Null <: TypTree with CompoundTypeTreeApi
+
+ /** The API that all compound type trees support */
+ trait CompoundTypeTreeApi extends TypTreeApi { this: CompoundTypeTree =>
+ val templ: Template
}
- 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)
+
+ override type AppliedTypeTree >: Null <: TypTree with AppliedTypeTreeApi
+
+ /** The API that all applied type trees support */
+ trait AppliedTypeTreeApi extends TypTreeApi { this: AppliedTypeTree =>
+ val tpt: Tree
+ val args: List[Tree]
}
- 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)
+
+ override type TypeBoundsTree >: Null <: TypTree with TypeBoundsTreeApi
+
+ /** The API that all type bound trees support */
+ trait TypeBoundsTreeApi extends TypTreeApi { this: TypeBoundsTree =>
+ val lo: Tree
+ val hi: Tree
}
- class Traverser {
- protected var currentOwner: Symbol = definitions.RootClass
-
- def traverse(tree: Tree): Unit = tree match {
- case EmptyTree =>
- ;
- case PackageDef(pid, stats) =>
- traverse(pid)
- atOwner(tree.symbol.moduleClass) {
- traverseTrees(stats)
- }
- case ClassDef(mods, name, tparams, impl) =>
- atOwner(tree.symbol) {
- traverseTrees(mods.annotations); traverseTrees(tparams); traverse(impl)
- }
- case ModuleDef(mods, name, impl) =>
- atOwner(tree.symbol.moduleClass) {
- 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(this, tree)
- }
+ override type ExistentialTypeTree >: Null <: TypTree with ExistentialTypeTreeApi
- def traverseTrees(trees: List[Tree]) {
- trees foreach traverse
- }
- def traverseTreess(treess: List[List[Tree]]) {
- treess foreach traverseTrees
- }
- def traverseStats(stats: List[Tree], exprOwner: Symbol) {
- stats foreach (stat =>
- if (exprOwner != currentOwner) atOwner(exprOwner)(traverse(stat))
- else traverse(stat)
- )
- }
+ /** The API that all existential type trees support */
+ trait ExistentialTypeTreeApi extends TypTreeApi { this: ExistentialTypeTree =>
+ val tpt: Tree
+ val whereClauses: List[Tree]
+ }
- def atOwner(owner: Symbol)(traverse: => Unit) {
- val prevOwner = currentOwner
- currentOwner = owner
- traverse
- currentOwner = prevOwner
- }
+ override type TypeTree >: Null <: TypTree with TypeTreeApi
- /** Leave apply available in the generic traverser to do something else.
- */
- def apply[T <: Tree](tree: T): T = { traverse(tree); tree }
+ /** The API that all type trees support */
+ trait TypeTreeApi extends TypTreeApi { this: TypeTree =>
+ def original: Tree
}
- protected def xtraverse(traverser: Traverser, tree: Tree): Unit = throw new MatchError(tree)
+ /** An empty deferred value definition corresponding to:
+ * val _: _
+ * This is used as a placeholder in the `self` parameter Template if there is
+ * no definition of a self value of self type.
+ */
+ val emptyValDef: ValDef
+
+// ---------------------- copying ------------------------------------------------
- // to be implemented in subclasses:
+ /** The standard (lazy) tree copier
+ */
type TreeCopier <: TreeCopierOps
+ val treeCopy: TreeCopier = newLazyTreeCopier
+
def newStrictTreeCopier: TreeCopier
def newLazyTreeCopier: TreeCopier
- trait TreeCopierOps {
+ /** The API of a tree copier
+ * tree copiers are made available by an implicit conversion in reflect.ops
+ */
+ abstract class TreeCopierOps {
def ClassDef(tree: Tree, mods: Modifiers, name: Name, tparams: List[TypeDef], impl: Template): ClassDef
def PackageDef(tree: Tree, pid: RefTree, stats: List[Tree]): PackageDef
def ModuleDef(tree: Tree, mods: Modifiers, name: Name, impl: Template): ModuleDef
@@ -1107,443 +601,49 @@ trait Trees { self: Universe =>
def ExistentialTypeTree(tree: Tree, tpt: Tree, whereClauses: List[Tree]): ExistentialTypeTree
}
- 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) = {
- val t = new Ident(name) copyAttrs tree
- if (tree hasAttachment BackquotedIdentifier) t withAttachment BackquotedIdentifier
- else t
- }
- 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)
- }
+// ---------------------- traversing and transforming ------------------------------
- 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)
+ class Traverser {
+ protected[scala] var currentOwner: Symbol = rootMirror.RootClass
+
+ def traverse(tree: Tree): Unit = itraverse(this, tree)
+
+ def traverseTrees(trees: List[Tree]) {
+ trees foreach traverse
}
- 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 traverseTreess(treess: List[List[Tree]]) {
+ treess foreach traverseTrees
}
- 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 traverseStats(stats: List[Tree], exprOwner: Symbol) {
+ stats foreach (stat =>
+ if (exprOwner != currentOwner) atOwner(exprOwner)(traverse(stat))
+ else traverse(stat)
+ )
}
- 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)
+
+ def atOwner(owner: Symbol)(traverse: => Unit) {
+ val prevOwner = currentOwner
+ currentOwner = owner
+ traverse
+ currentOwner = prevOwner
}
+
+ /** Leave apply available in the generic traverser to do something else.
+ */
+ def apply[T <: Tree](tree: T): T = { traverse(tree); tree }
}
+ protected def itraverse(traverser: Traverser, tree: Tree): Unit = throw new MatchError(tree)
+
+ protected def xtraverse(traverser: Traverser, tree: Tree): Unit = throw new MatchError(tree)
+
abstract class Transformer {
val treeCopy: TreeCopier = newLazyTreeCopier
- protected var currentOwner: Symbol = definitions.RootClass
+ protected[scala] var currentOwner: Symbol = rootMirror.RootClass
protected def currentMethod = currentOwner.enclosingMethod
protected def currentClass = currentOwner.enclosingClass
- protected def currentPackage = currentOwner.enclosingTopLevelClass.owner
- def transform(tree: Tree): Tree = tree match {
- case EmptyTree =>
- tree
- case PackageDef(pid, stats) =>
- treeCopy.PackageDef(
- tree, transform(pid).asInstanceOf[RefTree],
- atOwner(tree.symbol.moduleClass) {
- 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(tree.symbol.moduleClass) {
- 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(this, tree)
- }
+// protected def currentPackage = currentOwner.enclosingTopLevelClass.owner
+ def transform(tree: Tree): Tree = itransform(this, tree)
def transformTrees(trees: List[Tree]): List[Tree] =
trees mapConserve (transform(_))
@@ -1577,154 +677,13 @@ trait Trees { self: Universe =>
}
}
- protected def xtransform(transformer: Transformer, tree: Tree): Tree = throw new MatchError(tree)
-
- class ForeachTreeTraverser(f: Tree => Unit) extends Traverser {
- override def traverse(t: Tree) {
- f(t)
- super.traverse(t)
- }
- }
+ protected def itransform(transformer: Transformer, tree: Tree): Tree = throw new MatchError(tree)
- 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)
- }
- }
+ protected def xtransform(transformer: Transformer, tree: Tree): Tree = throw new MatchError(tree)
- 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)
- }
- }
+ type Modifiers >: Null <: ModifiersApi
- 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)
- }
- }
- }
+ abstract class ModifiersApi extends ModifiersBase with HasFlagsApi
- protected def duplicateTree(tree: Tree): Tree
-
-/* A standard pattern match
- case EmptyTree =>
- case PackageDef(pid, stats) =>
- // package pid { stats }
- case ClassDef(mods, name, tparams, impl) =>
- // mods class name [tparams] impl where impl = extends parents { defs }
- case ModuleDef(mods, name, impl) => (eliminated by refcheck)
- // mods object name impl where impl = extends parents { defs }
- case ValDef(mods, name, tpt, rhs) =>
- // mods val name: tpt = rhs
- // note missing type information is expressed by tpt = TypeTree()
- case DefDef(mods, name, tparams, vparamss, tpt, rhs) =>
- // mods def name[tparams](vparams_1)...(vparams_n): tpt = rhs
- // note missing type information is expressed by tpt = TypeTree()
- case TypeDef(mods, name, tparams, rhs) => (eliminated by erasure)
- // mods type name[tparams] = rhs
- // mods type name[tparams] >: lo <: hi, where lo, hi are in a TypeBoundsTree,
- and DEFERRED is set in mods
- case LabelDef(name, params, rhs) =>
- // used for tailcalls and like
- // while/do are desugared to label defs as follows:
- // while (cond) body ==> LabelDef($L, List(), if (cond) { body; L$() } else ())
- // do body while (cond) ==> LabelDef($L, List(), body; if (cond) L$() else ())
- case Import(expr, selectors) => (eliminated by typecheck)
- // import expr.{selectors}
- // Selectors are a list of pairs of names (from, to).
- // The last (and maybe only name) may be a nme.WILDCARD
- // for instance
- // import qual.{x, y => z, _} would be represented as
- // Import(qual, List(("x", "x"), ("y", "z"), (WILDCARD, null)))
- case Template(parents, self, body) =>
- // extends parents { self => body }
- // if self is missing it is represented as emptyValDef
- case Block(stats, expr) =>
- // { stats; expr }
- case CaseDef(pat, guard, body) => (eliminated by transmatch/explicitouter)
- // case pat if guard => body
- case Alternative(trees) => (eliminated by transmatch/explicitouter)
- // pat1 | ... | patn
- case Star(elem) => (eliminated by transmatch/explicitouter)
- // pat*
- case Bind(name, body) => (eliminated by transmatch/explicitouter)
- // name @ pat
- case UnApply(fun: Tree, args) (introduced by typer, eliminated by transmatch/explicitouter)
- // used for unapply's
- case ArrayValue(elemtpt, trees) => (introduced by uncurry)
- // used to pass arguments to vararg arguments
- // for instance, printf("%s%d", foo, 42) is translated to after uncurry to:
- // Apply(
- // Ident("printf"),
- // Literal("%s%d"),
- // ArrayValue(<Any>, List(Ident("foo"), Literal(42))))
- case Function(vparams, body) => (eliminated by lambdaLift)
- // vparams => body where vparams:List[ValDef]
- case Assign(lhs, rhs) =>
- // lhs = rhs
- case AssignOrNamedArg(lhs, rhs) => (eliminated by typer, resurrected by reifier)
- // @annotation(lhs = rhs)
- case If(cond, thenp, elsep) =>
- // if (cond) thenp else elsep
- case Match(selector, cases) =>
- // selector match { cases }
- case Return(expr) =>
- // return expr
- case Try(block, catches, finalizer) =>
- // try block catch { catches } finally finalizer where catches: List[CaseDef]
- case Throw(expr) =>
- // throw expr
- case New(tpt) =>
- // new tpt always in the context: (new tpt).<init>[targs](args)
- case Typed(expr, tpt) => (eliminated by erasure)
- // expr: tpt
- case TypeApply(fun, args) =>
- // fun[args]
- case Apply(fun, args) =>
- // fun(args)
- // for instance fun[targs](args) is expressed as Apply(TypeApply(fun, targs), args)
- case ApplyDynamic(qual, args) (introduced by erasure, eliminated by cleanup)
- // fun(args)
- case Super(qual, mix) =>
- // qual.super[mix] qual is always This(something), if mix is empty, it is tpnme.EMPTY
- case This(qual) =>
- // qual.this
- case Select(qualifier, selector) =>
- // qualifier.selector
- case Ident(name) =>
- // name
- // note: type checker converts idents that refer to enclosing fields or methods
- // to selects; name ==> this.name
- case ReferenceToBoxed(ident) => (created by typer, eliminated by lambdalift)
- // synthetic node emitted by macros to reference capture vars directly without going through ``elem''
- // var x = ...; fun { x } will emit Ident(x), which gets transformed to Select(Ident(x), "elem")
- // if ReferenceToBoxed were used instead of Ident, no transformation would be performed
- case Literal(value) =>
- // value
- case TypeTree() => (introduced by refcheck)
- // a type that's not written out, but given in the tpe attribute
- case Annotated(annot, arg) => (eliminated by typer)
- // arg @annot for types, arg: @annot for exprs
- case SingletonTypeTree(ref) => (eliminated by uncurry)
- // ref.type
- case SelectFromTypeTree(qualifier, selector) => (eliminated by uncurry)
- // qualifier # selector, a path-dependent type p.T is expressed as p.type # T
- case CompoundTypeTree(templ: Template) => (eliminated by uncurry)
- // parent1 with ... with parentN { refinement }
- case AppliedTypeTree(tpt, args) => (eliminated by uncurry)
- // tpt[args]
- case TypeBoundsTree(lo, hi) => (eliminated by uncurry)
- // >: lo <: hi
- case ExistentialTypeTree(tpt, whereClauses) => (eliminated by uncurry)
- // tpt forSome { whereClauses }
-*/
}
diff --git a/src/library/scala/reflect/api/Types.scala b/src/library/scala/reflect/api/Types.scala
index 3d42242641..b62a92cbd7 100755
--- a/src/library/scala/reflect/api/Types.scala
+++ b/src/library/scala/reflect/api/Types.scala
@@ -1,15 +1,13 @@
package scala.reflect
package api
-trait Types { self: Universe =>
+trait Types extends base.Types { self: Universe =>
- /** This class declares operations that are visible in a Type.
+ override type Type >: Null <: TypeApi
+
+ /** The extended API of types
*/
- abstract class AbsType {
- /** The type symbol associated with the type, or `NoSymbol` for types
- * that do not refer to a type symbol.
- */
- def typeSymbol: Symbol
+ abstract class TypeApi extends TypeBase {
/** The defined or declared members with name `name` in this type;
* an OverloadedSymbol if several exist, NoSymbol if none exist.
@@ -18,6 +16,7 @@ trait Types { self: Universe =>
def declaration(name: Name): Symbol
/** The collection of declarations in this type
+ * [Eugene++] why not List?
*/
def declarations: Iterable[Symbol]
@@ -34,6 +33,7 @@ trait Types { self: Universe =>
/** An iterable containing all members of this type (directly declared or inherited)
* Members appear in the linearization order of their owners.
* Members with the same owner appear in reverse order of their declarations.
+ * [Eugene++] the order needs to be reversed back, at least in the public API
*/
def members: Iterable[Symbol]
@@ -43,6 +43,11 @@ trait Types { self: Universe =>
*/
def nonPrivateMembers: Iterable[Symbol]
+ /** Substitute symbols in `to` for corresponding occurrences of references to
+ * symbols `from` in this type.
+ */
+ def substituteSymbols(from: List[Symbol], to: List[Symbol]): Type
+
/** Substitute types in `to` for corresponding occurrences of references to
* symbols `from` in this type.
*/
@@ -166,304 +171,133 @@ trait Types { self: Universe =>
*/
def widen: Type
- /** The kind of this type; used for debugging */
+ /** The string discriminator of this type; useful for debugging */
def kind: String
}
- /** An object representing an unknown type, used during type inference.
- * If you see WildcardType outside of inference it is almost certainly a bug.
- */
- val WildcardType: Type
-
- /** BoundedWildcardTypes, used only during type inference, are created in
- * two places that I can find:
- *
- * 1. If the expected type of an expression is an existential type,
- * its hidden symbols are replaced with bounded wildcards.
- * 2. When an implicit conversion is being sought based in part on
- * the name of a method in the converted type, a HasMethodMatching
- * type is created: a MethodType with parameters typed as
- * BoundedWildcardTypes.
- */
- type BoundedWildcardType >: Null <: Type
-
- val BoundedWildcardType: BoundedWildcardTypeExtractor
+ /** .. */
+ override type ThisType >: Null <: SingletonType with ThisTypeApi
- abstract class BoundedWildcardTypeExtractor {
- def apply(bounds: TypeBounds): BoundedWildcardType
- def unapply(tpe: BoundedWildcardType): Option[TypeBounds]
+ /** The API that all this types support */
+ trait ThisTypeApi extends TypeApi { this: ThisType =>
+ val sym: Symbol
}
- /** The type of Scala types, and also Scala type signatures.
- * (No difference is internally made between the two).
- */
- type Type >: Null <: AbsType
-
- /** The type of Scala singleton types, i.e. types that are inhabited
- * by only one nun-null value. These include types of the forms
- * {{{
- * C.this.type
- * C.super.type
- * x.type
- * }}}
- * as well as constant types.
- */
- type SingletonType >: Null <: Type
+ /** .. */
+ override type SingleType >: Null <: SingletonType with SingleTypeApi
- /** This constant is used as a special value that indicates that no meaningful type exists.
- */
- val NoType: Type
-
- /** This constant is used as a special value denoting the empty prefix in a path dependent type.
- * For instance `x.type` is represented as `SingleType(NoPrefix, <x>)`, where `<x>` stands for
- * the symbol for `x`.
- */
- val NoPrefix: Type
-
- /** The `ThisType` type describes types of the form on the left with the
- * correspnding ThisType representations to the right.
- * {{{
- * C.this.type ThisType(C)
- * }}}
- */
- type ThisType <: SingletonType
-
- /** The constructor/deconstructor for `ThisType` instances. */
- val ThisType: ThisTypeExtractor
-
- /** An extractor class to create and pattern match with syntax `ThisType(sym)`
- * where `sym` is the class prefix of the this type.
- */
- abstract class ThisTypeExtractor {
- def apply(sym: Symbol): Type
- def unapply(tpe: ThisType): Option[Symbol]
+ /** The API that all single types support */
+ trait SingleTypeApi extends TypeApi { this: SingleType =>
+ val pre: Type
+ val sym: Symbol
}
- /** The `TypeRef` type describes types of any of the forms on the left,
- * with their TypeRef representations to the right.
- * {{{
- * T # C[T_1, ..., T_n] TypeRef(T, C, List(T_1, ..., T_n))
- * p.C[T_1, ..., T_n] TypeRef(p.type, C, List(T_1, ..., T_n))
- * C[T_1, ..., T_n] TypeRef(NoPrefix, C, List(T_1, ..., T_n))
- * T # C TypeRef(T, C, Nil)
- * p.C TypeRef(p.type, C, Nil)
- * C TypeRef(NoPrefix, C, Nil)
- * }}}
- */
- type TypeRef <: Type
+ /** .. */
+ override type SuperType >: Null <: SingletonType with SuperTypeApi
- /** The constructor/deconstructor for `TypeRef` instances. */
- val TypeRef: TypeRefExtractor
-
- /** An extractor class to create and pattern match with syntax `TypeRef(pre, sym, args)`
- * Here, `pre` is the prefix of the type reference, `sym` is the symbol
- * referred to by the type reference, and `args` is a possible empty list of
- * type argumenrts.
- */
- abstract class TypeRefExtractor {
- def apply(pre: Type, sym: Symbol, args: List[Type]): Type
- def unapply(tpe: TypeRef): Option[(Type, Symbol, List[Type])]
+ /** The API that all super types support */
+ trait SuperTypeApi extends TypeApi { this: SuperType =>
+ val thistpe: Type
+ val supertpe: Type
}
- /** The `SingleType` type describes types of any of the forms on the left,
- * with their TypeRef representations to the right.
- * {{{
- * (T # x).type SingleType(T, x)
- * p.x.type SingleType(p.type, x)
- * x.type SingleType(NoPrefix, x)
- * }}}
- */
- type SingleType <: SingletonType
+ /** .. */
+ override type ConstantType >: Null <: SingletonType with ConstantTypeApi
- /** The constructor/deconstructor for `SingleType` instances. */
- val SingleType: SingleTypeExtractor
-
- /** An extractor class to create and pattern match with syntax `SingleType(pre, sym)`
- * Here, `pre` is the prefix of the single-type, and `sym` is the stable value symbol
- * referred to by the single-type.
- */
- abstract class SingleTypeExtractor {
- def apply(pre: Type, sym: Symbol): Type
- def unapply(tpe: SingleType): Option[(Type, Symbol)]
+ /** The API that all constant types support */
+ trait ConstantTypeApi extends TypeApi { this: ConstantType =>
+ val value: Constant
}
- /** The `SuperType` type is not directly written, but arises when `C.super` is used
- * as a prefix in a `TypeRef` or `SingleType`. It's internal presentation is
- * {{{
- * SuperType(thistpe, supertpe)
- * }}}
- * Here, `thistpe` is the type of the corresponding this-type. For instance,
- * in the type arising from C.super, the `thistpe` part would be `ThisType(C)`.
- * `supertpe` is the type of the super class referred to by the `super`.
- */
- type SuperType <: SingletonType
-
- /** The constructor/deconstructor for `SuperType` instances. */
- val SuperType: SuperTypeExtractor
+ /** .. */
+ override type TypeRef >: Null <: Type with TypeRefApi
- /** An extractor class to create and pattern match with syntax `SingleType(thistpe, supertpe)`
- */
- abstract class SuperTypeExtractor {
- def apply(thistpe: Type, supertpe: Type): Type
- def unapply(tpe: SuperType): Option[(Type, Type)]
+ /** The API that all type refs support */
+ trait TypeRefApi extends TypeApi { this: TypeRef =>
+ val pre: Type
+ val sym: Symbol
+ val args: List[Type]
}
- /** The `ConstantType` type is not directly written in user programs, but arises as the type of a constant.
- * The REPL expresses constant types like Int(11). Here are some constants with their types.
- * {{{
- * 1 ConstantType(Constant(1))
- * "abc" ConstantType(Constant("abc"))
- * }}}
- */
- type ConstantType <: SingletonType
-
- /** The constructor/deconstructor for `ConstantType` instances. */
- val ConstantType: ConstantTypeExtractor
+ /** .. */
+ override type RefinedType >: Null <: CompoundType with RefinedTypeApi
- /** An extractor class to create and pattern match with syntax `ConstantType(constant)`
- * Here, `constant` is the constant value represented by the type.
- */
- abstract class ConstantTypeExtractor {
- def apply(value: Constant): ConstantType
- def unapply(tpe: ConstantType): Option[Constant]
+ /** The API that all refined types support */
+ trait RefinedTypeApi extends TypeApi { this: RefinedType =>
+ val parents: List[Type]
+ val decls: Scope
}
- /** A subtype of Type representing refined types as well as `ClassInfo` signatures.
- */
- type CompoundType <: Type
+ /** .. */
+ override type ClassInfoType >: Null <: CompoundType with ClassInfoTypeApi
- /** The `RefinedType` type defines types of any of the forms on the left,
- * with their RefinedType representations to the right.
- * {{{
- * P_1 with ... with P_m { D_1; ...; D_n} RefinedType(List(P_1, ..., P_m), Scope(D_1, ..., D_n))
- * P_1 with ... with P_m RefinedType(List(P_1, ..., P_m), Scope())
- * { D_1; ...; D_n} RefinedType(List(AnyRef), Scope(D_1, ..., D_n))
- * }}}
- */
- type RefinedType <: CompoundType
-
- /** The constructor/deconstructor for `RefinedType` instances. */
- val RefinedType: RefinedTypeExtractor
-
- /** An extractor class to create and pattern match with syntax `RefinedType(parents, decls)`
- * Here, `parents` is the list of parent types of the class, and `decls` is the scope
- * containing all declarations in the class.
- */
- abstract class RefinedTypeExtractor {
- def apply(parents: List[Type], decls: Scope): RefinedType
-
- /** An alternative constructor that passes in the synthetic classs symbol
- * that backs the refined type. (Normally, a fresh class symbol is created automatically).
- */
- def apply(parents: List[Type], decls: Scope, clazz: Symbol): RefinedType
- def unapply(tpe: RefinedType): Option[(List[Type], Scope)]
+ /** The API that all class info types support */
+ trait ClassInfoTypeApi extends TypeApi { this: ClassInfoType =>
+ val parents: List[Type]
+ val decls: Scope
+ val typeSymbol: Symbol
}
- type NullaryMethodType <: Type
- val NullaryMethodType: NullaryMethodTypeExtractor
+ /** .. */
+ override type MethodType >: Null <: Type with MethodTypeApi
- type PolyType <: Type
- val PolyType: PolyTypeExtractor
-
- type ExistentialType <: Type
- val ExistentialType: ExistentialTypeExtractor
+ /** The API that all method types support */
+ trait MethodTypeApi extends TypeApi { this: MethodType =>
+ val params: List[Symbol]
+ val resultType: Type
+ }
- type AnnotatedType <: Type
- val AnnotatedType: AnnotatedTypeExtractor
+ /** .. */
+ override type NullaryMethodType >: Null <: Type with NullaryMethodTypeApi
- /** The `MethodType` type signature is used to indicate parameters and result type of a method
- */
- type MethodType <: Type
+ /** The API that all nullary method types support */
+ trait NullaryMethodTypeApi extends TypeApi { this: NullaryMethodType =>
+ val resultType: Type
+ }
- /** The constructor/deconstructor for `MethodType` instances. */
- val MethodType: MethodTypeExtractor
+ /** .. */
+ override type PolyType >: Null <: Type with PolyTypeApi
- /** An extractor class to create and pattern match with syntax `MethodType(params, respte)`
- * Here, `params` is a potentially empty list of parameter symbols of the method,
- * and `restpe` is the result type of the method. If the method is curried, `restpe` would
- * be another `MethodType`.
- * Note: `MethodType(Nil, Int)` would be the type of a method defined with an empty parameter list.
- * {{{
- * def f(): Int
- * }}}
- * If the method is completely parameterless, as in
- * {{{
- * def f: Int
- * }}}
- * its type is a `NullaryMethodType`.
- */
- abstract class MethodTypeExtractor {
- def apply(params: List[Symbol], resultType: Type): MethodType
- def unapply(tpe: MethodType): Option[(List[Symbol], Type)]
+ /** The API that all polymorphic types support */
+ trait PolyTypeApi extends TypeApi { this: PolyType =>
+ val typeParams: List[Symbol]
+ val resultType: Type
}
- /** The `TypeBounds` type signature is used to indicate lower and upper type bounds
- * of type parameters and abstract types. It is not a first-class type.
- * If an abstract type or type parameter is declared with any of the forms
- * on the left, its type signature is the TypeBounds type on the right.
- * {{{
- * T >: L <: U TypeBounds(L, U)
- * T >: L TypeBounds(L, Any)
- * T <: U TypeBounds(Nothing, U)
- * }}}
- */
- type TypeBounds <: Type
+ /** .. */
+ override type ExistentialType >: Null <: Type with ExistentialTypeApi
- /** The constructor/deconstructor for `TypeBounds` instances. */
- val TypeBounds: TypeBoundsExtractor
-
- /** An extractor class to create and pattern match with syntax `TypeBound(lower, upper)`
- * Here, `lower` is the lower bound of the `TypeBounds` pair, and `upper` is
- * the upper bound.
- */
- abstract class TypeBoundsExtractor {
- def apply(lo: Type, hi: Type): TypeBounds
- def unapply(tpe: TypeBounds): Option[(Type, Type)]
+ /** The API that all existential types support */
+ trait ExistentialTypeApi extends TypeApi { this: ExistentialType =>
+ val quantified: List[Symbol]
+ val underlying: Type
}
- /** The `ClassInfo` type signature is used to define parents and declarations
- * of classes, traits, and objects. If a class, trait, or object C is declared like this
- * {{{
- * C extends P_1 with ... with P_m { D_1; ...; D_n}
- * }}}
- * its `ClassInfo` type has the following form:
- * {{{
- * ClassInfo(List(P_1, ..., P_m), Scope(D_1, ..., D_n), C)
- * }}}
- */
- type ClassInfoType <: CompoundType
+ /** .. */
+ override type AnnotatedType >: Null <: Type with AnnotatedTypeApi
- /** The constructor/deconstructor for `ClassInfoType` instances. */
- val ClassInfoType: ClassInfoTypeExtractor
-
- /** An extractor class to create and pattern match with syntax `ClassInfo(parents, decls, clazz)`
- * Here, `parents` is the list of parent types of the class, `decls` is the scope
- * containing all declarations in the class, and `clazz` is the symbol of the class
- * itself.
- */
- abstract class ClassInfoTypeExtractor {
- def apply(parents: List[Type], decls: Scope, clazz: Symbol): ClassInfoType
- def unapply(tpe: ClassInfoType): Option[(List[Type], Scope, Symbol)]
+ /** The API that all annotated types support */
+ trait AnnotatedTypeApi extends TypeApi { this: AnnotatedType =>
+ val annotations: List[AnnotationInfo]
+ val underlying: Type
+ val selfsym: Symbol
}
- abstract class NullaryMethodTypeExtractor {
- def apply(resultType: Type): NullaryMethodType
- def unapply(tpe: NullaryMethodType): Option[(Type)]
- }
+ /** .. */
+ override type TypeBounds >: Null <: Type with TypeBoundsApi
- abstract class PolyTypeExtractor {
- def apply(typeParams: List[Symbol], resultType: Type): PolyType
- def unapply(tpe: PolyType): Option[(List[Symbol], Type)]
+ /** The API that all type bounds support */
+ trait TypeBoundsApi extends TypeApi { this: TypeBounds =>
+ val lo: Type
+ val hi: Type
}
- abstract class ExistentialTypeExtractor {
- def apply(quantified: List[Symbol], underlying: Type): ExistentialType
- def unapply(tpe: ExistentialType): Option[(List[Symbol], Type)]
- }
+ /** .. */
+ override type BoundedWildcardType >: Null <: Type with BoundedWildcardTypeApi
- abstract class AnnotatedTypeExtractor {
- def apply(annotations: List[AnnotationInfo], underlying: Type, selfsym: Symbol): AnnotatedType
- def unapply(tpe: AnnotatedType): Option[(List[AnnotationInfo], Type, Symbol)]
+ /** The API that all this types support */
+ trait BoundedWildcardTypeApi extends TypeApi { this: BoundedWildcardType =>
+ val bounds: TypeBounds
}
/** The least upper bound of a list of types, as determined by `<:<`. */
diff --git a/src/library/scala/reflect/api/Universe.scala b/src/library/scala/reflect/api/Universe.scala
index ce1b806812..002cd2e673 100755
--- a/src/library/scala/reflect/api/Universe.scala
+++ b/src/library/scala/reflect/api/Universe.scala
@@ -3,25 +3,22 @@ package api
import language.experimental.macros
-abstract class Universe extends Symbols
- with FreeVars
+abstract class Universe extends base.Universe
+ with Symbols
with Types
- with Constants
- with Scopes
+ with FlagSets
with Names
with Trees
- with AnnotationInfos
+ with TreePrinters
+ with Constants
with Positions
- with Exprs
+ with Mirrors
with StandardDefinitions
- with TypeTags
- with TreePrinters
with StandardNames
- with ClassLoaders
- with TreeBuildUtil
- with ToolBoxes
- with FrontEnds
- with Importers {
+ with Importers
+ with Exprs
+ with AnnotationInfos
+{
/** Given an expression, generate a tree that when compiled and executed produces the original tree.
* The produced tree will be bound to the Universe it was called from.
@@ -36,17 +33,17 @@ abstract class Universe extends Symbols
*
* {{{
* <[
- * val $mr: scala.reflect.api.Universe = <reference to the Universe that calls the reify>
- * $mr.Expr[Int]($mr.Apply($mr.Select($mr.Ident($mr.newFreeVar("x", <Int>, x), "+"), List($mr.Literal($mr.Constant(1))))))
+ * val $u: u.type = u // where u is a reference to the Universe that calls the reify
+ * $u.Expr[Int]($u.Apply($u.Select($u.Ident($u.newFreeVar("x", <Int>, x), "+"), List($u.Literal($u.Constant(1))))))
* ]>
* }}}
*
- * Reification performs expression splicing (when processing Expr.eval and Expr.value)
+ * Reification performs expression splicing (when processing Expr.splice)
* and type splicing (for every type T that has a TypeTag[T] implicit in scope):
*
* {{{
- * val two = mirror.reify(2) // Literal(Constant(2))
- * val four = mirror.reify(two.eval + two.eval) // Apply(Select(two.tree, newTermName("$plus")), List(two.tree))
+ * val two = mirror.reify(2) // Literal(Constant(2))
+ * val four = mirror.reify(two.splice + two.splice) // Apply(Select(two.tree, newTermName("$plus")), List(two.tree))
*
* def macroImpl[T](c: Context) = {
* ...
diff --git a/src/library/scala/reflect/api/package.scala b/src/library/scala/reflect/api/package.scala
new file mode 100644
index 0000000000..d2fce7cf1d
--- /dev/null
+++ b/src/library/scala/reflect/api/package.scala
@@ -0,0 +1,12 @@
+package scala.reflect
+
+package object api {
+
+ // type and value aliases for slices of the base Universe cake that are not
+ // repeated in api.Universe
+ type Scopes = base.Scopes
+ type BuildUtils = base.BuildUtils
+ type Attachments = base.Attachments
+
+ type MirrorOf[U <: base.Universe with Singleton] = base.MirrorOf[U]
+}
diff --git a/src/library/scala/reflect/base/AnnotationInfos.scala b/src/library/scala/reflect/base/AnnotationInfos.scala
new file mode 100644
index 0000000000..f03644deef
--- /dev/null
+++ b/src/library/scala/reflect/base/AnnotationInfos.scala
@@ -0,0 +1,44 @@
+package scala.reflect
+package base
+
+trait AnnotationInfos { self: Universe =>
+
+ type AnnotationInfo >: Null <: AnyRef
+ implicit val AnnotationInfoTag: ClassTag[AnnotationInfo]
+ val AnnotationInfo: AnnotationInfoExtractor
+
+ abstract class AnnotationInfoExtractor {
+ def apply(atp: Type, args: List[Tree], assocs: List[(Name, ClassfileAnnotArg)]): AnnotationInfo
+ def unapply(info: AnnotationInfo): Option[(Type, List[Tree], List[(Name, ClassfileAnnotArg)])]
+ }
+
+ type ClassfileAnnotArg >: Null <: AnyRef
+ implicit val ClassfileAnnotArgTag: ClassTag[ClassfileAnnotArg]
+
+ type LiteralAnnotArg >: Null <: AnyRef with ClassfileAnnotArg
+ implicit val LiteralAnnotArgTag: ClassTag[LiteralAnnotArg]
+ val LiteralAnnotArg: LiteralAnnotArgExtractor
+
+ abstract class LiteralAnnotArgExtractor {
+ def apply(const: Constant): LiteralAnnotArg
+ def unapply(arg: LiteralAnnotArg): Option[Constant]
+ }
+
+ type ArrayAnnotArg >: Null <: AnyRef with ClassfileAnnotArg
+ implicit val ArrayAnnotArgTag: ClassTag[ArrayAnnotArg]
+ val ArrayAnnotArg: ArrayAnnotArgExtractor
+
+ abstract class ArrayAnnotArgExtractor {
+ def apply(args: Array[ClassfileAnnotArg]): ArrayAnnotArg
+ def unapply(arg: ArrayAnnotArg): Option[Array[ClassfileAnnotArg]]
+ }
+
+ type NestedAnnotArg >: Null <: AnyRef with ClassfileAnnotArg
+ implicit val NestedAnnotArgTag: ClassTag[NestedAnnotArg]
+ val NestedAnnotArg: NestedAnnotArgExtractor
+
+ abstract class NestedAnnotArgExtractor {
+ def apply(annInfo: AnnotationInfo): NestedAnnotArg
+ def unapply(arg: NestedAnnotArg): Option[AnnotationInfo]
+ }
+} \ No newline at end of file
diff --git a/src/library/scala/reflect/base/Attachments.scala b/src/library/scala/reflect/base/Attachments.scala
new file mode 100644
index 0000000000..76606ca958
--- /dev/null
+++ b/src/library/scala/reflect/base/Attachments.scala
@@ -0,0 +1,42 @@
+package scala.reflect
+package base
+
+/** Attachments is a generalisation of Position.
+ * Typically it stores a Position of a tree, but this can be extended to encompass arbitrary payloads.
+ *
+ * Attachments have to carry positions, because we don't want to introduce even a single additional field in Tree
+ * imposing an unnecessary memory tax because of something that will not be used in most cases.
+ */
+abstract class Attachments { self =>
+
+ type Pos >: Null
+
+ /** Gets the underlying position */
+ def pos: Pos
+
+ /** Creates a copy of this attachment with its position updated */
+ def withPos(newPos: Pos): Attachments { type Pos = self.Pos }
+
+ /** Gets the underlying payload */
+ def all: Set[Any] = Set.empty
+
+ def get[T: ClassTag]: Option[T] =
+ (all find (_.getClass == classTag[T].erasure)).asInstanceOf[Option[T]]
+
+ /** Creates a copy of this attachment with its payload updated */
+ def add(attachment: Any): Attachments { type Pos = self.Pos } =
+ new NonemptyAttachments(this.pos, all + attachment)
+
+ def remove[T: ClassTag]: Attachments { type Pos = self.Pos } = {
+ val newAll = all filterNot (_.getClass == classTag[T].erasure)
+ if (newAll.isEmpty) pos.asInstanceOf[Attachments { type Pos = self.Pos }]
+ else new NonemptyAttachments(this.pos, newAll)
+ }
+
+ private class NonemptyAttachments(override val pos: Pos, override val all: Set[Any]) extends Attachments {
+ type Pos = self.Pos
+ def withPos(newPos: Pos) = new NonemptyAttachments(newPos, all)
+ }
+}
+
+
diff --git a/src/library/scala/reflect/base/Base.scala b/src/library/scala/reflect/base/Base.scala
new file mode 100644
index 0000000000..461eaa2e9e
--- /dev/null
+++ b/src/library/scala/reflect/base/Base.scala
@@ -0,0 +1,763 @@
+package scala.reflect
+package base
+
+import language.experimental.macros
+import java.io.PrintWriter
+import scala.annotation.switch
+import scala.ref.WeakReference
+import collection.mutable
+
+class Base extends Universe { self =>
+
+ private var nextId = 0
+
+ abstract class Symbol(val name: Name, val flags: FlagSet) extends SymbolBase {
+ val id = { nextId += 1; nextId }
+ def owner: Symbol
+ def fullName: String =
+ if (isEffectiveRoot || owner.isEffectiveRoot) name.toString else owner.fullName + "." + name
+ private def isEffectiveRoot =
+ this == NoSymbol || this == rootMirror.RootClass || this == rootMirror.EmptyPackageClass
+
+ def newTermSymbol(name: TermName, pos: Position = NoPosition, flags: FlagSet = NoFlags): TermSymbol =
+ new TermSymbol(this, name, flags)
+
+ def newModuleAndClassSymbol(name: Name, pos: Position = NoPosition, flags: FlagSet = NoFlags): (ModuleSymbol, ClassSymbol) = {
+ val c = newClassSymbol(name.toTypeName, pos, flags)
+ val m = new ModuleSymbol(this, name.toTermName, flags, c)
+ (m, c)
+ }
+
+ def newMethodSymbol(name: TermName, pos: Position = NoPosition, flags: FlagSet = NoFlags): MethodSymbol
+ = new MethodSymbol(this, name, flags)
+
+ def newTypeSymbol(name: TypeName, pos: Position = NoPosition, flags: FlagSet = NoFlags): TypeSymbol =
+ new TypeSymbol(this, name, flags)
+
+ def newClassSymbol(name: TypeName, pos: Position = NoPosition, flags: FlagSet = NoFlags): ClassSymbol =
+ new ClassSymbol(this, name, flags)
+
+ def newFreeTermSymbol(name: TermName, info: Type, value: => Any, flags: FlagSet = NoFlags, origin: String = null) =
+ new FreeTermSymbol(this, name, flags)
+
+ def newFreeTypeSymbol(name: TypeName, info: Type, value: => Any, flags: FlagSet = NoFlags, origin: String = null) =
+ new FreeTypeSymbol(this, name, flags)
+
+ private def kindString: String =
+ if (isModule) "module"
+ else if (isClass) "class"
+ else if (isFreeType) "free type"
+ else if (isType) "type"
+ else if (isMethod) "method"
+ else if (isFreeTerm) "free term"
+ else if (isTerm) "value"
+ else "symbol"
+ // [Eugene++ to Martin] base names should expose `decode`
+ override def toString() = s"$kindString $name"
+ }
+ implicit val SymbolTag = ClassTag[Symbol](classOf[Symbol])
+
+ class TermSymbol(val owner: Symbol, override val name: TermName, flags: FlagSet)
+ extends Symbol(name, flags) with TermSymbolBase
+ implicit val TermSymbolTag = ClassTag[TermSymbol](classOf[TermSymbol])
+
+ class TypeSymbol(val owner: Symbol, override val name: TypeName, flags: FlagSet)
+ extends Symbol(name, flags) with TypeSymbolBase {
+ override val asTypeConstructor = TypeRef(ThisType(owner), this, Nil)
+ }
+ implicit val TypeSymbolTag = ClassTag[TypeSymbol](classOf[TypeSymbol])
+
+ class MethodSymbol(owner: Symbol, name: TermName, flags: FlagSet)
+ extends TermSymbol(owner, name, flags) with MethodSymbolBase
+ implicit val MethodSymbolTag = ClassTag[MethodSymbol](classOf[MethodSymbol])
+
+ class ModuleSymbol(owner: Symbol, name: TermName, flags: FlagSet, override val moduleClass: Symbol)
+ extends TermSymbol(owner, name, flags) with ModuleSymbolBase
+ implicit val ModuleSymbolTag = ClassTag[ModuleSymbol](classOf[ModuleSymbol])
+
+ class ClassSymbol(owner: Symbol, name: TypeName, flags: FlagSet)
+ extends TypeSymbol(owner, name, flags) with ClassSymbolBase
+ implicit val ClassSymbolTag = ClassTag[ClassSymbol](classOf[ClassSymbol])
+
+ class FreeTermSymbol(owner: Symbol, name: TermName, flags: FlagSet)
+ extends TermSymbol(owner, name, flags) with FreeTermSymbolBase
+ implicit val FreeTermSymbolTag = ClassTag[FreeTermSymbol](classOf[FreeTermSymbol])
+
+ class FreeTypeSymbol(owner: Symbol, name: TypeName, flags: FlagSet)
+ extends TypeSymbol(owner, name, flags) with FreeTypeSymbolBase
+ implicit val FreeTypeSymbolTag = ClassTag[FreeTypeSymbol](classOf[FreeTypeSymbol])
+
+
+ object NoSymbol extends Symbol(nme.NO_NAME, NoFlags) {
+ override def owner = throw new UnsupportedOperationException("NoSymbol.owner")
+ }
+
+ // todo. write a decent toString that doesn't crash on recursive types
+ class Type extends TypeBase { def typeSymbol: Symbol = NoSymbol }
+ implicit val TypeTagg = ClassTag[Type](classOf[Type])
+
+ val NoType = new Type
+ val NoPrefix = new Type
+
+ class SingletonType extends Type
+ implicit val SingletonTypeTag = ClassTag[SingletonType](classOf[SingletonType])
+
+ case class ThisType(sym: Symbol) extends SingletonType { override val typeSymbol = sym }
+ object ThisType extends ThisTypeExtractor
+ implicit val ThisTypeTag = ClassTag[ThisType](classOf[ThisType])
+
+ case class SingleType(pre: Type, sym: Symbol) extends SingletonType
+ object SingleType extends SingleTypeExtractor
+ implicit val SingleTypeTag = ClassTag[SingleType](classOf[SingleType])
+
+ case class SuperType(thistpe: Type, supertpe: Type) extends SingletonType
+ object SuperType extends SuperTypeExtractor
+ implicit val SuperTypeTag = ClassTag[SuperType](classOf[SuperType])
+
+ case class ConstantType(value: Constant) extends SingletonType
+ object ConstantType extends ConstantTypeExtractor
+ implicit val ConstantTypeTag = ClassTag[ConstantType](classOf[ConstantType])
+
+ case class TypeRef(pre: Type, sym: Symbol, args: List[Type]) extends Type { override val typeSymbol = sym }
+ object TypeRef extends TypeRefExtractor
+ implicit val TypeRefTag = ClassTag[TypeRef](classOf[TypeRef])
+
+ abstract class CompoundType extends Type
+ implicit val CompoundTypeTag = ClassTag[CompoundType](classOf[CompoundType])
+
+ case class RefinedType(parents: List[Type], decls: Scope) extends CompoundType
+ object RefinedType extends RefinedTypeExtractor {
+ def apply(parents: List[Type], decls: Scope, clazz: Symbol): RefinedType =
+ RefinedType(parents, decls)
+ }
+ implicit val RefinedTypeTag = ClassTag[RefinedType](classOf[RefinedType])
+
+ case class ClassInfoType(parents: List[Type], decls: Scope, override val typeSymbol: Symbol) extends CompoundType
+ object ClassInfoType extends ClassInfoTypeExtractor
+ implicit val ClassInfoTypeTag = ClassTag[ClassInfoType](classOf[ClassInfoType])
+
+ case class MethodType(params: List[Symbol], resultType: Type) extends Type
+ object MethodType extends MethodTypeExtractor
+ implicit val MethodTypeTag = ClassTag[MethodType](classOf[MethodType])
+
+ case class NullaryMethodType(resultType: Type) extends Type
+ object NullaryMethodType extends NullaryMethodTypeExtractor
+ implicit val NullaryMethodTypeTag = ClassTag[NullaryMethodType](classOf[NullaryMethodType])
+
+ case class PolyType(typeParams: List[Symbol], resultType: Type) extends Type
+ object PolyType extends PolyTypeExtractor
+ implicit val PolyTypeTag = ClassTag[PolyType](classOf[PolyType])
+
+ case class ExistentialType(quantified: List[Symbol], underlying: Type) extends Type { override def typeSymbol = underlying.typeSymbol }
+ object ExistentialType extends ExistentialTypeExtractor
+ implicit val ExistentialTypeTag = ClassTag[ExistentialType](classOf[ExistentialType])
+
+ case class AnnotatedType(annotations: List[AnnotationInfo], underlying: Type, selfsym: Symbol) extends Type { override def typeSymbol = underlying.typeSymbol }
+ object AnnotatedType extends AnnotatedTypeExtractor
+ implicit val AnnotatedTypeTag = ClassTag[AnnotatedType](classOf[AnnotatedType])
+
+ case class TypeBounds(lo: Type, hi: Type) extends Type
+ object TypeBounds extends TypeBoundsExtractor
+ implicit val TypeBoundsTag = ClassTag[TypeBounds](classOf[TypeBounds])
+
+ val WildcardType = new Type
+
+ case class BoundedWildcardType(bounds: TypeBounds) extends Type
+ object BoundedWildcardType extends BoundedWildcardTypeExtractor
+ implicit val BoundedWildcardTypeTag = ClassTag[BoundedWildcardType](classOf[BoundedWildcardType])
+
+ type Scope = Iterable[Symbol]
+ implicit val ScopeTag = ClassTag[Scope](classOf[Scope])
+
+ def newScope = newScopeWith()
+ def newNestedScope(outer: Iterable[Symbol]) = newScope
+ def newScopeWith(elems: Symbol*): Scope = elems
+
+ abstract class Name(str: String) extends NameBase {
+ override def toString = str
+ }
+ implicit val NameTag = ClassTag[Name](classOf[Name])
+
+ class TermName(str: String) extends Name(str) {
+ def isTermName = true
+ def isTypeName = false
+ def toTermName = this
+ def toTypeName = new TypeName(str)
+ }
+ implicit val TermNameTag = ClassTag[TermName](classOf[TermName])
+
+ class TypeName(str: String) extends Name(str) {
+ def isTermName = false
+ def isTypeName = true
+ def toTermName = new TermName(str)
+ def toTypeName = this
+ }
+ implicit val TypeNameTag = ClassTag[TypeName](classOf[TypeName])
+
+ def newTermName(str: String) = new TermName(str)
+ def newTypeName(str: String) = new TypeName(str)
+
+ object nme extends TermNamesBase {
+ type NameType = TermName
+ val EMPTY = newTermName("")
+ val ROOT = newTermName("<root>")
+ val EMPTY_PACKAGE_NAME = newTermName("<empty>")
+ val CONSTRUCTOR = newTermName("<init>")
+ val NO_NAME = newTermName("<none>")
+ val WILDCARD = newTermName("_")
+ }
+
+ object tpnme extends TypeNamesBase {
+ type NameType = TypeName
+ val EMPTY = nme.EMPTY.toTypeName
+ val ROOT = nme.ROOT.toTypeName
+ val EMPTY_PACKAGE_NAME = nme.EMPTY_PACKAGE_NAME.toTypeName
+ val WILDCARD = nme.WILDCARD.toTypeName
+ }
+
+ type FlagSet = Long
+ val NoFlags = 0L
+ implicit val FlagSetTag = ClassTag[FlagSet](classOf[FlagSet])
+
+ class Modifiers(override val flags: FlagSet,
+ override val privateWithin: Name,
+ override val annotations: List[Tree]) extends ModifiersBase {
+ def hasFlag(flags: FlagSet) = (this.flags & flags) != 0
+ def hasAllFlags(flags: FlagSet) = (flags & ~this.flags) == 0
+ }
+
+ implicit val ModifiersTag = ClassTag[Modifiers](classOf[Modifiers])
+
+ object Modifiers extends ModifiersCreator {
+ def apply(flags: Long,
+ privateWithin: Name,
+ annotations: List[Tree]) = new Modifiers(flags, privateWithin, annotations)
+ }
+
+ case class Constant(value: Any)
+ object Constant extends ConstantExtractor
+ implicit val ConstantTag = ClassTag[Constant](classOf[Constant])
+
+ case class AnnotationInfo(atp: Type, args: List[Tree], assocs: List[(Name, ClassfileAnnotArg)])
+ object AnnotationInfo extends AnnotationInfoExtractor
+ implicit val AnnotationInfoTag = ClassTag[AnnotationInfo](classOf[AnnotationInfo])
+
+ abstract class ClassfileAnnotArg
+ implicit val ClassfileAnnotArgTag = ClassTag[ClassfileAnnotArg](classOf[ClassfileAnnotArg])
+
+ case class LiteralAnnotArg(const: Constant) extends ClassfileAnnotArg
+ object LiteralAnnotArg extends LiteralAnnotArgExtractor
+ implicit val LiteralAnnotArgTag = ClassTag[LiteralAnnotArg](classOf[LiteralAnnotArg])
+
+ case class ArrayAnnotArg(args: Array[ClassfileAnnotArg]) extends ClassfileAnnotArg
+ object ArrayAnnotArg extends ArrayAnnotArgExtractor
+ implicit val ArrayAnnotArgTag = ClassTag[ArrayAnnotArg](classOf[ArrayAnnotArg])
+
+ case class NestedAnnotArg(annInfo: AnnotationInfo) extends ClassfileAnnotArg
+ object NestedAnnotArg extends NestedAnnotArgExtractor
+ implicit val NestedAnnotArgTag = ClassTag[NestedAnnotArg](classOf[NestedAnnotArg])
+
+ class Position extends Attachments {
+ override type Pos = Position
+ def pos = this
+ def withPos(newPos: Position) = newPos
+ def isRange = false
+ def focus = this
+ }
+ implicit val PositionTag = ClassTag[Position](classOf[Position])
+
+ val NoPosition = new Position
+
+ def atPos[T <: Tree](pos: Position)(tree: T): T = tree
+
+ private val generated = new mutable.HashMap[String, WeakReference[Symbol]]
+
+ private def cached(name: String)(symExpr: => Symbol): Symbol =
+ generated get name match {
+ case Some(WeakReference(sym)) =>
+ sym
+ case _ =>
+ val sym = symExpr
+ generated(name) = WeakReference(sym)
+ sym
+ }
+
+ object build extends BuildBase {
+ def selectType(owner: Symbol, name: String): TypeSymbol = {
+ val clazz = new ClassSymbol(owner, newTypeName(name), NoFlags)
+ cached(clazz.fullName)(clazz).asTypeSymbol
+ }
+
+ def selectTerm(owner: Symbol, name: String): TermSymbol = {
+ val valu = new MethodSymbol(owner, newTermName(name), NoFlags)
+ cached(valu.fullName)(valu).asTermSymbol
+ }
+
+ def selectOverloadedMethod(owner: Symbol, name: String, index: Int): MethodSymbol =
+ selectTerm(owner, name).asMethodSymbol
+
+ def newNestedSymbol(owner: Symbol, name: Name, pos: Position, flags: Long, isClass: Boolean): Symbol =
+ if (name.isTypeName)
+ if (isClass) new ClassSymbol(owner, name.toTypeName, flags)
+ else new TypeSymbol(owner, name.toTypeName, flags)
+ else new TermSymbol(owner, name.toTermName, flags)
+
+ def newFreeTerm(name: String, info: Type, value: => Any, flags: Long = 0L, origin: String = null): FreeTermSymbol =
+ new FreeTermSymbol(rootMirror.RootClass, newTermName(name), flags)
+
+ def newFreeType(name: String, info: Type, value: => Any, flags: Long = 0L, origin: String = null): FreeTypeSymbol =
+ new FreeTypeSymbol(rootMirror.RootClass, newTypeName(name), flags)
+
+ def newFreeExistential(name: String, info: Type, value: => Any, flags: Long = 0L, origin: String = null): FreeTypeSymbol =
+ new FreeTypeSymbol(rootMirror.RootClass, newTypeName(name), flags)
+
+ def setTypeSignature[S <: Symbol](sym: S, tpe: Type): S = sym
+
+ def setAnnotations[S <: Symbol](sym: S, annots: List[AnnotationInfo]): S = sym
+
+ def flagsFromBits(bits: Long): FlagSet = bits
+
+ object emptyValDef extends ValDef(NoMods, nme.WILDCARD, TypeTree(NoType), EmptyTree) {
+ override def isEmpty = true
+ }
+
+ def This(sym: Symbol): Tree = self.This(sym.name.toTypeName)
+
+ def Select(qualifier: Tree, sym: Symbol): Select = self.Select(qualifier, sym.name)
+
+ def Ident(sym: Symbol): Ident = self.Ident(sym.name)
+
+ def TypeTree(tp: Type): TypeTree = self.TypeTree()
+
+ def thisPrefix(sym: Symbol): Type = SingleType(NoPrefix, sym)
+
+ def setType[T <: Tree](tree: T, tpe: Type): T = tree
+
+ def setSymbol[T <: Tree](tree: T, sym: Symbol): T = tree
+ }
+
+ import build._
+
+ class Mirror extends MirrorOf[self.type] {
+ val universe: self.type = self
+
+ lazy val RootClass = new ClassSymbol(NoSymbol, tpnme.ROOT, NoFlags)
+ lazy val RootPackage = new ModuleSymbol(NoSymbol, nme.ROOT, NoFlags, RootClass)
+ lazy val EmptyPackageClass = new ClassSymbol(RootClass, tpnme.EMPTY_PACKAGE_NAME, NoFlags)
+ lazy val EmptyPackage = new ModuleSymbol(RootClass, nme.EMPTY_PACKAGE_NAME, NoFlags, EmptyPackageClass)
+
+ def staticClass(fullName: String): ClassSymbol =
+ mkStatic[ClassSymbol](fullName)
+
+ def staticModule(fullName: String): ModuleSymbol =
+ mkStatic[ModuleSymbol](fullName)
+
+ private def mkStatic[S <: Symbol : ClassTag](fullName: String): S =
+ cached(fullName) {
+ val point = fullName lastIndexOf '.'
+ val owner =
+ if (point > 0) staticModule(fullName take point).moduleClass
+ else rootMirror.RootClass
+ val name = fullName drop point + 1
+ val symtag = implicitly[ClassTag[S]]
+ if (symtag == ClassSymbolTag) new ClassSymbol(owner, newTypeName(name), NoFlags)
+ else owner.newModuleAndClassSymbol(newTermName(name))._1
+ }.asInstanceOf[S]
+ }
+
+ lazy val rootMirror = new Mirror
+
+ import rootMirror._
+
+ object definitions extends DefinitionsBase {
+ lazy val ScalaPackage = staticModule("scala")
+ lazy val ScalaPackageClass = ScalaPackage.moduleClass.asClassSymbol
+
+ lazy val AnyClass = staticClass("scala.Any")
+ lazy val AnyValClass = staticClass("scala.Any")
+ lazy val ObjectClass = staticClass("java.lang.Object")
+ lazy val AnyRefClass = ObjectClass
+
+ lazy val NullClass = staticClass("scala.Null")
+ lazy val NothingClass = staticClass("scala.Nothing")
+
+ lazy val UnitClass = staticClass("scala.Unit")
+ lazy val ByteClass = staticClass("scala.Byte")
+ lazy val ShortClass = staticClass("scala.Short")
+ lazy val CharClass = staticClass("scala.Char")
+ lazy val IntClass = staticClass("scala.Int")
+ lazy val LongClass = staticClass("scala.Long")
+ lazy val FloatClass = staticClass("scala.Float")
+ lazy val DoubleClass = staticClass("scala.Double")
+ lazy val BooleanClass = staticClass("scala.Boolean")
+
+ lazy val StringClass = staticClass("java.lang.String")
+ lazy val ClassClass = staticClass("java.lang.Class")
+ lazy val ArrayClass = staticClass("scala.Array")
+ lazy val ListClass = staticClass("scala.List")
+
+ lazy val PredefModule = staticModule("scala.Predef")
+ }
+
+ import definitions._
+
+ private def thisModuleType(fullName: String): Type = ThisType(staticModule(fullName).moduleClass)
+ private lazy val ScalaPrefix = thisModuleType("scala")
+ private lazy val JavaLangPrefix = thisModuleType("java.lang")
+
+ lazy val ByteTpe = TypeRef(ScalaPrefix, ByteClass, Nil)
+ lazy val ShortTpe = TypeRef(ScalaPrefix, ShortClass, Nil)
+ lazy val CharTpe = TypeRef(ScalaPrefix, CharClass, Nil)
+ lazy val IntTpe = TypeRef(ScalaPrefix, IntClass, Nil)
+ lazy val LongTpe = TypeRef(ScalaPrefix, LongClass, Nil)
+ lazy val FloatTpe = TypeRef(ScalaPrefix, FloatClass, Nil)
+ lazy val DoubleTpe = TypeRef(ScalaPrefix, DoubleClass, Nil)
+ lazy val BooleanTpe = TypeRef(ScalaPrefix, BooleanClass, Nil)
+ lazy val UnitTpe = TypeRef(ScalaPrefix, UnitClass, Nil)
+ lazy val AnyTpe = TypeRef(ScalaPrefix, AnyClass, Nil)
+ lazy val AnyValTpe = TypeRef(ScalaPrefix, AnyValClass, Nil)
+ lazy val NothingTpe = TypeRef(ScalaPrefix, NothingClass, Nil)
+ lazy val NullTpe = TypeRef(ScalaPrefix, NullClass, Nil)
+ lazy val ObjectTpe = TypeRef(JavaLangPrefix, ObjectClass, Nil)
+ lazy val AnyRefTpe = ObjectTpe
+ lazy val StringTpe = TypeRef(JavaLangPrefix, StringClass, Nil)
+
+ private var nodeCount = 0 // not synchronized
+
+ abstract class Tree extends TreeBase with Product {
+ def isDef: Boolean = false
+ def isEmpty: Boolean = 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
+ }
+ }
+
+ def show(tree: Tree) = s"<tree ${tree.getClass}>"
+
+ trait TermTree extends Tree
+
+ trait TypTree extends Tree
+
+ trait SymTree extends Tree
+
+ trait NameTree extends Tree {
+ def name: Name
+ }
+
+ trait RefTree extends SymTree with NameTree {
+ def qualifier: Tree // empty for Idents
+ def name: Name
+ }
+
+ abstract class DefTree extends SymTree with NameTree {
+ def name: Name
+ override def isDef = true
+ }
+
+ case object EmptyTree extends TermTree {
+ override def isEmpty = true
+ }
+
+ abstract class MemberDef extends DefTree {
+ def mods: Modifiers
+ }
+
+ case class PackageDef(pid: RefTree, stats: List[Tree])
+ extends MemberDef {
+ def name = pid.name
+ def mods = NoMods
+ }
+ object PackageDef extends PackageDefExtractor
+
+ abstract class ImplDef extends MemberDef {
+ def impl: Template
+ }
+
+ case class ClassDef(mods: Modifiers, name: TypeName, tparams: List[TypeDef], impl: Template)
+ extends ImplDef
+ object ClassDef extends ClassDefExtractor
+
+ case class ModuleDef(mods: Modifiers, name: TermName, impl: Template)
+ extends ImplDef
+ object ModuleDef extends ModuleDefExtractor
+
+ abstract class ValOrDefDef extends MemberDef {
+ val name: Name
+ val tpt: Tree
+ val rhs: Tree
+ }
+
+ case class ValDef(mods: Modifiers, name: TermName, tpt: Tree, rhs: Tree) extends ValOrDefDef
+ object ValDef extends ValDefExtractor
+
+ case class DefDef(mods: Modifiers, name: Name, tparams: List[TypeDef],
+ vparamss: List[List[ValDef]], tpt: Tree, rhs: Tree) extends ValOrDefDef
+ object DefDef extends DefDefExtractor
+
+ case class TypeDef(mods: Modifiers, name: TypeName, tparams: List[TypeDef], rhs: Tree)
+ extends MemberDef
+ object TypeDef extends TypeDefExtractor
+
+ case class LabelDef(name: TermName, params: List[Ident], rhs: Tree)
+ extends DefTree with TermTree
+ object LabelDef extends LabelDefExtractor
+
+ case class ImportSelector(name: Name, namePos: Int, rename: Name, renamePos: Int)
+ object ImportSelector extends ImportSelectorExtractor
+
+ case class Import(expr: Tree, selectors: List[ImportSelector])
+ extends SymTree
+ object Import extends ImportExtractor
+
+ case class Template(parents: List[Tree], self: ValDef, body: List[Tree])
+ extends SymTree
+ object Template extends TemplateExtractor
+
+ case class Block(stats: List[Tree], expr: Tree)
+ extends TermTree
+ object Block extends BlockExtractor
+
+ case class CaseDef(pat: Tree, guard: Tree, body: Tree)
+ extends Tree
+ object CaseDef extends CaseDefExtractor
+
+ case class Alternative(trees: List[Tree])
+ extends TermTree
+ object Alternative extends AlternativeExtractor
+
+ case class Star(elem: Tree)
+ extends TermTree
+ object Star extends StarExtractor
+
+ case class Bind(name: Name, body: Tree)
+ extends DefTree
+ object Bind extends BindExtractor
+
+ case class UnApply(fun: Tree, args: List[Tree])
+ extends TermTree
+ object UnApply extends UnApplyExtractor
+
+ case class ArrayValue(elemtpt: Tree, elems: List[Tree])
+ extends TermTree
+ object ArrayValue extends ArrayValueExtractor
+
+ case class Function(vparams: List[ValDef], body: Tree)
+ extends TermTree with SymTree
+ object Function extends FunctionExtractor
+
+ case class Assign(lhs: Tree, rhs: Tree)
+ extends TermTree
+ object Assign extends AssignExtractor
+
+ case class AssignOrNamedArg(lhs: Tree, rhs: Tree)
+ extends TermTree
+ object AssignOrNamedArg extends AssignOrNamedArgExtractor
+
+ case class If(cond: Tree, thenp: Tree, elsep: Tree)
+ extends TermTree
+ object If extends IfExtractor
+
+ case class Match(selector: Tree, cases: List[CaseDef])
+ extends TermTree
+ object Match extends MatchExtractor
+
+ case class Return(expr: Tree)
+ extends TermTree with SymTree
+ object Return extends ReturnExtractor
+
+ case class Try(block: Tree, catches: List[CaseDef], finalizer: Tree)
+ extends TermTree
+ object Try extends TryExtractor
+
+ case class Throw(expr: Tree)
+ extends TermTree
+ object Throw extends ThrowExtractor
+
+ case class New(tpt: Tree) extends TermTree
+ object New extends NewExtractor
+
+ case class Typed(expr: Tree, tpt: Tree)
+ extends TermTree
+ object Typed extends TypedExtractor
+
+ abstract class GenericApply extends TermTree {
+ val fun: Tree
+ val args: List[Tree]
+ }
+
+ case class TypeApply(fun: Tree, args: List[Tree])
+ extends GenericApply
+ object TypeApply extends TypeApplyExtractor
+
+ case class Apply(fun: Tree, args: List[Tree])
+ extends GenericApply
+ object Apply extends ApplyExtractor
+
+ case class ApplyDynamic(qual: Tree, args: List[Tree])
+ extends TermTree with SymTree
+ object ApplyDynamic extends ApplyDynamicExtractor
+
+ case class Super(qual: Tree, mix: TypeName) extends TermTree
+ object Super extends SuperExtractor
+
+ case class This(qual: TypeName)
+ extends TermTree with SymTree
+ object This extends ThisExtractor
+
+ case class Select(qualifier: Tree, name: Name)
+ extends RefTree
+ object Select extends SelectExtractor
+
+ case class Ident(name: Name) extends RefTree {
+ def qualifier: Tree = EmptyTree
+ }
+ object Ident extends IdentExtractor
+
+ case class ReferenceToBoxed(ident: Ident) extends TermTree
+ object ReferenceToBoxed extends ReferenceToBoxedExtractor
+
+ case class Literal(value: Constant)
+ extends TermTree {
+ assert(value ne null)
+ }
+ object Literal extends LiteralExtractor
+
+ case class Annotated(annot: Tree, arg: Tree) extends Tree
+ object Annotated extends AnnotatedExtractor
+
+ case class SingletonTypeTree(ref: Tree)
+ extends TypTree
+ object SingletonTypeTree extends SingletonTypeTreeExtractor
+
+ case class SelectFromTypeTree(qualifier: Tree, name: TypeName)
+ extends TypTree with RefTree
+ object SelectFromTypeTree extends SelectFromTypeTreeExtractor
+
+ case class CompoundTypeTree(templ: Template)
+ extends TypTree
+ object CompoundTypeTree extends CompoundTypeTreeExtractor
+
+ case class AppliedTypeTree(tpt: Tree, args: List[Tree])
+ extends TypTree
+ object AppliedTypeTree extends AppliedTypeTreeExtractor
+
+ case class TypeBoundsTree(lo: Tree, hi: Tree)
+ extends TypTree
+ object TypeBoundsTree extends TypeBoundsTreeExtractor
+
+ case class ExistentialTypeTree(tpt: Tree, whereClauses: List[Tree])
+ extends TypTree
+ object ExistentialTypeTree extends ExistentialTypeTreeExtractor
+
+ case class TypeTree() extends TypTree {
+ val original: Tree = null
+ override def isEmpty = true
+ }
+ object TypeTree extends TypeTreeExtractor
+
+ 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])
+
+ // [Eugene++] to be removed after SI-5863 is fixed
+ def ClassDef(sym: Symbol, impl: Template): ClassDef = ???
+ def ModuleDef(sym: Symbol, impl: Template): ModuleDef = ???
+ def ValDef(sym: Symbol, rhs: Tree): ValDef = ???
+ def ValDef(sym: Symbol): ValDef = ???
+ def DefDef(sym: Symbol, mods: Modifiers, vparamss: List[List[ValDef]], rhs: Tree): DefDef = ???
+ def DefDef(sym: Symbol, vparamss: List[List[ValDef]], rhs: Tree): DefDef = ???
+ def DefDef(sym: Symbol, mods: Modifiers, rhs: Tree): DefDef = ???
+ def DefDef(sym: Symbol, rhs: Tree): DefDef = ???
+ def DefDef(sym: Symbol, rhs: List[List[Symbol]] => Tree): DefDef = ???
+ def TypeDef(sym: Symbol, rhs: Tree): TypeDef = ???
+ def TypeDef(sym: Symbol): TypeDef = ???
+ def LabelDef(sym: Symbol, params: List[Symbol], rhs: Tree): LabelDef = ???
+ def CaseDef(pat: Tree, body: Tree): CaseDef = ???
+ def Bind(sym: Symbol, body: Tree): Bind = ???
+ def Try(body: Tree, cases: (Tree, Tree)*): Try = ???
+ def Throw(tpe: Type, args: Tree*): Throw = ???
+ def Apply(sym: Symbol, args: Tree*): Tree = ???
+ def New(tpt: Tree, argss: List[List[Tree]]): Tree = ???
+ def New(tpe: Type, args: Tree*): Tree = ???
+ def New(sym: Symbol, args: Tree*): Tree = ???
+ def ApplyConstructor(tpt: Tree, args: List[Tree]): Tree = ???
+ def Super(sym: Symbol, mix: TypeName): Tree = ???
+ def This(sym: Symbol): Tree = ???
+ def Select(qualifier: Tree, name: String): Select = ???
+ def Select(qualifier: Tree, sym: Symbol): Select = ???
+ def Ident(name: String): Ident = ???
+ def Ident(sym: Symbol): Ident = ???
+ def Block(stats: Tree*): Block = ???
+ def TypeTree(tp: Type): TypeTree = ???
+}
diff --git a/src/library/scala/reflect/base/BuildUtils.scala b/src/library/scala/reflect/base/BuildUtils.scala
new file mode 100644
index 0000000000..eaba0ec2b7
--- /dev/null
+++ b/src/library/scala/reflect/base/BuildUtils.scala
@@ -0,0 +1,90 @@
+package scala.reflect
+package base
+
+trait BuildUtils { self: Universe =>
+
+ val build: BuildBase
+
+ abstract class BuildBase {
+ /** Selects type symbol with given simple name `name` from the defined members of `owner`.
+ */
+ def selectType(owner: Symbol, name: String): TypeSymbol
+
+ /** Selects term symbol with given name and type from the defined members of prefix type
+ */
+ def selectTerm(owner: Symbol, name: String): TermSymbol
+
+ /** Selects overloaded method symbol with given name and index
+ */
+ def selectOverloadedMethod(owner: Symbol, name: String, index: Int): MethodSymbol
+
+ /** A fresh symbol with given name `name`, position `pos` and flags `flags` that has
+ * the current symbol as its owner.
+ */
+ def newNestedSymbol(owner: Symbol, name: Name, pos: Position, flags: FlagSet, isClass: Boolean): Symbol
+
+ /** Create a fresh free term symbol.
+ * @param name the name of the free variable
+ * @param info the type signature of the free variable
+ * @param value the value of the free variable at runtime
+ * @param flags (optional) flags of the free variable
+ * @param origin debug information that tells where this symbol comes from
+ */
+ def newFreeTerm(name: String, info: Type, value: => Any, flags: FlagSet = NoFlags, origin: String = null): FreeTermSymbol
+
+ /** Create a fresh free non-existential type symbol.
+ * @param name the name of the free variable
+ * @param info the type signature of the free variable
+ * @param value a type tag that captures the value of the free variable
+ * is completely phantom, since the captured type cannot be propagated to the runtime
+ * if it could be, we wouldn't be creating a free type to begin with
+ * the only usage for it is preserving the captured symbol for compile-time analysis
+ * @param flags (optional) flags of the free variable
+ * @param origin debug information that tells where this symbol comes from
+ */
+ def newFreeType(name: String, info: Type, value: => Any, flags: FlagSet = NoFlags, origin: String = null): FreeTypeSymbol
+
+ /** Create a fresh free existential type symbol.
+ * @param name the name of the free variable
+ * @param info the type signature of the free variable
+ * @param value a type tag that captures the value of the free variable
+ * is completely phantom, since the captured type cannot be propagated to the runtime
+ * if it could be, we wouldn't be creating a free type to begin with
+ * the only usage for it is preserving the captured symbol for compile-time analysis
+ * @param flags (optional) flags of the free variable
+ * @param origin (optional) debug information that tells where this symbol comes from
+ * [Martin to Eugene: why needed?]
+ */
+ def newFreeExistential(name: String, info: Type, value: => Any, flags: FlagSet = NoFlags, origin: String = null): FreeTypeSymbol
+
+ /** Set symbol's type signature to given type.
+ * @return the symbol itself
+ */
+ def setTypeSignature[S <: Symbol](sym: S, tpe: Type): S
+
+ /** Set symbol's annotations to given annotations `annots`.
+ */
+ def setAnnotations[S <: Symbol](sym: S, annots: List[AnnotationInfo]): S
+
+ def flagsFromBits(bits: Long): FlagSet
+
+ // [Eugene++ to Martin] these are necessary for reification
+ // on a second thought, I added them to BuildUtils instead of base
+
+ def emptyValDef: ValDef
+
+ def This(sym: Symbol): Tree
+
+ def Select(qualifier: Tree, sym: Symbol): Select
+
+ def Ident(sym: Symbol): Ident
+
+ def TypeTree(tp: Type): TypeTree
+
+ def thisPrefix(sym: Symbol): Type
+
+ def setType[T <: Tree](tree: T, tpe: Type): T
+
+ def setSymbol[T <: Tree](tree: T, sym: Symbol): T
+ }
+}
diff --git a/src/library/scala/reflect/base/Constants.scala b/src/library/scala/reflect/base/Constants.scala
new file mode 100644
index 0000000000..8f98e85ad0
--- /dev/null
+++ b/src/library/scala/reflect/base/Constants.scala
@@ -0,0 +1,20 @@
+/* NSC -- new Scala compiler
+ * Copyright 2005-2011 LAMP/EPFL
+ * @author Martin Odersky
+ */
+
+package scala.reflect
+package base
+
+trait Constants {
+ self: Universe =>
+
+ type Constant >: Null <: AnyRef
+ implicit val ConstantTag: ClassTag[Constant]
+ val Constant: ConstantExtractor
+
+ abstract class ConstantExtractor {
+ def apply(value: Any): Constant
+ def unapply(arg: Constant): Option[Any]
+ }
+}
diff --git a/src/library/scala/reflect/base/FlagSets.scala b/src/library/scala/reflect/base/FlagSets.scala
new file mode 100644
index 0000000000..57946d0f27
--- /dev/null
+++ b/src/library/scala/reflect/base/FlagSets.scala
@@ -0,0 +1,17 @@
+package scala.reflect
+package base
+
+trait FlagSets { self: Universe =>
+
+ /** An abstract type representing sets of flags that apply to definition trees and symbols */
+ type FlagSet
+
+ /** A tag that preserves the identity of the `FlagSet` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val FlagSetTag: ClassTag[FlagSet]
+
+ /** The empty set of flags */
+ val NoFlags: FlagSet
+}
+
diff --git a/src/library/scala/reflect/base/MirrorOf.scala b/src/library/scala/reflect/base/MirrorOf.scala
new file mode 100644
index 0000000000..03e035cd81
--- /dev/null
+++ b/src/library/scala/reflect/base/MirrorOf.scala
@@ -0,0 +1,25 @@
+package scala.reflect
+package base
+
+// [Eugene++ to Martin] why was this a member of `scala.reflect`, but not `scala.reflect.base`?
+
+abstract class MirrorOf[U <: base.Universe with Singleton] {
+ /** .. */
+ val universe: U
+
+ /** .. */
+ def RootClass: U#ClassSymbol
+ def RootPackage: U#ModuleSymbol
+ def EmptyPackageClass: U#ClassSymbol
+ def EmptyPackage: U#ModuleSymbol
+
+ /** The symbol corresponding to the globally accessible class with the
+ * given fully qualified name `fullName`.
+ */
+ def staticClass(fullName: String): U#ClassSymbol
+
+ /** The symbol corresponding to the globally accessible object with the
+ * given fully qualified name `fullName`.
+ */
+ def staticModule(fullName: String): U#ModuleSymbol
+}
diff --git a/src/library/scala/reflect/base/Mirrors.scala b/src/library/scala/reflect/base/Mirrors.scala
new file mode 100644
index 0000000000..50866ef000
--- /dev/null
+++ b/src/library/scala/reflect/base/Mirrors.scala
@@ -0,0 +1,12 @@
+package scala.reflect
+package base
+
+trait Mirrors {
+ self: Universe =>
+
+ /** .. */
+ type Mirror >: Null <: MirrorOf[self.type]
+
+ /** .. */
+ val rootMirror: Mirror
+}
diff --git a/src/library/scala/reflect/base/Names.scala b/src/library/scala/reflect/base/Names.scala
new file mode 100644
index 0000000000..edf2ba7dc9
--- /dev/null
+++ b/src/library/scala/reflect/base/Names.scala
@@ -0,0 +1,53 @@
+package scala.reflect
+package base
+
+/** A trait that manages names.
+ * A name is a string in one of two name universes: terms and types.
+ * The same string can be a name in both universes.
+ * Two names are equal if they represent the same string and they are
+ * members of the same universe.
+ *
+ * Names are interned. That is, for two names `name11 and `name2`,
+ * `name1 == name2` implies `name1 eq name2`.
+ */
+trait Names {
+
+ /** The abstract type of names */
+ type Name >: Null <: NameBase
+ implicit val NameTag: ClassTag[Name]
+
+ /** The abstract type of names representing terms */
+ type TypeName >: Null <: Name
+ implicit val TypeNameTag: ClassTag[TypeName]
+
+ /** The abstract type of names representing types */
+ type TermName >: Null <: Name
+ implicit val TermNameTag: ClassTag[TermName]
+
+ /** The base API that all names support */
+ abstract class NameBase {
+ /** Is this name a term name? */
+ def isTermName: Boolean
+
+ /** Is this name a type name? */
+ def isTypeName: Boolean
+
+ /** Returns a term name that represents the same string as this name */
+ def toTermName: TermName
+
+ /** Returns a type name that represents the same string as this name */
+ def toTypeName: TypeName
+ }
+
+ /** Create a new term name.
+ */
+ def newTermName(s: String): TermName
+
+ /** Creates a new type name.
+ */
+ def newTypeName(s: String): TypeName
+
+ def EmptyTermName: TermName = newTermName("")
+
+ def EmptyTypeName: TypeName = EmptyTermName.toTypeName
+}
diff --git a/src/library/scala/reflect/base/Positions.scala b/src/library/scala/reflect/base/Positions.scala
new file mode 100644
index 0000000000..cefeb51c9a
--- /dev/null
+++ b/src/library/scala/reflect/base/Positions.scala
@@ -0,0 +1,22 @@
+package scala.reflect
+package base
+
+trait Positions {
+ self: Universe =>
+
+ /** .. */
+ type Position >: Null <: Attachments { type Pos = Position }
+
+ /** A tag that preserves the identity of the `FlagSet` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val PositionTag: ClassTag[Position]
+
+ /** .. */
+ val NoPosition: Position
+
+ /** Assigns a given position to all position-less nodes of a given AST.
+ */
+ def atPos[T <: Tree](pos: Position)(tree: T): T
+ // [Eugene++] why do we have this in base?
+}
diff --git a/src/library/scala/reflect/api/Scopes.scala b/src/library/scala/reflect/base/Scopes.scala
index 4a5702eadc..a5db01c0ce 100755..100644
--- a/src/library/scala/reflect/api/Scopes.scala
+++ b/src/library/scala/reflect/base/Scopes.scala
@@ -1,9 +1,14 @@
package scala.reflect
-package api
+package base
trait Scopes { self: Universe =>
- type Scope <: Iterable[Symbol]
+ type Scope >: Null <: Iterable[Symbol]
+
+ /** A tag that preserves the identity of the `Scope` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val ScopeTag: ClassTag[Scope]
/** Create a new scope */
def newScope: Scope
diff --git a/src/library/scala/reflect/base/StandardDefinitions.scala b/src/library/scala/reflect/base/StandardDefinitions.scala
new file mode 100644
index 0000000000..eff23b539e
--- /dev/null
+++ b/src/library/scala/reflect/base/StandardDefinitions.scala
@@ -0,0 +1,75 @@
+/* NSC -- new Scala compiler
+ * Copyright 2005-2011 LAMP/EPFL
+ * @author Martin Odersky
+ */
+
+package scala.reflect
+package base
+
+// [Eugene++] not sure whether we need this in the top level of the universe
+trait StandardTypes {
+ self: Universe =>
+
+ val ByteTpe: Type
+ val ShortTpe: Type
+ val CharTpe: Type
+ val IntTpe: Type
+ val LongTpe: Type
+ val FloatTpe: Type
+ val DoubleTpe: Type
+ val BooleanTpe: Type
+ val UnitTpe: Type
+
+ val AnyTpe: Type
+ val AnyValTpe: Type
+ val AnyRefTpe: Type
+ val ObjectTpe: Type
+
+ val NothingTpe: Type
+ val NullTpe: Type
+ val StringTpe: Type
+}
+
+trait StandardDefinitions extends StandardTypes {
+ self: Universe =>
+
+ val definitions: DefinitionsBase
+
+ // [Eugene] todo. shortcut to these fields if possible when generating tags
+ // todo. also shortcut to StandardTypes, of course
+ trait DefinitionsBase {
+ // packages
+ def ScalaPackageClass: ClassSymbol
+ def ScalaPackage: ModuleSymbol
+
+ // top types
+ def AnyClass : ClassSymbol
+ def AnyValClass: ClassSymbol
+ def ObjectClass: ClassSymbol
+ def AnyRefClass: TypeSymbol
+
+ // bottom types
+ def NullClass : ClassSymbol
+ def NothingClass: ClassSymbol
+
+ // the scala value classes
+ def UnitClass : ClassSymbol
+ def ByteClass : ClassSymbol
+ def ShortClass : ClassSymbol
+ def CharClass : ClassSymbol
+ def IntClass : ClassSymbol
+ def LongClass : ClassSymbol
+ def FloatClass : ClassSymbol
+ def DoubleClass : ClassSymbol
+ def BooleanClass: ClassSymbol
+
+ // some special classes
+ def StringClass : ClassSymbol
+ def ClassClass : ClassSymbol
+ def ArrayClass : ClassSymbol
+ def ListClass : ClassSymbol // [Eugene] I'd say List has earned its right to be here
+
+ // the Predef object
+ def PredefModule: ModuleSymbol
+ }
+}
diff --git a/src/library/scala/reflect/base/StandardNames.scala b/src/library/scala/reflect/base/StandardNames.scala
new file mode 100644
index 0000000000..8a3fbe9683
--- /dev/null
+++ b/src/library/scala/reflect/base/StandardNames.scala
@@ -0,0 +1,29 @@
+/* NSC -- new Scala compiler
+* Copyright 2005-2011 LAMP/EPFL
+* @author Martin Odersky
+*/
+
+package scala.reflect
+package base
+
+trait StandardNames {
+ self: Universe =>
+
+ val nme: TermNamesBase
+ val tpnme: TypeNamesBase
+
+ trait NamesBase {
+ type NameType >: Null <: Name
+ val EMPTY: NameType
+ val ROOT: NameType
+ val EMPTY_PACKAGE_NAME: NameType
+ val WILDCARD: NameType
+ }
+
+ trait TypeNamesBase extends NamesBase
+
+ trait TermNamesBase extends NamesBase {
+ val CONSTRUCTOR: TermName
+ val NO_NAME: NameType
+ }
+}
diff --git a/src/library/scala/reflect/base/Symbols.scala b/src/library/scala/reflect/base/Symbols.scala
new file mode 100644
index 0000000000..9404520073
--- /dev/null
+++ b/src/library/scala/reflect/base/Symbols.scala
@@ -0,0 +1,272 @@
+package scala.reflect
+package base
+
+trait Symbols { self: Universe =>
+
+ // [Eugene++ to Martin] why is Symbol >: Null, whereas all other symbol types are not nullable?
+ // same question goes for Types
+
+ /** The abstract type of symbols representing declarations */
+ type Symbol >: Null <: SymbolBase
+
+ /** A tag that preserves the identity of the `Symbol` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val SymbolTag: ClassTag[Symbol]
+
+ /** The abstract type of type symbols representing type, class, and trait declarations,
+ * as well as type parameters
+ */
+ type TypeSymbol >: Null <: Symbol with TypeSymbolBase
+
+ /** A tag that preserves the identity of the `TypeSymbol` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val TypeSymbolTag: ClassTag[TypeSymbol]
+
+ /** The abstract type of term symbols representing val, var, def, and object declarations as
+ * well as packages and value parameters.
+ */
+ type TermSymbol >: Null <: Symbol with TermSymbolBase
+
+ /** A tag that preserves the identity of the `TermSymbol` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val TermSymbolTag: ClassTag[TermSymbol]
+
+ /** The abstract type of method symbols representing def declarations */
+ type MethodSymbol >: Null <: TermSymbol with MethodSymbolBase
+
+ /** A tag that preserves the identity of the `MethodSymbol` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val MethodSymbolTag: ClassTag[MethodSymbol]
+
+ /** The abstract type of module symbols representing object declarations */
+ type ModuleSymbol >: Null <: TermSymbol with ModuleSymbolBase
+
+ /** A tag that preserves the identity of the `ModuleSymbol` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val ModuleSymbolTag: ClassTag[ModuleSymbol]
+
+ /** The abstract type of class symbols representing class and trait definitions */
+ type ClassSymbol >: Null <: TypeSymbol with ClassSymbolBase
+
+ /** A tag that preserves the identity of the `ClassSymbol` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val ClassSymbolTag: ClassTag[ClassSymbol]
+
+ /** The abstract type of free terms introduced by reification */
+ type FreeTermSymbol >: Null <: TermSymbol with FreeTermSymbolBase
+
+ /** A tag that preserves the identity of the `FreeTermSymbol` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val FreeTermSymbolTag: ClassTag[FreeTermSymbol]
+
+ /** The abstract type of free types introduced by reification */
+ type FreeTypeSymbol >: Null <: TypeSymbol with FreeTypeSymbolBase
+
+ /** A tag that preserves the identity of the `FreeTypeSymbol` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val FreeTypeSymbolTag: ClassTag[FreeTypeSymbol]
+
+ /** A special "missing" symbol */
+ val NoSymbol: Symbol
+
+ /** The base API that all symbols support */
+ trait SymbolBase { this: Symbol =>
+
+ /** An id number which is unique for all symbols in this universe */
+ // [Eugene++ to Martin] do we leave this here?
+ def id: Int
+
+ /** The owner of this symbol. This is the symbol
+ * that directly contains the current symbol's definition.
+ * The `NoSymbol` symbol does not have an owner, and calling this method
+ * on one causes an internal error.
+ * The owner of the Scala root class [[scala.reflect.api.mirror.RootClass]]
+ * and the Scala root object [[scala.reflect.api.mirror.RootPackage]] is `NoSymbol`.
+ * Every other symbol has a chain of owners that ends in
+ * [[scala.reflect.api.mirror.RootClass]].
+ */
+ def owner: Symbol
+
+ /** The type of the symbol name.
+ * Can be either `TermName` or `TypeName` depending on whether this is a `TermSymbol` or a `TypeSymbol`.
+ *
+ * Type name namespaces do not intersect with term name namespaces.
+ * This fact is reflected in different types for names of `TermSymbol` and `TypeSymbol`.
+ */
+ type NameType >: Null <: Name
+
+ /** The name of the symbol as a member of the `Name` type.
+ */
+ def name: Name
+
+ /** The encoded full path name of this symbol, where outer names and inner names
+ * are separated by periods.
+ */
+ def fullName: String
+
+ /** If this symbol is a class, this symbol; otherwise the next enclosing
+ * class, or `NoSymbol` if none exists.
+ */
+ def enclosingClass: Symbol =
+ if (isClass || this == NoSymbol) this else owner.enclosingClass
+
+ /** If this symbol is a method, this symbol; otherwise the next enclosing
+ * method, or `NoSymbol` if none exists.
+ */
+ def enclosingMethod: Symbol =
+ if (isMethod || this == NoSymbol) this else owner.enclosingMethod
+
+ /** Does this symbol represent the definition of a type?
+ * Note that every symbol is either a term or a type.
+ * So for every symbol `sym`, either `sym.isTerm` is true
+ * or `sym.isType` is true.
+ */
+ def isType: Boolean = false
+
+ /** This symbol cast to a TypeSymbol.
+ * Returns ClassCastException if `isType` is false.
+ */
+ def asTypeSymbol: TypeSymbol = throw new ClassCastException(toString)
+
+ /** Does this symbol represent the definition of a term?
+ * Note that every symbol is either a term or a term.
+ * So for every symbol `sym`, either `sym.isTerm` is true
+ * or `sym.isTerm` is true.
+ */
+ def isTerm: Boolean = false
+
+ /** This symbol cast to a TermSymbol.
+ * Returns ClassCastException if `isTerm` is false.
+ */
+ def asTermSymbol: TermSymbol = throw new ClassCastException(toString)
+
+ /** Does this symbol represent the definition of a method?
+ * If yes, `isTerm` is also guaranteed to be true.
+ */
+ def isMethod: Boolean = false
+
+ /** This symbol cast to a MethodSymbol.
+ * Returns ClassCastException if `isMethod` is false.
+ */
+ def asMethodSymbol: MethodSymbol = throw new ClassCastException(toString)
+
+ /** Does this symbol represent the definition of a module (i.e. it
+ * results from an object definition?).
+ * If yes, `isTerm` is also guaranteed to be true.
+ */
+ def isModule: Boolean = false
+
+ /** This symbol cast to a ModuleSymbol defined by an object definition.
+ * Returns ClassCastException if `isModule` is false.
+ */
+ def asModuleSymbol: ModuleSymbol = throw new ClassCastException(toString)
+
+ /** Does this symbol represent the definition of a class or trait?
+ * If yes, `isType` is also guaranteed to be true.
+ */
+ def isClass: Boolean = false
+
+ /** This symbol cast to a ClassSymbol representing a class or trait.
+ * Returns ClassCastException if `isClass` is false.
+ */
+ def asClassSymbol: ClassSymbol = throw new ClassCastException(toString)
+
+ /** Does this symbol represent a free term captured by reification?
+ * If yes, `isTerm` is also guaranteed to be true.
+ */
+ def isFreeTerm: Boolean = false
+
+ /** This symbol cast to a free term symbol.
+ * Returns ClassCastException if `isFreeTerm` is false.
+ */
+ def asFreeTermSymbol: FreeTermSymbol = throw new ClassCastException(toString)
+
+ /** Does this symbol represent a free type captured by reification?
+ * If yes, `isType` is also guaranteed to be true.
+ */
+ def isFreeType: Boolean = false
+
+ /** This symbol cast to a free type symbol.
+ * Returns ClassCastException if `isFreeType` is false.
+ */
+ def asFreeTypeSymbol: FreeTypeSymbol = throw new ClassCastException(toString)
+
+ def newTermSymbol(name: TermName, pos: Position = NoPosition, flags: FlagSet = NoFlags): TermSymbol
+ def newModuleAndClassSymbol(name: Name, pos: Position = NoPosition, flags: FlagSet = NoFlags): (ModuleSymbol, ClassSymbol)
+ def newMethodSymbol(name: TermName, pos: Position = NoPosition, flags: FlagSet = NoFlags): MethodSymbol
+ def newTypeSymbol(name: TypeName, pos: Position = NoPosition, flags: FlagSet = NoFlags): TypeSymbol
+ def newClassSymbol(name: TypeName, pos: Position = NoPosition, flags: FlagSet = NoFlags): ClassSymbol
+ }
+
+ /** The base API that all type symbols support */
+ trait TypeSymbolBase extends SymbolBase { this: TypeSymbol =>
+ /** Type symbols have their names of type `TypeName`.
+ */
+ final type NameType = TypeName
+
+ /** The type constructor corresponding to this type symbol.
+ * This is different from `asType` in that type parameters
+ * are part of results of `asType`, but not of `asTypeConstructor`.
+ *
+ * Example: Given a class declaration `class C[T] { ... } `, that generates a symbol
+ * `C`. Then `C.asType` is the type `C[T]`, but `C.asTypeConstructor` is `C`.
+ */
+ def asTypeConstructor: Type
+
+ override def isType = true
+ override def asTypeSymbol = this
+ }
+
+ /** The base API that all term symbols support */
+ trait TermSymbolBase extends SymbolBase { this: TermSymbol =>
+ /** Term symbols have their names of type `TermName`.
+ */
+ final type NameType = TermName
+
+ final override def isTerm = true
+ final override def asTermSymbol = this
+ }
+
+ /** The base API that all method symbols support */
+ trait MethodSymbolBase extends TermSymbolBase { this: MethodSymbol =>
+ final override def isMethod = true
+ final override def asMethodSymbol = this
+ }
+
+ /** The base API that all module symbols support */
+ trait ModuleSymbolBase extends TermSymbolBase { this: ModuleSymbol =>
+ /** The class implicitly associated with the object definition.
+ */
+ def moduleClass: Symbol // needed for tree traversals
+ // [Eugene++] when this becomes `moduleClass: ClassSymbol`, it will be the happiest day in my life
+
+ final override def isModule = true
+ final override def asModuleSymbol = this
+ }
+
+ /** The base API that all class symbols support */
+ trait ClassSymbolBase extends TypeSymbolBase { this: ClassSymbol =>
+ final override def isClass = true
+ final override def asClassSymbol = this
+ }
+
+ /** The base API that all free type symbols support */
+ trait FreeTypeSymbolBase extends TypeSymbolBase { this: FreeTypeSymbol =>
+ final override def isFreeType = true
+ final override def asFreeTypeSymbol = this
+ }
+
+ /** The base API that all free term symbols support */
+ trait FreeTermSymbolBase extends TermSymbolBase { this: FreeTermSymbol =>
+ final override def isFreeTerm = true
+ final override def asFreeTermSymbol = this
+ }
+}
diff --git a/src/library/scala/reflect/base/TagInterop.scala b/src/library/scala/reflect/base/TagInterop.scala
new file mode 100644
index 0000000000..0ec4d06a6c
--- /dev/null
+++ b/src/library/scala/reflect/base/TagInterop.scala
@@ -0,0 +1,29 @@
+package scala.reflect
+package base
+
+import scala.runtime.ScalaRunTime._
+
+trait TagInterop { self: Universe =>
+ def arrayTagToClassManifest[T](tag: ArrayTag[T]): ClassManifest[T] = {
+ val erasure = arrayElementClass(tag)
+ if (erasure.isArray) {
+ val elementClass = arrayElementClass(erasure)
+ val elementManifest = arrayTagToClassManifest(ClassTag(elementClass))
+ ClassManifest.arrayType(elementManifest).asInstanceOf[ClassManifest[T]]
+ } else {
+ ClassManifest.fromClass(erasure.asInstanceOf[Class[T]])
+ }
+ }
+
+ // [Eugene++] `mirror` parameters are now of type `Any`, because I can't make these path-dependent types work
+ // if you're brave enough, replace `Any` with `Mirror`, recompile and run interop_concretetypetags_are_manifests.scala
+
+ // [Eugene++] would be great if we could approximate the interop without any mirrors
+ // todo. think how to implement that
+
+ def concreteTypeTagToManifest[T: ClassTag](mirror: Any, tag: base.Universe # ConcreteTypeTag[T]): Manifest[T] =
+ throw new UnsupportedOperationException("This universe does not support tag -> manifest conversions. Use scala.reflect.runtime.universe from scala-reflect.jar.")
+
+ def manifestToConcreteTypeTag[T](mirror: Any, manifest: Manifest[T]): base.Universe # ConcreteTypeTag[T] =
+ throw new UnsupportedOperationException("This universe does not support manifest -> tag conversions. Use scala.reflect.runtime.universe from scala-reflect.jar.")
+}
diff --git a/src/library/scala/reflect/base/TreeCreator.scala b/src/library/scala/reflect/base/TreeCreator.scala
new file mode 100644
index 0000000000..c9c8de2307
--- /dev/null
+++ b/src/library/scala/reflect/base/TreeCreator.scala
@@ -0,0 +1,6 @@
+package scala.reflect
+package base
+
+abstract class TreeCreator {
+ def apply[U <: Universe with Singleton](m: MirrorOf[U]): U # Tree
+}
diff --git a/src/library/scala/reflect/base/Trees.scala b/src/library/scala/reflect/base/Trees.scala
new file mode 100644
index 0000000000..298d229570
--- /dev/null
+++ b/src/library/scala/reflect/base/Trees.scala
@@ -0,0 +1,1459 @@
+/* NSC -- new Scala compiler
+ * Copyright 2005-2011 LAMP/EPFL
+ * @author Martin Odersky
+ */
+package scala.reflect
+package base
+
+// [Eugene++] of all reflection APIs, this one is in the biggest need of review and documentation
+
+// Syncnote: Trees are currently not thread-safe.
+// [Eugene++] now when trees are finally abstract types, can we do something for this?
+trait Trees { self: Universe =>
+
+ /** The base API that all trees support */
+ abstract class TreeBase extends Product { this: Tree =>
+ /** ... */
+ def isDef: Boolean
+
+ /** ... */
+ def isEmpty: Boolean
+
+ /** The canonical way to test if a Tree represents a term.
+ */
+ def isTerm: Boolean
+
+ /** The canonical way to test if a Tree represents a type.
+ */
+ def isType: Boolean
+
+ /** Obtains string representation of a tree */
+ override def toString: String = show(this)
+ }
+
+ /** Obtains string representation of a tree */
+ def show(tree: Tree): String
+
+ /** Tree is the basis for scala's abstract syntax. The nodes are
+ * implemented as case classes, and the parameters which initialize
+ * a given tree are immutable: however Trees have several mutable
+ * fields which are manipulated in the course of typechecking,
+ * including pos, symbol, and tpe.
+ *
+ * Newly instantiated trees have tpe set to null (though it
+ * may be set immediately thereafter depending on how it is
+ * constructed.) When a tree is passed to the typer, typically via
+ * `typer.typed(tree)`, under normal circumstances the tpe must be
+ * null or the typer will ignore it. Furthermore, the typer is not
+ * required to return the same tree it was passed.
+ *
+ * Trees can be easily traversed with e.g. foreach on the root node;
+ * for a more nuanced traversal, subclass Traverser. Transformations
+ * can be considerably trickier: see the numerous subclasses of
+ * Transformer found around the compiler.
+ *
+ * Copying Trees should be done with care depending on whether
+ * it need be done lazily or strictly (see LazyTreeCopier and
+ * StrictTreeCopier) and on whether the contents of the mutable
+ * fields should be copied. The tree copiers will copy the mutable
+ * attributes to the new tree; calling Tree#duplicate will copy
+ * symbol and tpe, but all the positions will be focused.
+ *
+ * Trees can be coarsely divided into four mutually exclusive categories:
+ *
+ * - TermTrees, representing terms
+ * - TypTrees, representing types. Note that is `TypTree`, not `TypeTree`.
+ * - SymTrees, which may represent types or terms.
+ * - Other Trees, which have none of those as parents.
+ *
+ * SymTrees include important nodes Ident and Select, which are
+ * used as both terms and types; they are distinguishable based on
+ * whether the Name is a TermName or TypeName. The correct way for
+ * to test for a type or a term (on any Tree) are the isTerm/isType
+ * methods on Tree.
+ *
+ * "Others" are mostly syntactic or short-lived constructs. Examples
+ * include CaseDef, which wraps individual match cases: they are
+ * neither terms nor types, nor do they carry a symbol. Another
+ * example is Parens, which is eliminated during parsing.
+ */
+ type Tree >: Null <: TreeBase
+ // [Eugene++] todo. discuss nullability of abstract types
+
+ /** A tag that preserves the identity of the `Tree` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val TreeTag: ClassTag[Tree]
+
+ /** The empty tree */
+ val EmptyTree: Tree
+
+ /** A tree for a term. Not all terms are TermTrees; use isTerm
+ * to reliably identify terms.
+ */
+ type TermTree >: Null <: AnyRef with Tree
+
+ /** A tag that preserves the identity of the `TermTree` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val TermTreeTag: ClassTag[TermTree]
+
+ /** A tree for a type. Not all types are TypTrees; use isType
+ * to reliably identify types.
+ */
+ type TypTree >: Null <: AnyRef with Tree
+
+ /** A tag that preserves the identity of the `TypTree` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val TypTreeTag: ClassTag[TypTree]
+
+ /** A tree with a mutable symbol field, initialized to NoSymbol.
+ */
+ type SymTree >: Null <: AnyRef with Tree
+
+ /** A tag that preserves the identity of the `SymTree` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val SymTreeTag: ClassTag[SymTree]
+
+ /** A tree with a name - effectively, a DefTree or RefTree.
+ */
+ type NameTree >: Null <: AnyRef with Tree
+
+ /** A tag that preserves the identity of the `NameTree` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val NameTreeTag: ClassTag[NameTree]
+
+ /** A tree which references a symbol-carrying entity.
+ * References one, as opposed to defining one; definitions
+ * are in DefTrees.
+ */
+ type RefTree >: Null <: SymTree with NameTree
+
+ /** A tag that preserves the identity of the `RefTree` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val RefTreeTag: ClassTag[RefTree]
+
+ /** A tree which defines a symbol-carrying entity.
+ */
+ type DefTree >: Null <: SymTree with NameTree
+
+ /** A tag that preserves the identity of the `DefTree` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val DefTreeTag: ClassTag[DefTree]
+
+ /** Common base class for all member definitions: types, classes,
+ * objects, packages, vals and vars, defs.
+ */
+ type MemberDef >: Null <: DefTree
+
+ /** A tag that preserves the identity of the `MemberDef` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val MemberDefTag: ClassTag[MemberDef]
+
+ /** A packaging, such as `package pid { stats }`
+ */
+ type PackageDef >: Null <: MemberDef
+
+ /** A tag that preserves the identity of the `PackageDef` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val PackageDefTag: ClassTag[PackageDef]
+
+ /** The constructor/deconstructor for `PackageDef` instances. */
+ val PackageDef: PackageDefExtractor
+
+ /** An extractor class to create and pattern match with syntax `PackageDef(pid, stats)`.
+ * This AST node corresponds to the following Scala code:
+ *
+ * `package` pid { stats }
+ */
+ abstract class PackageDefExtractor {
+ def apply(pid: RefTree, stats: List[Tree]): PackageDef
+ def unapply(packageDef: PackageDef): Option[(RefTree, List[Tree])]
+ }
+
+ /** A common base class for class and object definitions.
+ */
+ type ImplDef >: Null <: MemberDef
+
+ /** A tag that preserves the identity of the `ImplDef` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val ImplDefTag: ClassTag[ImplDef]
+
+ /** A class definition.
+ */
+ type ClassDef >: Null <: ImplDef
+
+ /** A tag that preserves the identity of the `ClassDef` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val ClassDefTag: ClassTag[ClassDef]
+
+ /** The constructor/deconstructor for `ClassDef` instances. */
+ val ClassDef: ClassDefExtractor
+
+ /** An extractor class to create and pattern match with syntax `ClassDef(mods, name, tparams, impl)`.
+ * This AST node corresponds to the following Scala code:
+ *
+ * mods `class` name [tparams] impl
+ *
+ * Where impl stands for:
+ *
+ * `extends` parents { defs }
+ */
+ abstract class ClassDefExtractor {
+ def apply(mods: Modifiers, name: TypeName, tparams: List[TypeDef], impl: Template): ClassDef
+ def unapply(classDef: ClassDef): Option[(Modifiers, TypeName, List[TypeDef], Template)]
+ }
+
+ /** An object definition, e.g. `object Foo`. Internally, objects are
+ * quite frequently called modules to reduce ambiguity.
+ * Eliminated by refcheck.
+ */
+ type ModuleDef >: Null <: ImplDef
+
+ /** A tag that preserves the identity of the `ModuleDef` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val ModuleDefTag: ClassTag[ModuleDef]
+
+ /** The constructor/deconstructor for `ModuleDef` instances. */
+ val ModuleDef: ModuleDefExtractor
+
+ /** An extractor class to create and pattern match with syntax `ModuleDef(mods, name, impl)`.
+ * This AST node corresponds to the following Scala code:
+ *
+ * mods `object` name impl
+ *
+ * Where impl stands for:
+ *
+ * `extends` parents { defs }
+ */
+ abstract class ModuleDefExtractor {
+ def apply(mods: Modifiers, name: TermName, impl: Template): ModuleDef
+ def unapply(moduleDef: ModuleDef): Option[(Modifiers, TermName, Template)]
+ }
+
+ /** A common base class for ValDefs and DefDefs.
+ */
+ type ValOrDefDef >: Null <: MemberDef
+
+ /** A tag that preserves the identity of the `ValOrDefDef` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val ValOrDefDefTag: ClassTag[ValOrDefDef]
+
+ /** Broadly speaking, a value definition. All these are encoded as ValDefs:
+ *
+ * - immutable values, e.g. "val x"
+ * - mutable values, e.g. "var x" - the MUTABLE flag set in mods
+ * - lazy values, e.g. "lazy val x" - the LAZY flag set in mods
+ * - method parameters, see vparamss in DefDef - the PARAM flag is set in mods
+ * - explicit self-types, e.g. class A { self: Bar => } - !!! not sure what is set.
+ */
+ type ValDef >: Null <: ValOrDefDef
+
+ /** A tag that preserves the identity of the `ValDef` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val ValDefTag: ClassTag[ValDef]
+
+ /** The constructor/deconstructor for `ValDef` instances. */
+ val ValDef: ValDefExtractor
+
+ /** An extractor class to create and pattern match with syntax `ValDef(mods, name, tpt, rhs)`.
+ * This AST node corresponds to the following Scala code:
+ *
+ * mods `val` name: tpt = rhs
+ *
+ * mods `var` name: tpt = rhs
+ *
+ * mods name: tpt = rhs // in signatures of function and method definitions
+ *
+ * self: Bar => // self-types (!!! not sure what is set)
+ *
+ * If the type of a value is not specified explicitly (i.e. is meant to be inferred),
+ * this is expressed by having `tpt` set to `TypeTree()` (but not to an `EmptyTree`!).
+ */
+ abstract class ValDefExtractor {
+ def apply(mods: Modifiers, name: TermName, tpt: Tree, rhs: Tree): ValDef
+ def unapply(valDef: ValDef): Option[(Modifiers, TermName, Tree, Tree)]
+ }
+
+ /** A method or macro definition.
+ * @param name The name of the method or macro. Can be a type name in case this is a type macro
+ */
+ type DefDef >: Null <: ValOrDefDef
+
+ /** A tag that preserves the identity of the `DefDef` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val DefDefTag: ClassTag[DefDef]
+
+ /** The constructor/deconstructor for `DefDef` instances. */
+ val DefDef: DefDefExtractor
+
+ /** An extractor class to create and pattern match with syntax `DefDef(mods, name, tparams, vparamss, tpt, rhs)`.
+ * This AST node corresponds to the following Scala code:
+ *
+ * mods `def` name[tparams](vparams_1)...(vparams_n): tpt = rhs
+ *
+ * If the return type is not specified explicitly (i.e. is meant to be inferred),
+ * this is expressed by having `tpt` set to `TypeTree()` (but not to an `EmptyTree`!).
+ */
+ abstract class DefDefExtractor {
+ def apply(mods: Modifiers, name: Name, tparams: List[TypeDef], vparamss: List[List[ValDef]], tpt: Tree, rhs: Tree): DefDef
+ def unapply(defDef: DefDef): Option[(Modifiers, Name, List[TypeDef], List[List[ValDef]], Tree, Tree)]
+ }
+
+ /** An abstract type, a type parameter, or a type alias.
+ * Eliminated by erasure.
+ */
+ type TypeDef >: Null <: MemberDef
+
+ /** A tag that preserves the identity of the `TypeDef` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val TypeDefTag: ClassTag[TypeDef]
+
+ /** The constructor/deconstructor for `TypeDef` instances. */
+ val TypeDef: TypeDefExtractor
+
+ /** An extractor class to create and pattern match with syntax `TypeDef(mods, name, tparams, rhs)`.
+ * This AST node corresponds to the following Scala code:
+ *
+ * mods `type` name[tparams] = rhs
+ *
+ * mods `type` name[tparams] >: lo <: hi
+ *
+ * First usage illustrates `TypeDefs` representing type aliases and type parameters.
+ * Second usage illustrates `TypeDefs` representing abstract types,
+ * where lo and hi are both `TypeBoundsTrees` and `Modifier.deferred` is set in mods.
+ */
+ abstract class TypeDefExtractor {
+ def apply(mods: Modifiers, name: TypeName, tparams: List[TypeDef], rhs: Tree): TypeDef
+ def unapply(typeDef: TypeDef): Option[(Modifiers, TypeName, List[TypeDef], Tree)]
+ }
+
+ /** A labelled expression. Not expressible in language syntax, but
+ * generated by the compiler to simulate while/do-while loops, and
+ * also by the pattern matcher.
+ *
+ * The label acts much like a nested function, where `params` represents
+ * the incoming parameters. The symbol given to the LabelDef should have
+ * a MethodType, as if it were a nested function.
+ *
+ * Jumps are apply nodes attributed with a label's symbol. The
+ * arguments from the apply node will be passed to the label and
+ * assigned to the Idents.
+ *
+ * Forward jumps within a block are allowed.
+ */
+ type LabelDef >: Null <: DefTree with TermTree
+
+ /** A tag that preserves the identity of the `LabelDef` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val LabelDefTag: ClassTag[LabelDef]
+
+ /** The constructor/deconstructor for `LabelDef` instances. */
+ val LabelDef: LabelDefExtractor
+
+ /** An extractor class to create and pattern match with syntax `LabelDef(name, params, rhs)`.
+ *
+ * This AST node does not have direct correspondence to Scala code.
+ * It is used for tailcalls and like.
+ * For example, while/do are desugared to label defs as follows:
+ *
+ * while (cond) body ==> LabelDef($L, List(), if (cond) { body; L$() } else ())
+ * do body while (cond) ==> LabelDef($L, List(), body; if (cond) L$() else ())
+ */
+ abstract class LabelDefExtractor {
+ def apply(name: TermName, params: List[Ident], rhs: Tree): LabelDef
+ def unapply(labelDef: LabelDef): Option[(TermName, List[Ident], Tree)]
+ }
+
+ /** Import selector
+ *
+ * Representation of an imported name its optional rename and their optional positions
+ *
+ * Eliminated by typecheck.
+ *
+ * @param name the imported name
+ * @param namePos its position or -1 if undefined
+ * @param rename the name the import is renamed to (== name if no renaming)
+ * @param renamePos the position of the rename or -1 if undefined
+ */
+ type ImportSelector >: Null <: AnyRef
+
+ /** A tag that preserves the identity of the `ImportSelector` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val ImportSelectorTag: ClassTag[ImportSelector]
+
+ /** The constructor/deconstructor for `ImportSelector` instances. */
+ val ImportSelector: ImportSelectorExtractor
+
+ /** An extractor class to create and pattern match with syntax `ImportSelector(name:, namePos, rename, renamePos)`.
+ * This is not an AST node, it is used as a part of the `Import` node.
+ */
+ abstract class ImportSelectorExtractor {
+ def apply(name: Name, namePos: Int, rename: Name, renamePos: Int): ImportSelector
+ def unapply(importSelector: ImportSelector): Option[(Name, Int, Name, Int)]
+ }
+
+ /** Import clause
+ *
+ * @param expr
+ * @param selectors
+ */
+ type Import >: Null <: SymTree
+
+ /** A tag that preserves the identity of the `Import` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val ImportTag: ClassTag[Import]
+
+ /** The constructor/deconstructor for `Import` instances. */
+ val Import: ImportExtractor
+
+ /** An extractor class to create and pattern match with syntax `Import(expr, selectors)`.
+ * This AST node corresponds to the following Scala code:
+ *
+ * import expr.{selectors}
+ *
+ * Selectors are a list of pairs of names (from, to). // [Eugene++] obviously, they no longer are. please, document!
+ * The last (and maybe only name) may be a nme.WILDCARD. For instance:
+ *
+ * import qual.{x, y => z, _}
+ *
+ * Would be represented as:
+ *
+ * Import(qual, List(("x", "x"), ("y", "z"), (WILDCARD, null)))
+ *
+ * The symbol of an `Import` is an import symbol @see Symbol.newImport.
+ * It's used primarily as a marker to check that the import has been typechecked.
+ */
+ abstract class ImportExtractor {
+ def apply(expr: Tree, selectors: List[ImportSelector]): Import
+ def unapply(import_ : Import): Option[(Tree, List[ImportSelector])]
+ }
+
+ /** Instantiation template of a class or trait
+ *
+ * @param parents
+ * @param body
+ */
+ type Template >: Null <: SymTree
+
+ /** A tag that preserves the identity of the `Template` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val TemplateTag: ClassTag[Template]
+
+ /** The constructor/deconstructor for `Template` instances. */
+ val Template: TemplateExtractor
+
+ /** An extractor class to create and pattern match with syntax `Template(parents, self, body)`.
+ * This AST node corresponds to the following Scala code:
+ *
+ * `extends` parents { self => body }
+ *
+ * In case when the self-type annotation is missing, it is represented as
+ * an empty value definition with nme.WILDCARD as name and NoType as type.
+ *
+ * The symbol of a template is a local dummy. @see Symbol.newLocalDummy
+ * The owner of the local dummy is the enclosing trait or class.
+ * The local dummy is itself the owner of any local blocks. For example:
+ *
+ * class C {
+ * def foo { // owner is C
+ * def bar // owner is local dummy
+ * }
+ * }
+ */
+ abstract class TemplateExtractor {
+ def apply(parents: List[Tree], self: ValDef, body: List[Tree]): Template
+ def unapply(template: Template): Option[(List[Tree], ValDef, List[Tree])]
+ }
+
+ /** Block of expressions (semicolon separated expressions) */
+ type Block >: Null <: TermTree
+
+ /** A tag that preserves the identity of the `Block` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val BlockTag: ClassTag[Block]
+
+ /** The constructor/deconstructor for `Block` instances. */
+ val Block: BlockExtractor
+
+ /** An extractor class to create and pattern match with syntax `Block(stats, expr)`.
+ * This AST node corresponds to the following Scala code:
+ *
+ * { stats; expr }
+ *
+ * If the block is empty, the `expr` is set to `Literal(Constant(()))`. // [Eugene++] check this
+ */
+ abstract class BlockExtractor {
+ def apply(stats: List[Tree], expr: Tree): Block
+ def unapply(block: Block): Option[(List[Tree], Tree)]
+ }
+
+ /** Case clause in a pattern match, eliminated during explicitouter
+ * (except for occurrences in switch statements).
+ * Eliminated by patmat/explicitouter.
+ */
+ type CaseDef >: Null <: AnyRef with Tree
+
+ /** A tag that preserves the identity of the `CaseDef` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val CaseDefTag: ClassTag[CaseDef]
+
+ /** The constructor/deconstructor for `CaseDef` instances. */
+ val CaseDef: CaseDefExtractor
+
+ /** An extractor class to create and pattern match with syntax `CaseDef(pat, guard, body)`.
+ * This AST node corresponds to the following Scala code:
+ *
+ * `case` pat `if` guard => body
+ *
+ * If the guard is not present, the `guard` is set to `EmptyTree`. // [Eugene++] check this
+ * If the body is not specified, the `body` is set to `EmptyTree`. // [Eugene++] check this
+ */
+ abstract class CaseDefExtractor {
+ def apply(pat: Tree, guard: Tree, body: Tree): CaseDef
+ def unapply(caseDef: CaseDef): Option[(Tree, Tree, Tree)]
+ }
+
+ /** Alternatives of patterns, eliminated by explicitouter, except for
+ * occurrences in encoded Switch stmt (=remaining Match(CaseDef(...)))
+ * Eliminated by patmat/explicitouter.
+ */
+ type Alternative >: Null <: TermTree
+
+ /** A tag that preserves the identity of the `Alternative` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val AlternativeTag: ClassTag[Alternative]
+
+ /** The constructor/deconstructor for `Alternative` instances. */
+ val Alternative: AlternativeExtractor
+
+ /** An extractor class to create and pattern match with syntax `Alternative(trees)`.
+ * This AST node corresponds to the following Scala code:
+ *
+ * pat1 | ... | patn
+ */
+ abstract class AlternativeExtractor {
+ def apply(trees: List[Tree]): Alternative
+ def unapply(alternative: Alternative): Option[List[Tree]]
+ }
+
+ /** Repetition of pattern.
+ * Eliminated by patmat/explicitouter.
+ */
+ type Star >: Null <: TermTree
+
+ /** A tag that preserves the identity of the `Star` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val StarTag: ClassTag[Star]
+
+ /** The constructor/deconstructor for `Star` instances. */
+ val Star: StarExtractor
+
+ /** An extractor class to create and pattern match with syntax `Star(elem)`.
+ * This AST node corresponds to the following Scala code:
+ *
+ * pat*
+ */
+ abstract class StarExtractor {
+ def apply(elem: Tree): Star
+ def unapply(star: Star): Option[Tree]
+ }
+
+ /** Bind of a variable to a rhs pattern, eliminated by explicitouter
+ * Eliminated by patmat/explicitouter.
+ *
+ * @param name
+ * @param body
+ */
+ type Bind >: Null <: DefTree
+
+ /** A tag that preserves the identity of the `Bind` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val BindTag: ClassTag[Bind]
+
+ /** The constructor/deconstructor for `Bind` instances. */
+ val Bind: BindExtractor
+
+ /** An extractor class to create and pattern match with syntax `Bind(name, body)`.
+ * This AST node corresponds to the following Scala code:
+ *
+ * pat*
+ */
+ abstract class BindExtractor {
+ def apply(name: Name, body: Tree): Bind
+ def unapply(bind: Bind): Option[(Name, Tree)]
+ }
+
+ /** Noone knows what this is.
+ * It is not idempotent w.r.t typechecking.
+ * Can we, please, remove it?
+ * Introduced by typer, eliminated by patmat/explicitouter.
+ */
+ type UnApply >: Null <: TermTree
+
+ /** A tag that preserves the identity of the `UnApply` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val UnApplyTag: ClassTag[UnApply]
+
+ /** The constructor/deconstructor for `UnApply` instances. */
+ val UnApply: UnApplyExtractor
+
+ /** An extractor class to create and pattern match with syntax `UnApply(fun, args)`.
+ * This AST node does not have direct correspondence to Scala code,
+ * and is introduced when typechecking pattern matches and `try` blocks.
+ */
+ abstract class UnApplyExtractor {
+ def apply(fun: Tree, args: List[Tree]): UnApply
+ def unapply(unApply: UnApply): Option[(Tree, List[Tree])]
+ }
+
+ /** Array of expressions, needs to be translated in backend.
+ * This AST node is used to pass arguments to vararg arguments.
+ * Introduced by uncurry.
+ */
+ type ArrayValue >: Null <: TermTree
+
+ /** A tag that preserves the identity of the `ArrayValue` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val ArrayValueTag: ClassTag[ArrayValue]
+
+ /** The constructor/deconstructor for `ArrayValue` instances. */
+ val ArrayValue: ArrayValueExtractor
+
+ /** An extractor class to create and pattern match with syntax `ArrayValue(elemtpt, elems)`.
+ * This AST node does not have direct correspondence to Scala code,
+ * and is used to pass arguments to vararg arguments. For instance:
+ *
+ * printf("%s%d", foo, 42)
+ *
+ * Is translated to after uncurry to:
+ *
+ * Apply(
+ * Ident("printf"),
+ * Literal("%s%d"),
+ * ArrayValue(<Any>, List(Ident("foo"), Literal(42))))
+ */
+ abstract class ArrayValueExtractor {
+ def apply(elemtpt: Tree, elems: List[Tree]): ArrayValue
+ def unapply(arrayValue: ArrayValue): Option[(Tree, List[Tree])]
+ }
+
+ /** Anonymous function, eliminated by lambdalift */
+ type Function >: Null <: TermTree with SymTree
+
+ /** A tag that preserves the identity of the `Function` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val FunctionTag: ClassTag[Function]
+
+ /** The constructor/deconstructor for `Function` instances. */
+ val Function: FunctionExtractor
+
+ /** An extractor class to create and pattern match with syntax `Function(vparams, body)`.
+ * This AST node corresponds to the following Scala code:
+ *
+ * vparams => body
+ *
+ * The symbol of a Function is a synthetic value of name nme.ANON_FUN_NAME
+ * It is the owner of the function's parameters.
+ */
+ abstract class FunctionExtractor {
+ def apply(vparams: List[ValDef], body: Tree): Function
+ def unapply(function: Function): Option[(List[ValDef], Tree)]
+ }
+
+ /** Assignment */
+ type Assign >: Null <: TermTree
+
+ /** A tag that preserves the identity of the `Assign` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val AssignTag: ClassTag[Assign]
+
+ /** The constructor/deconstructor for `Assign` instances. */
+ val Assign: AssignExtractor
+
+ /** An extractor class to create and pattern match with syntax `Assign(lhs, rhs)`.
+ * This AST node corresponds to the following Scala code:
+ *
+ * lhs = rhs
+ */
+ abstract class AssignExtractor {
+ def apply(lhs: Tree, rhs: Tree): Assign
+ def unapply(assign: Assign): Option[(Tree, Tree)]
+ }
+
+ /** Either an assignment or a named argument. Only appears in argument lists,
+ * eliminated by typecheck (doTypedApply), resurrected by reifier.
+ */
+ type AssignOrNamedArg >: Null <: TermTree
+
+ /** A tag that preserves the identity of the `AssignOrNamedArg` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val AssignOrNamedArgTag: ClassTag[AssignOrNamedArg]
+
+ /** The constructor/deconstructor for `AssignOrNamedArg` instances. */
+ val AssignOrNamedArg: AssignOrNamedArgExtractor
+
+ /** An extractor class to create and pattern match with syntax `AssignOrNamedArg(lhs, rhs)`.
+ * This AST node corresponds to the following Scala code:
+ *
+ * @annotation(lhs = rhs)
+ *
+ * m.f(lhs = rhs)
+ */
+ abstract class AssignOrNamedArgExtractor {
+ def apply(lhs: Tree, rhs: Tree): AssignOrNamedArg
+ def unapply(assignOrNamedArg: AssignOrNamedArg): Option[(Tree, Tree)]
+ }
+
+ /** Conditional expression */
+ type If >: Null <: TermTree
+
+ /** A tag that preserves the identity of the `If` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val IfTag: ClassTag[If]
+
+ /** The constructor/deconstructor for `If` instances. */
+ val If: IfExtractor
+
+ /** An extractor class to create and pattern match with syntax `If(cond, thenp, elsep)`.
+ * This AST node corresponds to the following Scala code:
+ *
+ * `if` (cond) thenp `else` elsep
+ *
+ * If the alternative is not present, the `elsep` is set to `EmptyTree`. // [Eugene++] check this
+ */
+ abstract class IfExtractor {
+ def apply(cond: Tree, thenp: Tree, elsep: Tree): If
+ def unapply(if_ : If): Option[(Tree, Tree, Tree)]
+ }
+
+ /** - Pattern matching expression (before explicitouter)
+ * - Switch statements (after explicitouter)
+ *
+ * After explicitouter, cases will satisfy the following constraints:
+ *
+ * - all guards are `EmptyTree`,
+ * - all patterns will be either `Literal(Constant(x:Int))`
+ * or `Alternative(lit|...|lit)`
+ * - except for an "otherwise" branch, which has pattern
+ * `Ident(nme.WILDCARD)`
+ */
+ type Match >: Null <: TermTree
+
+ /** A tag that preserves the identity of the `Match` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val MatchTag: ClassTag[Match]
+
+ /** The constructor/deconstructor for `Match` instances. */
+ val Match: MatchExtractor
+
+ /** An extractor class to create and pattern match with syntax `Match(selector, cases)`.
+ * This AST node corresponds to the following Scala code:
+ *
+ * selector `match` { cases }
+ *
+ * // [Eugene++] say something about `val (foo, bar) = baz` and likes.
+ */
+ abstract class MatchExtractor {
+ def apply(selector: Tree, cases: List[CaseDef]): Match
+ def unapply(match_ : Match): Option[(Tree, List[CaseDef])]
+ }
+
+ /** Return expression */
+ type Return >: Null <: TermTree with SymTree
+
+ /** A tag that preserves the identity of the `Return` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val ReturnTag: ClassTag[Return]
+
+ /** The constructor/deconstructor for `Return` instances. */
+ val Return: ReturnExtractor
+
+ /** An extractor class to create and pattern match with syntax `Return(expr)`.
+ * This AST node corresponds to the following Scala code:
+ *
+ * `return` expr
+ *
+ * The symbol of a Return node is the enclosing method
+ */
+ abstract class ReturnExtractor {
+ def apply(expr: Tree): Return
+ def unapply(return_ : Return): Option[Tree]
+ }
+
+ /** [Eugene++] comment me! */
+ type Try >: Null <: TermTree
+
+ /** A tag that preserves the identity of the `Try` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val TryTag: ClassTag[Try]
+
+ /** The constructor/deconstructor for `Try` instances. */
+ val Try: TryExtractor
+
+ /** An extractor class to create and pattern match with syntax `Try(block, catches, finalizer)`.
+ * This AST node corresponds to the following Scala code:
+ *
+ * `try` block `catch` { catches } `finally` finalizer
+ *
+ * If the finalizer is not present, the `finalizer` is set to `EmptyTree`. // [Eugene++] check this
+ */
+ abstract class TryExtractor {
+ def apply(block: Tree, catches: List[CaseDef], finalizer: Tree): Try
+ def unapply(try_ : Try): Option[(Tree, List[CaseDef], Tree)]
+ }
+
+ /** Throw expression */
+ type Throw >: Null <: TermTree
+
+ /** A tag that preserves the identity of the `Throw` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val ThrowTag: ClassTag[Throw]
+
+ /** The constructor/deconstructor for `Throw` instances. */
+ val Throw: ThrowExtractor
+
+ /** An extractor class to create and pattern match with syntax `Throw(expr)`.
+ * This AST node corresponds to the following Scala code:
+ *
+ * `throw` expr
+ */
+ abstract class ThrowExtractor {
+ def apply(expr: Tree): Throw
+ def unapply(throw_ : Throw): Option[Tree]
+ }
+
+ /** Object instantiation
+ * One should always use factory method below to build a user level new.
+ *
+ * @param tpt a class type
+ */
+ type New >: Null <: TermTree
+
+ /** A tag that preserves the identity of the `New` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val NewTag: ClassTag[New]
+
+ /** The constructor/deconstructor for `New` instances. */
+ val New: NewExtractor
+
+ /** An extractor class to create and pattern match with syntax `New(tpt)`.
+ * This AST node corresponds to the following Scala code:
+ *
+ * `new` T
+ *
+ * This node always occurs in the following context:
+ *
+ * (`new` tpt).<init>[targs](args)
+ */
+ abstract class NewExtractor {
+ def apply(tpt: Tree): New
+ def unapply(new_ : New): Option[Tree]
+ }
+
+ /** Type annotation, eliminated by cleanup */
+ type Typed >: Null <: TermTree
+
+ /** A tag that preserves the identity of the `Typed` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val TypedTag: ClassTag[Typed]
+
+ /** The constructor/deconstructor for `Typed` instances. */
+ val Typed: TypedExtractor
+
+ /** An extractor class to create and pattern match with syntax `Typed(expr, tpt)`.
+ * This AST node corresponds to the following Scala code:
+ *
+ * expr: tpt
+ */
+ abstract class TypedExtractor {
+ def apply(expr: Tree, tpt: Tree): Typed
+ def unapply(typed: Typed): Option[(Tree, Tree)]
+ }
+
+ /** Common base class for Apply and TypeApply. This could in principle
+ * be a SymTree, but whether or not a Tree is a SymTree isn't used
+ * to settle any interesting questions, and it would add a useless
+ * field to all the instances (useless, since GenericApply forwards to
+ * the underlying fun.)
+ */
+ type GenericApply >: Null <: TermTree
+
+ /** A tag that preserves the identity of the `GenericApply` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val GenericApplyTag: ClassTag[GenericApply]
+
+ /** Explicit type application.
+ * @PP: All signs point toward it being a requirement that args.nonEmpty,
+ * but I can't find that explicitly stated anywhere. Unless your last name
+ * is odersky, you should probably treat it as true.
+ */
+ type TypeApply >: Null <: GenericApply
+
+ /** A tag that preserves the identity of the `TypeApply` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val TypeApplyTag: ClassTag[TypeApply]
+
+ /** The constructor/deconstructor for `TypeApply` instances. */
+ val TypeApply: TypeApplyExtractor
+
+ /** An extractor class to create and pattern match with syntax `TypeApply(fun, args)`.
+ * This AST node corresponds to the following Scala code:
+ *
+ * fun[args]
+ */
+ abstract class TypeApplyExtractor {
+ def apply(fun: Tree, args: List[Tree]): TypeApply
+ def unapply(typeApply: TypeApply): Option[(Tree, List[Tree])]
+ }
+
+ /** Value application */
+ type Apply >: Null <: GenericApply
+
+ /** A tag that preserves the identity of the `Apply` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val ApplyTag: ClassTag[Apply]
+
+ /** The constructor/deconstructor for `Apply` instances. */
+ val Apply: ApplyExtractor
+
+ /** An extractor class to create and pattern match with syntax `Apply(fun, args)`.
+ * This AST node corresponds to the following Scala code:
+ *
+ * fun(args)
+ *
+ * For instance:
+ *
+ * fun[targs](args)
+ *
+ * Is expressed as:
+ *
+ * Apply(TypeApply(fun, targs), args)
+ */
+ abstract class ApplyExtractor {
+ def apply(fun: Tree, args: List[Tree]): Apply
+ def unapply(apply: Apply): Option[(Tree, List[Tree])]
+ }
+
+ /** Dynamic value application.
+ * In a dynamic application q.f(as)
+ * - q is stored in qual
+ * - as is stored in args
+ * - f is stored as the node's symbol field.
+ * [Eugene++] what is it used for?
+ * Introduced by erasure, eliminated by cleanup.
+ */
+ type ApplyDynamic >: Null <: TermTree with SymTree
+
+ /** A tag that preserves the identity of the `ApplyDynamic` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val ApplyDynamicTag: ClassTag[ApplyDynamic]
+
+ /** The constructor/deconstructor for `ApplyDynamic` instances. */
+ val ApplyDynamic: ApplyDynamicExtractor
+
+ /** An extractor class to create and pattern match with syntax `ApplyDynamic(qual, args)`.
+ * This AST node corresponds to the following Scala code:
+ *
+ * fun(args)
+ *
+ * The symbol of an ApplyDynamic is the function symbol of `qual`, or NoSymbol, if there is none.
+ */
+ abstract class ApplyDynamicExtractor {
+ def apply(qual: Tree, args: List[Tree]): ApplyDynamic
+ def unapply(applyDynamic: ApplyDynamic): Option[(Tree, List[Tree])]
+ }
+
+ /** Super reference, qual = corresponding this reference
+ * A super reference C.super[M] is represented as Super(This(C), M).
+ */
+ type Super >: Null <: TermTree
+
+ /** A tag that preserves the identity of the `Super` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val SuperTag: ClassTag[Super]
+
+ /** The constructor/deconstructor for `Super` instances. */
+ val Super: SuperExtractor
+
+ /** An extractor class to create and pattern match with syntax `Super(qual, mix)`.
+ * This AST node corresponds to the following Scala code:
+ *
+ * C.super[M]
+ *
+ * Which is represented as:
+ *
+ * Super(This(C), M)
+ *
+ * If `mix` is empty, it is tpnme.EMPTY.
+ *
+ * The symbol of a Super is the class _from_ which the super reference is made.
+ * For instance in C.super(...), it would be C.
+ */
+ abstract class SuperExtractor {
+ def apply(qual: Tree, mix: TypeName): Super
+ def unapply(super_ : Super): Option[(Tree, TypeName)]
+ }
+
+ /** Self reference */
+ type This >: Null <: TermTree with SymTree
+
+ /** A tag that preserves the identity of the `This` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val ThisTag: ClassTag[This]
+
+ /** The constructor/deconstructor for `This` instances. */
+ val This: ThisExtractor
+
+ /** An extractor class to create and pattern match with syntax `This(qual)`.
+ * This AST node corresponds to the following Scala code:
+ *
+ * qual.this
+ *
+ * The symbol of a This is the class to which the this refers.
+ * For instance in C.this, it would be C.
+ *
+ * If `mix` is empty, then ???
+ */
+ abstract class ThisExtractor {
+ def apply(qual: TypeName): This
+ def unapply(this_ : This): Option[TypeName]
+ }
+
+ /** Designator <qualifier> . <name> */
+ type Select >: Null <: RefTree
+
+ /** A tag that preserves the identity of the `Select` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val SelectTag: ClassTag[Select]
+
+ /** The constructor/deconstructor for `Select` instances. */
+ val Select: SelectExtractor
+
+ /** An extractor class to create and pattern match with syntax `Select(qual, name)`.
+ * This AST node corresponds to the following Scala code:
+ *
+ * qualifier.selector
+ */
+ abstract class SelectExtractor {
+ def apply(qualifier: Tree, name: Name): Select
+ def unapply(select: Select): Option[(Tree, Name)]
+ }
+
+ /** Identifier <name> */
+ type Ident >: Null <: RefTree
+
+ /** A tag that preserves the identity of the `Ident` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val IdentTag: ClassTag[Ident]
+
+ /** The constructor/deconstructor for `Ident` instances. */
+ val Ident: IdentExtractor
+
+ /** An extractor class to create and pattern match with syntax `Ident(qual, name)`.
+ * This AST node corresponds to the following Scala code:
+ *
+ * name
+ *
+ * Type checker converts idents that refer to enclosing fields or methods to selects.
+ * For example, name ==> this.name
+ */
+ abstract class IdentExtractor {
+ def apply(name: Name): Ident
+ def unapply(ident: Ident): Option[Name]
+ }
+
+ /** Marks underlying reference to id as boxed.
+ * @pre id must refer to a captured variable
+ * A reference such marked will refer to the boxed entity, no dereferencing
+ * with `.elem` is done on it.
+ * This tree node can be emitted by macros such as reify that call referenceCapturedVariable.
+ * It is eliminated in LambdaLift, where the boxing conversion takes place.
+ */
+ type ReferenceToBoxed >: Null <: TermTree
+
+ /** A tag that preserves the identity of the `ReferenceToBoxed` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val ReferenceToBoxedTag: ClassTag[ReferenceToBoxed]
+
+ /** The constructor/deconstructor for `ReferenceToBoxed` instances. */
+ val ReferenceToBoxed: ReferenceToBoxedExtractor
+
+ /** An extractor class to create and pattern match with syntax `ReferenceToBoxed(ident)`.
+ * This AST node does not have direct correspondence to Scala code,
+ * and is emitted by macros to reference capture vars directly without going through `elem`.
+ *
+ * For example:
+ *
+ * var x = ...
+ * fun { x }
+ *
+ * Will emit:
+ *
+ * Ident(x)
+ *
+ * Which gets transformed to:
+ *
+ * Select(Ident(x), "elem")
+ *
+ * If `ReferenceToBoxed` were used instead of Ident, no transformation would be performed.
+ */
+ abstract class ReferenceToBoxedExtractor {
+ def apply(ident: Ident): ReferenceToBoxed
+ def unapply(referenceToBoxed: ReferenceToBoxed): Option[Ident]
+ }
+
+ /** Literal */
+ type Literal >: Null <: TermTree
+
+ /** A tag that preserves the identity of the `Literal` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val LiteralTag: ClassTag[Literal]
+
+ /** The constructor/deconstructor for `Literal` instances. */
+ val Literal: LiteralExtractor
+
+ /** An extractor class to create and pattern match with syntax `Literal(value)`.
+ * This AST node corresponds to the following Scala code:
+ *
+ * value
+ */
+ abstract class LiteralExtractor {
+ def apply(value: Constant): Literal
+ def unapply(literal: Literal): Option[Constant]
+ }
+
+ /** A tree that has an annotation attached to it. Only used for annotated types and
+ * annotation ascriptions, annotations on definitions are stored in the Modifiers.
+ * Eliminated by typechecker (typedAnnotated), the annotations are then stored in
+ * an AnnotatedType.
+ */
+ type Annotated >: Null <: AnyRef with Tree
+
+ /** A tag that preserves the identity of the `Annotated` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val AnnotatedTag: ClassTag[Annotated]
+
+ /** The constructor/deconstructor for `Annotated` instances. */
+ val Annotated: AnnotatedExtractor
+
+ /** An extractor class to create and pattern match with syntax `Annotated(annot, arg)`.
+ * This AST node corresponds to the following Scala code:
+ *
+ * arg @annot // for types
+ * arg: @annot // for exprs
+ */
+ abstract class AnnotatedExtractor {
+ def apply(annot: Tree, arg: Tree): Annotated
+ def unapply(annotated: Annotated): Option[(Tree, Tree)]
+ }
+
+ /** Singleton type, eliminated by RefCheck */
+ type SingletonTypeTree >: Null <: TypTree
+
+ /** A tag that preserves the identity of the `SingletonTypeTree` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val SingletonTypeTreeTag: ClassTag[SingletonTypeTree]
+
+ /** The constructor/deconstructor for `SingletonTypeTree` instances. */
+ val SingletonTypeTree: SingletonTypeTreeExtractor
+
+ /** An extractor class to create and pattern match with syntax `SingletonTypeTree(ref)`.
+ * This AST node corresponds to the following Scala code:
+ *
+ * ref.type
+ */
+ abstract class SingletonTypeTreeExtractor {
+ def apply(ref: Tree): SingletonTypeTree
+ def unapply(singletonTypeTree: SingletonTypeTree): Option[Tree]
+ }
+
+ /** Type selection <qualifier> # <name>, eliminated by RefCheck */
+ // [Eugene++] don't see why we need it, when we have Select
+ type SelectFromTypeTree >: Null <: TypTree with RefTree
+
+ /** A tag that preserves the identity of the `SelectFromTypeTree` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val SelectFromTypeTreeTag: ClassTag[SelectFromTypeTree]
+
+ /** The constructor/deconstructor for `SelectFromTypeTree` instances. */
+ val SelectFromTypeTree: SelectFromTypeTreeExtractor
+
+ /** An extractor class to create and pattern match with syntax `SelectFromTypeTree(qualifier, name)`.
+ * This AST node corresponds to the following Scala code:
+ *
+ * qualifier # selector
+ *
+ * Note: a path-dependent type p.T is expressed as p.type # T
+ */
+ abstract class SelectFromTypeTreeExtractor {
+ def apply(qualifier: Tree, name: TypeName): SelectFromTypeTree
+ def unapply(selectFromTypeTree: SelectFromTypeTree): Option[(Tree, TypeName)]
+ }
+
+ /** Intersection type <parent1> with ... with <parentN> { <decls> }, eliminated by RefCheck */
+ type CompoundTypeTree >: Null <: TypTree
+
+ /** A tag that preserves the identity of the `CompoundTypeTree` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val CompoundTypeTreeTag: ClassTag[CompoundTypeTree]
+
+ /** The constructor/deconstructor for `CompoundTypeTree` instances. */
+ val CompoundTypeTree: CompoundTypeTreeExtractor
+
+ /** An extractor class to create and pattern match with syntax `CompoundTypeTree(templ)`.
+ * This AST node corresponds to the following Scala code:
+ *
+ * parent1 with ... with parentN { refinement }
+ */
+ abstract class CompoundTypeTreeExtractor {
+ def apply(templ: Template): CompoundTypeTree
+ def unapply(compoundTypeTree: CompoundTypeTree): Option[Template]
+ }
+
+ /** Applied type <tpt> [ <args> ], eliminated by RefCheck */
+ type AppliedTypeTree >: Null <: TypTree
+
+ /** A tag that preserves the identity of the `AppliedTypeTree` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val AppliedTypeTreeTag: ClassTag[AppliedTypeTree]
+
+ /** The constructor/deconstructor for `AppliedTypeTree` instances. */
+ val AppliedTypeTree: AppliedTypeTreeExtractor
+
+ /** An extractor class to create and pattern match with syntax `AppliedTypeTree(tpt, args)`.
+ * This AST node corresponds to the following Scala code:
+ *
+ * tpt[args]
+ */
+ abstract class AppliedTypeTreeExtractor {
+ def apply(tpt: Tree, args: List[Tree]): AppliedTypeTree
+ def unapply(appliedTypeTree: AppliedTypeTree): Option[(Tree, List[Tree])]
+ }
+
+ /** Document me! */
+ type TypeBoundsTree >: Null <: TypTree
+
+ /** A tag that preserves the identity of the `TypeBoundsTree` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val TypeBoundsTreeTag: ClassTag[TypeBoundsTree]
+
+ /** The constructor/deconstructor for `TypeBoundsTree` instances. */
+ val TypeBoundsTree: TypeBoundsTreeExtractor
+
+ /** An extractor class to create and pattern match with syntax `TypeBoundsTree(lo, hi)`.
+ * This AST node corresponds to the following Scala code:
+ *
+ * >: lo <: hi
+ */
+ abstract class TypeBoundsTreeExtractor {
+ def apply(lo: Tree, hi: Tree): TypeBoundsTree
+ def unapply(typeBoundsTree: TypeBoundsTree): Option[(Tree, Tree)]
+ }
+
+ /** Document me! */
+ type ExistentialTypeTree >: Null <: TypTree
+
+ /** A tag that preserves the identity of the `ExistentialTypeTree` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val ExistentialTypeTreeTag: ClassTag[ExistentialTypeTree]
+
+ /** The constructor/deconstructor for `ExistentialTypeTree` instances. */
+ val ExistentialTypeTree: ExistentialTypeTreeExtractor
+
+ /** An extractor class to create and pattern match with syntax `ExistentialTypeTree(tpt, whereClauses)`.
+ * This AST node corresponds to the following Scala code:
+ *
+ * tpt forSome { whereClauses }
+ */
+ abstract class ExistentialTypeTreeExtractor {
+ def apply(tpt: Tree, whereClauses: List[Tree]): ExistentialTypeTree
+ def unapply(existentialTypeTree: ExistentialTypeTree): Option[(Tree, List[Tree])]
+ }
+
+ /** A synthetic tree holding an arbitrary type. Not to be confused with
+ * with TypTree, the trait for trees that are only used for type trees.
+ * TypeTree's are inserted in several places, but most notably in
+ * `RefCheck`, where the arbitrary type trees are all replaced by
+ * TypeTree's. */
+ type TypeTree >: Null <: TypTree
+
+ /** A tag that preserves the identity of the `TypeTree` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val TypeTreeTag: ClassTag[TypeTree]
+
+ /** The constructor/deconstructor for `TypeTree` instances. */
+ val TypeTree: TypeTreeExtractor
+
+ /** An extractor class to create and pattern match with syntax `TypeTree()`.
+ * This AST node does not have direct correspondence to Scala code,
+ * and is emitted by everywhere when we want to wrap a `Type` in a `Tree`.
+ */
+ abstract class TypeTreeExtractor {
+ def apply(): TypeTree
+ def unapply(typeTree: TypeTree): Boolean
+ }
+
+ /** ... */
+ type Modifiers >: Null <: ModifiersBase
+
+ /** A tag that preserves the identity of the `Modifiers` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val ModifiersTag: ClassTag[Modifiers]
+
+ /** ... */
+ abstract class ModifiersBase {
+ def flags: FlagSet
+ def hasFlag(flags: FlagSet): Boolean
+ def hasAllFlags(flags: FlagSet): Boolean
+ def privateWithin: Name // default: EmptyTypeName
+ def annotations: List[Tree] // default: List()
+ def mapAnnotations(f: List[Tree] => List[Tree]): Modifiers =
+ Modifiers(flags, privateWithin, f(annotations))
+ }
+
+ val Modifiers: ModifiersCreator
+
+ abstract class ModifiersCreator {
+ def apply(): Modifiers = Modifiers(NoFlags, EmptyTypeName, List())
+ def apply(flags: FlagSet, privateWithin: Name, annotations: List[Tree]): Modifiers
+ }
+
+ def Modifiers(flags: FlagSet, privateWithin: Name): Modifiers = Modifiers(flags, privateWithin, List())
+ def Modifiers(flags: FlagSet): Modifiers = Modifiers(flags, EmptyTypeName)
+
+ /** ... */
+ lazy val NoMods = Modifiers()
+
+ // [Eugene++] temporarily moved here until SI-5863 is fixed
+// ---------------------- factories ----------------------------------------------
+
+ /** @param sym the class symbol
+ * @param impl the implementation template
+ */
+ def ClassDef(sym: Symbol, impl: Template): ClassDef
+
+ /**
+ * @param sym the class symbol
+ * @param impl the implementation template
+ */
+ def ModuleDef(sym: Symbol, impl: Template): ModuleDef
+
+ def ValDef(sym: Symbol, rhs: Tree): ValDef
+
+ def ValDef(sym: Symbol): ValDef
+
+ def DefDef(sym: Symbol, mods: Modifiers, vparamss: List[List[ValDef]], rhs: Tree): DefDef
+
+ def DefDef(sym: Symbol, vparamss: List[List[ValDef]], rhs: Tree): DefDef
+
+ def DefDef(sym: Symbol, mods: Modifiers, rhs: Tree): DefDef
+
+ def DefDef(sym: Symbol, rhs: Tree): DefDef
+
+ def DefDef(sym: Symbol, rhs: List[List[Symbol]] => Tree): DefDef
+
+ /** A TypeDef node which defines given `sym` with given tight hand side `rhs`. */
+ def TypeDef(sym: Symbol, rhs: Tree): TypeDef
+
+ /** A TypeDef node which defines abstract type or type parameter for given `sym` */
+ def TypeDef(sym: Symbol): TypeDef
+
+ def LabelDef(sym: Symbol, params: List[Symbol], rhs: Tree): LabelDef
+
+ /** Block factory that flattens directly nested blocks.
+ */
+ def Block(stats: Tree*): Block
+
+ /** casedef shorthand */
+ def CaseDef(pat: Tree, body: Tree): CaseDef
+
+ def Bind(sym: Symbol, body: Tree): Bind
+
+ def Try(body: Tree, cases: (Tree, Tree)*): Try
+
+ def Throw(tpe: Type, args: Tree*): Throw
+
+ /** Factory method for object creation `new tpt(args_1)...(args_n)`
+ * A `New(t, as)` is expanded to: `(new t).<init>(as)`
+ */
+ def New(tpt: Tree, argss: List[List[Tree]]): Tree
+
+ /** 0-1 argument list new, based on a type.
+ */
+ def New(tpe: Type, args: Tree*): Tree
+
+ def New(sym: Symbol, args: Tree*): Tree
+
+ def Apply(sym: Symbol, args: Tree*): Tree
+
+ def ApplyConstructor(tpt: Tree, args: List[Tree]): Tree
+
+ def Super(sym: Symbol, mix: TypeName): Tree
+
+ def This(sym: Symbol): Tree
+
+ def Select(qualifier: Tree, name: String): Select
+
+ def Select(qualifier: Tree, sym: Symbol): Select
+
+ def Ident(name: String): Ident
+
+ def Ident(sym: Symbol): Ident
+
+ def TypeTree(tp: Type): TypeTree
+} \ No newline at end of file
diff --git a/src/library/scala/reflect/base/TypeCreator.scala b/src/library/scala/reflect/base/TypeCreator.scala
new file mode 100644
index 0000000000..8a14e53dd3
--- /dev/null
+++ b/src/library/scala/reflect/base/TypeCreator.scala
@@ -0,0 +1,6 @@
+package scala.reflect
+package base
+
+abstract class TypeCreator {
+ def apply[U <: Universe with Singleton](m: MirrorOf[U]): U # Type
+}
diff --git a/src/library/scala/reflect/api/TypeTags.scala b/src/library/scala/reflect/base/TypeTags.scala
index c58b0fcec2..5c55f45cf7 100644
--- a/src/library/scala/reflect/api/TypeTags.scala
+++ b/src/library/scala/reflect/base/TypeTags.scala
@@ -4,7 +4,7 @@
*/
package scala.reflect
-package api
+package base
import java.lang.{ Class => jClass }
import language.implicitConversions
@@ -16,34 +16,29 @@ import language.implicitConversions
*
* === Overview ===
*
- * Type tags are organized in a hierarchy of five classes:
- * [[scala.reflect.ArrayTag]], [[scala.reflect.ErasureTag]], [[scala.reflect.ClassTag]],
- * [[scala.reflect.api.Universe#TypeTag]] and [[scala.reflect.api.Universe#ConcreteTypeTag]].
+ * Type tags are organized in a hierarchy of four classes:
+ * [[scala.reflect.ArrayTag]], [[scala.reflect.ClassTag]],
+ * [[scala.reflect.base.Universe#TypeTag]] and [[scala.reflect.base.Universe#ConcreteTypeTag]].
*
* An [[scala.reflect.ArrayTag]] value carries knowledge about how to build an array of elements of type T.
- * Typically such operation is performed by storing an erasure and instantiating arrays via Java reflection,
+ * Typically such operation is performed by storing an erasure and instantiating arrays via reflection,
* but [[scala.reflect.ArrayTag]] only defines an interface, not an implementation, hence it only contains the factory methods
* `newArray` and `wrap` that can be used to build, correspondingly, single-dimensional and multi-dimensional arrays.
*
- * An [[scala.reflect.ErasureTag]] value wraps a Java class, which can be accessed via the `erasure` method.
- * This notion, previously embodied in a [[scala.reflect.ClassManifest]] together with the notion of array creation,
- * deserves a concept of itself. Quite often (e.g. for serialization or classloader introspection) it's useful to
- * know an erasure, and only it, so we've implemented this notion in [[scala.reflect.ErasureTag]].
- *
- * A [[scala.reflect.ClassTag]] is a standard implementation of both [[scala.reflect.ArrayTag]] and [[scala.reflect.ErasureTag]].
+ * A [[scala.reflect.ClassTag]] is a standard implementation of [[scala.reflect.ArrayTag]].
* It guarantees that the source type T did not to contain any references to type parameters or abstract types.
* [[scala.reflect.ClassTag]] corresponds to a previous notion of [[scala.reflect.ClassManifest]].
*
- * A [[scala.reflect.api.Universe#TypeTag]] value wraps a full Scala type in its tpe field.
- * A [[scala.reflect.api.Universe#ConcreteTypeTag]] value is a [[scala.reflect.api.Universe#TypeTag]]
+ * A [[scala.reflect.base.Universe#TypeTag]] value wraps a full Scala type in its tpe field.
+ * A [[scala.reflect.base.Universe#ConcreteTypeTag]] value is a [[scala.reflect.base.Universe#TypeTag]]
* that is guaranteed not to contain any references to type parameters or abstract types.
- * Both flavors of TypeTags also carry an erasure, so [[scala.reflect.api.Universe#TypeTag]] is also an [[scala.reflect.ErasureTag]],
- * and [[scala.reflect.api.Universe#ConcreteTypeTag]] is additionally an [[scala.reflect.ArrayTag]] and a [[scala.reflect.ClassTag]]
*
* It is recommended to use the tag supertypes of to precisely express your intent, i.e.:
- * use ArrayTag when you want to construct arrays,
- * use ErasureTag when you need an erasure and don't mind it being generated for untagged abstract types,
- * use ClassTag only when you need an erasure of a type that doesn't refer to untagged abstract types.
+ * use ArrayTag when you just want to construct arrays,
+ * use ClassTag only when you need an erasure, e.g. for serialization or pattern matching.
+ *
+ * [Eugene++] also mention sensitivity to prefixes, i.e. that rb.TypeTag is different from ru.TypeTag
+ * [Eugene++] migratability between mirrors and universes is also worth mentioning
*
* === Splicing ===
*
@@ -63,9 +58,9 @@ import language.implicitConversions
*
* Note that T has been replaced by String, because it comes with a TypeTag in f, whereas U was left as a type parameter.
*
- * === ErasureTag vs ClassTag and TypeTag vs ConcreteTypeTag ===
+ * === TypeTag vs ConcreteTypeTag ===
*
- * Be careful with ErasureTag and TypeTag, because they will reify types even if these types are abstract.
+ * Be careful with TypeTag, because it will reify types even if these types are abstract.
* This makes it easy to forget to tag one of the methods in the call chain and discover it much later in the runtime
* by getting cryptic errors far away from their source. For example, consider the following snippet:
*
@@ -77,7 +72,7 @@ import language.implicitConversions
* }
*
* This fragment of Scala REPL implementation defines a `bind` function that carries a named value along with its type
- * into the heart of the REPL. Using a [[scala.reflect.api.Universe#TypeTag]] here is reasonable, because it is desirable
+ * into the heart of the REPL. Using a [[scala.reflect.base.Universe#TypeTag]] here is reasonable, because it is desirable
* to work with all types, even if they are type parameters or abstract type members.
*
* However if any of the three `TypeTag` context bounds is omitted, the resulting code will be incorrect,
@@ -100,10 +95,11 @@ import language.implicitConversions
* however there are a few caveats:
*
* 1) The notion of OptManifest is no longer supported. Tags can reify arbitrary types, so they are always available.
- * // [Eugene] it might be useful, though, to guard against abstractness of the incoming type.
+ * // [Eugene++] it might be useful, though, to guard against abstractness of the incoming type.
*
- * 2) There's no equivalent for AnyValManifest. Consider comparing your tag with one of the core tags
+ * 2) There's no equivalent for AnyValManifest. Consider comparing your tag with one of the base tags
* (defined in the corresponding companion objects) to find out whether it represents a primitive value class.
+ * You can also use `<tag>.tpe.typeSymbol.isPrimitiveValueClass` for that purpose (requires scala-reflect.jar).
*
* 3) There's no replacement for factory methods defined in `ClassManifest` and `Manifest` companion objects.
* Consider assembling corresponding types using reflection API provided by Java (for classes) and Scala (for types).
@@ -111,6 +107,7 @@ import language.implicitConversions
* 4) Certain manifest functions (such as `<:<`, `>:>` and `typeArguments`) weren't included in the tag API.
* Consider using reflection API provided by Java (for classes) and Scala (for types) instead.
*/
+// [Eugene++] implement serialization for typetags
trait TypeTags { self: Universe =>
/**
@@ -119,23 +116,19 @@ trait TypeTags { self: Universe =>
* In that value, any occurrences of type parameters or abstract types U
* which come themselves with a TypeTag are represented by the type referenced by that TypeTag.
*
- * @see [[scala.reflect.api.TypeTags]]
+ * @see [[scala.reflect.base.TypeTags]]
*/
@annotation.implicitNotFound(msg = "No TypeTag available for ${T}")
- trait TypeTag[T] extends ErasureTag[T] with Equals with Serializable {
-
+ trait TypeTag[T] extends Equals with Serializable {
+ val mirror: Mirror
+ def in[U <: Universe with Singleton](otherMirror: MirrorOf[U]): U # TypeTag[T]
def tpe: Type
- def sym: Symbol = tpe.typeSymbol
-
- def isConcrete: Boolean = tpe.isConcrete
- def notConcrete: Boolean = !isConcrete
- def toConcrete: ConcreteTypeTag[T] = ConcreteTypeTag[T](tpe, erasure)
/** case class accessories */
override def canEqual(x: Any) = x.isInstanceOf[TypeTag[_]]
- override def equals(x: Any) = x.isInstanceOf[TypeTag[_]] && this.tpe == x.asInstanceOf[TypeTag[_]].tpe
- override def hashCode = scala.runtime.ScalaRunTime.hash(tpe)
- override def toString = if (!self.isInstanceOf[DummyMirror]) (if (isConcrete) "*ConcreteTypeTag" else "TypeTag") + "[" + tpe + "]" else "TypeTag[?]"
+ override def equals(x: Any) = x.isInstanceOf[TypeTag[_]] && this.mirror == x.asInstanceOf[TypeTag[_]].mirror && this.tpe == x.asInstanceOf[TypeTag[_]].tpe
+ override def hashCode = mirror.hashCode * 31 + tpe.hashCode
+ override def toString = "TypeTag[" + tpe + "]"
}
object TypeTag {
@@ -150,16 +143,12 @@ trait TypeTags { self: Universe =>
val Unit : TypeTag[scala.Unit] = ConcreteTypeTag.Unit
val Any : TypeTag[scala.Any] = ConcreteTypeTag.Any
val Object : TypeTag[java.lang.Object] = ConcreteTypeTag.Object
- val AnyVal : TypeTag[scala.AnyVal] = ConcreteTypeTag.AnyVal
- val AnyRef : TypeTag[scala.AnyRef] = ConcreteTypeTag.AnyRef
val Nothing : TypeTag[scala.Nothing] = ConcreteTypeTag.Nothing
val Null : TypeTag[scala.Null] = ConcreteTypeTag.Null
val String : TypeTag[java.lang.String] = ConcreteTypeTag.String
- // todo. uncomment after I redo the starr
- // def apply[T](tpe1: Type, erasure1: jClass[_]): TypeTag[T] =
- def apply[T](tpe1: Type, erasure1: jClass[_]): TypeTag[T] =
- tpe1 match {
+ def apply[T](mirror1: MirrorOf[self.type], tpec1: TypeCreator): TypeTag[T] =
+ tpec1(mirror1) match {
case ByteTpe => TypeTag.Byte.asInstanceOf[TypeTag[T]]
case ShortTpe => TypeTag.Short.asInstanceOf[TypeTag[T]]
case CharTpe => TypeTag.Char.asInstanceOf[TypeTag[T]]
@@ -171,58 +160,56 @@ trait TypeTags { self: Universe =>
case UnitTpe => TypeTag.Unit.asInstanceOf[TypeTag[T]]
case AnyTpe => TypeTag.Any.asInstanceOf[TypeTag[T]]
case ObjectTpe => TypeTag.Object.asInstanceOf[TypeTag[T]]
- case AnyValTpe => TypeTag.AnyVal.asInstanceOf[TypeTag[T]]
- case AnyRefTpe => TypeTag.AnyRef.asInstanceOf[TypeTag[T]]
case NothingTpe => TypeTag.Nothing.asInstanceOf[TypeTag[T]]
case NullTpe => TypeTag.Null.asInstanceOf[TypeTag[T]]
case StringTpe => TypeTag.String.asInstanceOf[TypeTag[T]]
- case _ => new TypeTag[T]{ def tpe = tpe1; def erasure = erasure1 }
+ case _ => new TypeTagImpl[T](mirror1.asInstanceOf[Mirror], tpec1)
}
def unapply[T](ttag: TypeTag[T]): Option[Type] = Some(ttag.tpe)
}
+ private class TypeTagImpl[T](val mirror: Mirror, val tpec: TypeCreator) extends TypeTag[T] {
+ lazy val tpe: Type = tpec[self.type](mirror)
+ def in[U <: Universe with Singleton](otherMirror: MirrorOf[U]): U # TypeTag[T] = {
+ val otherMirror1 = otherMirror.asInstanceOf[MirrorOf[otherMirror.universe.type]]
+ otherMirror.universe.TypeTag[T](otherMirror1, tpec)
+ }
+ }
+
/**
* If an implicit value of type u.ConcreteTypeTag[T] is required, the compiler will make one up on demand following the same procedure as for TypeTags.
* However, if the resulting type still contains references to type parameters or abstract types, a static error results.
*
- * @see [[scala.reflect.api.TypeTags]]
+ * @see [[scala.reflect.base.TypeTags]]
*/
@annotation.implicitNotFound(msg = "No ConcreteTypeTag available for ${T}")
- trait ConcreteTypeTag[T] extends TypeTag[T] with ClassTag[T] with Equals with Serializable {
- if (!self.isInstanceOf[DummyMirror]) {
- if (notConcrete) throw new Error("%s (%s) is not concrete and cannot be used to construct a concrete type tag".format(tpe, tpe.kind))
- }
-
+ trait ConcreteTypeTag[T] extends TypeTag[T] with Equals with Serializable {
/** case class accessories */
- override def canEqual(x: Any) = x.isInstanceOf[TypeTag[_]] // this is done on purpose. TypeTag(tpe) and ConcreteTypeTag(tpe) should be equal if tpe's are equal
- override def equals(x: Any) = x.isInstanceOf[TypeTag[_]] && this.tpe == x.asInstanceOf[TypeTag[_]].tpe
- override def hashCode = scala.runtime.ScalaRunTime.hash(tpe)
- override def toString = if (!self.isInstanceOf[DummyMirror]) "ConcreteTypeTag[" + tpe + "]" else "ConcreteTypeTag[?]"
+ override def canEqual(x: Any) = x.isInstanceOf[ConcreteTypeTag[_]]
+ override def equals(x: Any) = x.isInstanceOf[ConcreteTypeTag[_]] && this.mirror == x.asInstanceOf[ConcreteTypeTag[_]].mirror && this.tpe == x.asInstanceOf[ConcreteTypeTag[_]].tpe
+ override def hashCode = mirror.hashCode * 31 + tpe.hashCode
+ override def toString = "ConcreteTypeTag[" + tpe + "]"
}
object ConcreteTypeTag {
- val Byte : ConcreteTypeTag[scala.Byte] = new ConcreteTypeTag[scala.Byte]{ def tpe = ByteTpe; def erasure = ClassTag.Byte.erasure; private def readResolve() = ConcreteTypeTag.Byte }
- val Short : ConcreteTypeTag[scala.Short] = new ConcreteTypeTag[scala.Short]{ def tpe = ShortTpe; def erasure = ClassTag.Short.erasure; private def readResolve() = ConcreteTypeTag.Short }
- val Char : ConcreteTypeTag[scala.Char] = new ConcreteTypeTag[scala.Char]{ def tpe = CharTpe; def erasure = ClassTag.Char.erasure; private def readResolve() = ConcreteTypeTag.Char }
- val Int : ConcreteTypeTag[scala.Int] = new ConcreteTypeTag[scala.Int]{ def tpe = IntTpe; def erasure = ClassTag.Int.erasure; private def readResolve() = ConcreteTypeTag.Int }
- val Long : ConcreteTypeTag[scala.Long] = new ConcreteTypeTag[scala.Long]{ def tpe = LongTpe; def erasure = ClassTag.Long.erasure; private def readResolve() = ConcreteTypeTag.Long }
- val Float : ConcreteTypeTag[scala.Float] = new ConcreteTypeTag[scala.Float]{ def tpe = FloatTpe; def erasure = ClassTag.Float.erasure; private def readResolve() = ConcreteTypeTag.Float }
- val Double : ConcreteTypeTag[scala.Double] = new ConcreteTypeTag[scala.Double]{ def tpe = DoubleTpe; def erasure = ClassTag.Double.erasure; private def readResolve() = ConcreteTypeTag.Double }
- val Boolean : ConcreteTypeTag[scala.Boolean] = new ConcreteTypeTag[scala.Boolean]{ def tpe = BooleanTpe; def erasure = ClassTag.Boolean.erasure; private def readResolve() = ConcreteTypeTag.Boolean }
- val Unit : ConcreteTypeTag[scala.Unit] = new ConcreteTypeTag[scala.Unit]{ def tpe = UnitTpe; def erasure = ClassTag.Unit.erasure; private def readResolve() = ConcreteTypeTag.Unit }
- val Any : ConcreteTypeTag[scala.Any] = new ConcreteTypeTag[scala.Any]{ def tpe = AnyTpe; def erasure = ClassTag.Any.erasure; private def readResolve() = ConcreteTypeTag.Any }
- val Object : ConcreteTypeTag[java.lang.Object] = new ConcreteTypeTag[java.lang.Object]{ def tpe = ObjectTpe; def erasure = ClassTag.Object.erasure; private def readResolve() = ConcreteTypeTag.Object }
- val AnyVal : ConcreteTypeTag[scala.AnyVal] = new ConcreteTypeTag[scala.AnyVal]{ def tpe = AnyValTpe; def erasure = ClassTag.AnyVal.erasure; private def readResolve() = ConcreteTypeTag.AnyVal }
- val AnyRef : ConcreteTypeTag[scala.AnyRef] = new ConcreteTypeTag[scala.AnyRef]{ def tpe = AnyRefTpe; def erasure = ClassTag.AnyRef.erasure; private def readResolve() = ConcreteTypeTag.AnyRef }
- val Nothing : ConcreteTypeTag[scala.Nothing] = new ConcreteTypeTag[scala.Nothing]{ def tpe = NothingTpe; def erasure = ClassTag.Nothing.erasure; private def readResolve() = ConcreteTypeTag.Nothing }
- val Null : ConcreteTypeTag[scala.Null] = new ConcreteTypeTag[scala.Null]{ def tpe = NullTpe; def erasure = ClassTag.Null.erasure; private def readResolve() = ConcreteTypeTag.Null }
- val String : ConcreteTypeTag[java.lang.String] = new ConcreteTypeTag[java.lang.String]{ def tpe = StringTpe; def erasure = ClassTag.String.erasure; private def readResolve() = ConcreteTypeTag.String }
-
- // todo. uncomment after I redo the starr
- // def apply[T](tpe1: Type, erasure1: jClass[_]): ConcreteTypeTag[T] =
- def apply[T](tpe1: Type, erasure1: jClass[_] = null): ConcreteTypeTag[T] =
- tpe1 match {
+ val Byte: ConcreteTypeTag[scala.Byte] = new PredefConcreteTypeTag[scala.Byte] (ByteTpe, _.ConcreteTypeTag.Byte)
+ val Short: ConcreteTypeTag[scala.Short] = new PredefConcreteTypeTag[scala.Short] (ShortTpe, _.ConcreteTypeTag.Short)
+ val Char: ConcreteTypeTag[scala.Char] = new PredefConcreteTypeTag[scala.Char] (CharTpe, _.ConcreteTypeTag.Char)
+ val Int: ConcreteTypeTag[scala.Int] = new PredefConcreteTypeTag[scala.Int] (IntTpe, _.ConcreteTypeTag.Int)
+ val Long: ConcreteTypeTag[scala.Long] = new PredefConcreteTypeTag[scala.Long] (LongTpe, _.ConcreteTypeTag.Long)
+ val Float: ConcreteTypeTag[scala.Float] = new PredefConcreteTypeTag[scala.Float] (FloatTpe, _.ConcreteTypeTag.Float)
+ val Double: ConcreteTypeTag[scala.Double] = new PredefConcreteTypeTag[scala.Double] (DoubleTpe, _.ConcreteTypeTag.Double)
+ val Boolean: ConcreteTypeTag[scala.Boolean] = new PredefConcreteTypeTag[scala.Boolean] (BooleanTpe, _.ConcreteTypeTag.Boolean)
+ val Unit: ConcreteTypeTag[scala.Unit] = new PredefConcreteTypeTag[scala.Unit] (UnitTpe, _.ConcreteTypeTag.Unit)
+ val Any: ConcreteTypeTag[scala.Any] = new PredefConcreteTypeTag[scala.Any] (AnyTpe, _.ConcreteTypeTag.Any)
+ val Object: ConcreteTypeTag[java.lang.Object] = new PredefConcreteTypeTag[java.lang.Object] (ObjectTpe, _.ConcreteTypeTag.Object)
+ val Nothing: ConcreteTypeTag[scala.Nothing] = new PredefConcreteTypeTag[scala.Nothing] (NothingTpe, _.ConcreteTypeTag.Nothing)
+ val Null: ConcreteTypeTag[scala.Null] = new PredefConcreteTypeTag[scala.Null] (NullTpe, _.ConcreteTypeTag.Null)
+ val String: ConcreteTypeTag[java.lang.String] = new PredefConcreteTypeTag[java.lang.String] (StringTpe, _.ConcreteTypeTag.String)
+
+ def apply[T](mirror1: MirrorOf[self.type], tpec1: TypeCreator): ConcreteTypeTag[T] =
+ tpec1(mirror1) match {
case ByteTpe => ConcreteTypeTag.Byte.asInstanceOf[ConcreteTypeTag[T]]
case ShortTpe => ConcreteTypeTag.Short.asInstanceOf[ConcreteTypeTag[T]]
case CharTpe => ConcreteTypeTag.Char.asInstanceOf[ConcreteTypeTag[T]]
@@ -234,21 +221,33 @@ trait TypeTags { self: Universe =>
case UnitTpe => ConcreteTypeTag.Unit.asInstanceOf[ConcreteTypeTag[T]]
case AnyTpe => ConcreteTypeTag.Any.asInstanceOf[ConcreteTypeTag[T]]
case ObjectTpe => ConcreteTypeTag.Object.asInstanceOf[ConcreteTypeTag[T]]
- case AnyValTpe => ConcreteTypeTag.AnyVal.asInstanceOf[ConcreteTypeTag[T]]
- case AnyRefTpe => ConcreteTypeTag.AnyRef.asInstanceOf[ConcreteTypeTag[T]]
case NothingTpe => ConcreteTypeTag.Nothing.asInstanceOf[ConcreteTypeTag[T]]
case NullTpe => ConcreteTypeTag.Null.asInstanceOf[ConcreteTypeTag[T]]
case StringTpe => ConcreteTypeTag.String.asInstanceOf[ConcreteTypeTag[T]]
- case _ => new ConcreteTypeTag[T]{ def tpe = tpe1; def erasure = erasure1 }
+ case _ => new ConcreteTypeTagImpl[T](mirror1.asInstanceOf[Mirror], tpec1)
}
- def unapply[T](ttag: TypeTag[T]): Option[Type] = if (ttag.isConcrete) Some(ttag.tpe) else None
+ def unapply[T](ttag: ConcreteTypeTag[T]): Option[Type] = Some(ttag.tpe)
+ }
+
+ private class ConcreteTypeTagImpl[T](mirror: Mirror, tpec: TypeCreator) extends TypeTagImpl[T](mirror, tpec) with ConcreteTypeTag[T] {
+ override def in[U <: Universe with Singleton](otherMirror: MirrorOf[U]): U # TypeTag[T] = {
+ val otherMirror1 = otherMirror.asInstanceOf[MirrorOf[otherMirror.universe.type]]
+ otherMirror.universe.ConcreteTypeTag[T](otherMirror1, tpec)
+ }
}
- // incantations for summoning
- // moved to Context, since rm.tags have their own incantations in Predef, and these guys are only useful in macros
-// def tag[T](implicit ttag: TypeTag[T]) = ttag
-// def typeTag[T](implicit ttag: TypeTag[T]) = ttag
-// def concreteTag[T](implicit gttag: ConcreteTypeTag[T]) = cttag
-// def concreteTypeTag[T](implicit gttag: ConcreteTypeTag[T]) = cttag
+ private class PredefConcreteTypeTag[T](_tpe: Type, copyIn: Universe => Universe # TypeTag[T]) extends ConcreteTypeTagImpl[T](rootMirror, null) {
+ override lazy val tpe: Type = _tpe
+ override def in[U <: Universe with Singleton](otherMirror: MirrorOf[U]): U # TypeTag[T] =
+ copyIn(otherMirror.universe).asInstanceOf[U # TypeTag[T]]
+ private def readResolve() = copyIn(self)
+ }
+
+ // incantations
+ def typeTag[T](implicit ttag: TypeTag[T]) = ttag
+ def concreteTypeTag[T](implicit cttag: ConcreteTypeTag[T]) = cttag
+
+ // big thanks to Viktor Klang for this brilliant idea!
+ def typeOf[T](implicit ttag: TypeTag[T]): Type = ttag.tpe
}
diff --git a/src/library/scala/reflect/base/Types.scala b/src/library/scala/reflect/base/Types.scala
new file mode 100644
index 0000000000..6106e3fde7
--- /dev/null
+++ b/src/library/scala/reflect/base/Types.scala
@@ -0,0 +1,432 @@
+package scala.reflect
+package base
+
+trait Types { self: Universe =>
+
+ /** The base API that all types support */
+ abstract class TypeBase {
+
+ /** The type symbol associated with the type, or `NoSymbol` for types
+ * that do not refer to a type symbol.
+ */
+ def typeSymbol: Symbol
+ }
+
+ /** The type of Scala types, and also Scala type signatures.
+ * (No difference is internally made between the two).
+ */
+ type Type >: Null <: TypeBase
+
+ /** A tag that preserves the identity of the `Type` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val TypeTagg: ClassTag[Type] // [Eugene++] rename!
+
+ /** This constant is used as a special value that indicates that no meaningful type exists.
+ */
+ val NoType: Type
+
+ /** This constant is used as a special value denoting the empty prefix in a path dependent type.
+ * For instance `x.type` is represented as `SingleType(NoPrefix, <x>)`, where `<x>` stands for
+ * the symbol for `x`.
+ */
+ val NoPrefix: Type
+
+ /** The type of Scala singleton types, i.e. types that are inhabited
+ * by only one nun-null value. These include types of the forms
+ * {{{
+ * C.this.type
+ * C.super.type
+ * x.type
+ * }}}
+ * as well as constant types.
+ */
+ type SingletonType >: Null <: Type
+
+ /** A tag that preserves the identity of the `SingletonType` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val SingletonTypeTag: ClassTag[SingletonType]
+
+ /** The `ThisType` type describes types of the form on the left with the
+ * correspnding ThisType representations to the right.
+ * {{{
+ * C.this.type ThisType(C)
+ * }}}
+ */
+ type ThisType >: Null <: AnyRef with SingletonType
+
+ /** A tag that preserves the identity of the `ThisType` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val ThisTypeTag: ClassTag[ThisType]
+
+ /** The constructor/deconstructor for `ThisType` instances. */
+ val ThisType: ThisTypeExtractor
+
+ /** An extractor class to create and pattern match with syntax `ThisType(sym)`
+ * where `sym` is the class prefix of the this type.
+ */
+ abstract class ThisTypeExtractor {
+ def apply(sym: Symbol): Type // not ThisTypebecause of implementation details
+ def unapply(tpe: ThisType): Option[Symbol]
+ }
+
+ /** The `SingleType` type describes types of any of the forms on the left,
+ * with their TypeRef representations to the right.
+ * {{{
+ * (T # x).type SingleType(T, x)
+ * p.x.type SingleType(p.type, x)
+ * x.type SingleType(NoPrefix, x)
+ * }}}
+ */
+ type SingleType >: Null <: AnyRef with SingletonType
+
+ /** A tag that preserves the identity of the `SingleType` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val SingleTypeTag: ClassTag[SingleType]
+
+ /** The constructor/deconstructor for `SingleType` instances. */
+ val SingleType: SingleTypeExtractor
+
+ /** An extractor class to create and pattern match with syntax `SingleType(pre, sym)`
+ * Here, `pre` is the prefix of the single-type, and `sym` is the stable value symbol
+ * referred to by the single-type.
+ */
+ abstract class SingleTypeExtractor {
+ def apply(pre: Type, sym: Symbol): Type // not SingleTypebecause of implementation details
+ def unapply(tpe: SingleType): Option[(Type, Symbol)]
+ }
+
+ /** The `SuperType` type is not directly written, but arises when `C.super` is used
+ * as a prefix in a `TypeRef` or `SingleType`. It's internal presentation is
+ * {{{
+ * SuperType(thistpe, supertpe)
+ * }}}
+ * Here, `thistpe` is the type of the corresponding this-type. For instance,
+ * in the type arising from C.super, the `thistpe` part would be `ThisType(C)`.
+ * `supertpe` is the type of the super class referred to by the `super`.
+ */
+ type SuperType >: Null <: AnyRef with SingletonType
+
+ /** A tag that preserves the identity of the `SuperType` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val SuperTypeTag: ClassTag[SuperType]
+
+ /** The constructor/deconstructor for `SuperType` instances. */
+ val SuperType: SuperTypeExtractor
+
+ /** An extractor class to create and pattern match with syntax `SingleType(thistpe, supertpe)`
+ */
+ abstract class SuperTypeExtractor {
+ def apply(thistpe: Type, supertpe: Type): Type // not SuperTypebecause of implementation details
+ def unapply(tpe: SuperType): Option[(Type, Type)]
+ }
+
+ /** The `ConstantType` type is not directly written in user programs, but arises as the type of a constant.
+ * The REPL expresses constant types like Int(11). Here are some constants with their types.
+ * {{{
+ * 1 ConstantType(Constant(1))
+ * "abc" ConstantType(Constant("abc"))
+ * }}}
+ */
+ type ConstantType >: Null <: AnyRef with SingletonType
+
+ /** A tag that preserves the identity of the `ConstantType` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val ConstantTypeTag: ClassTag[ConstantType]
+
+ /** The constructor/deconstructor for `ConstantType` instances. */
+ val ConstantType: ConstantTypeExtractor
+
+ /** An extractor class to create and pattern match with syntax `ConstantType(constant)`
+ * Here, `constant` is the constant value represented by the type.
+ */
+ abstract class ConstantTypeExtractor {
+ def apply(value: Constant): ConstantType
+ def unapply(tpe: ConstantType): Option[Constant]
+ }
+
+ /** The `TypeRef` type describes types of any of the forms on the left,
+ * with their TypeRef representations to the right.
+ * {{{
+ * T # C[T_1, ..., T_n] TypeRef(T, C, List(T_1, ..., T_n))
+ * p.C[T_1, ..., T_n] TypeRef(p.type, C, List(T_1, ..., T_n))
+ * C[T_1, ..., T_n] TypeRef(NoPrefix, C, List(T_1, ..., T_n))
+ * T # C TypeRef(T, C, Nil)
+ * p.C TypeRef(p.type, C, Nil)
+ * C TypeRef(NoPrefix, C, Nil)
+ * }}}
+ */
+ type TypeRef >: Null <: AnyRef with Type
+
+ /** A tag that preserves the identity of the `TypeRef` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val TypeRefTag: ClassTag[TypeRef]
+
+ /** The constructor/deconstructor for `TypeRef` instances. */
+ val TypeRef: TypeRefExtractor
+
+ /** An extractor class to create and pattern match with syntax `TypeRef(pre, sym, args)`
+ * Here, `pre` is the prefix of the type reference, `sym` is the symbol
+ * referred to by the type reference, and `args` is a possible empty list of
+ * type argumenrts.
+ */
+ abstract class TypeRefExtractor {
+ def apply(pre: Type, sym: Symbol, args: List[Type]): Type // not TypeRefbecause of implementation details
+ def unapply(tpe: TypeRef): Option[(Type, Symbol, List[Type])]
+ }
+
+ /** A subtype of Type representing refined types as well as `ClassInfo` signatures.
+ */
+ type CompoundType >: Null <: AnyRef with Type
+
+ /** A tag that preserves the identity of the `CompoundType` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val CompoundTypeTag: ClassTag[CompoundType]
+
+ /** The `RefinedType` type defines types of any of the forms on the left,
+ * with their RefinedType representations to the right.
+ * {{{
+ * P_1 with ... with P_m { D_1; ...; D_n} RefinedType(List(P_1, ..., P_m), Scope(D_1, ..., D_n))
+ * P_1 with ... with P_m RefinedType(List(P_1, ..., P_m), Scope())
+ * { D_1; ...; D_n} RefinedType(List(AnyRef), Scope(D_1, ..., D_n))
+ * }}}
+ */
+ type RefinedType >: Null <: AnyRef with CompoundType
+
+ /** A tag that preserves the identity of the `RefinedType` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val RefinedTypeTag: ClassTag[RefinedType]
+
+ /** The constructor/deconstructor for `RefinedType` instances. */
+ val RefinedType: RefinedTypeExtractor
+
+ /** An extractor class to create and pattern match with syntax `RefinedType(parents, decls)`
+ * Here, `parents` is the list of parent types of the class, and `decls` is the scope
+ * containing all declarations in the class.
+ */
+ abstract class RefinedTypeExtractor {
+ def apply(parents: List[Type], decls: Scope): RefinedType
+
+ /** An alternative constructor that passes in the synthetic classs symbol
+ * that backs the refined type. (Normally, a fresh class symbol is created automatically).
+ */
+ def apply(parents: List[Type], decls: Scope, clazz: Symbol): RefinedType
+ def unapply(tpe: RefinedType): Option[(List[Type], Scope)]
+ }
+
+ /** The `ClassInfo` type signature is used to define parents and declarations
+ * of classes, traits, and objects. If a class, trait, or object C is declared like this
+ * {{{
+ * C extends P_1 with ... with P_m { D_1; ...; D_n}
+ * }}}
+ * its `ClassInfo` type has the following form:
+ * {{{
+ * ClassInfo(List(P_1, ..., P_m), Scope(D_1, ..., D_n), C)
+ * }}}
+ */
+ type ClassInfoType >: Null <: AnyRef with CompoundType
+
+ /** A tag that preserves the identity of the `ClassInfoType` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val ClassInfoTypeTag: ClassTag[ClassInfoType]
+
+ /** The constructor/deconstructor for `ClassInfoType` instances. */
+ val ClassInfoType: ClassInfoTypeExtractor
+
+ /** An extractor class to create and pattern match with syntax `ClassInfo(parents, decls, clazz)`
+ * Here, `parents` is the list of parent types of the class, `decls` is the scope
+ * containing all declarations in the class, and `clazz` is the symbol of the class
+ * itself.
+ */
+ abstract class ClassInfoTypeExtractor {
+ def apply(parents: List[Type], decls: Scope, typeSymbol: Symbol): ClassInfoType
+ def unapply(tpe: ClassInfoType): Option[(List[Type], Scope, Symbol)]
+ }
+
+ /** The `MethodType` type signature is used to indicate parameters and result type of a method
+ */
+ type MethodType >: Null <: AnyRef with Type
+
+ /** A tag that preserves the identity of the `MethodType` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val MethodTypeTag: ClassTag[MethodType]
+
+ /** The constructor/deconstructor for `MethodType` instances. */
+ val MethodType: MethodTypeExtractor
+
+ /** An extractor class to create and pattern match with syntax `MethodType(params, respte)`
+ * Here, `params` is a potentially empty list of parameter symbols of the method,
+ * and `restpe` is the result type of the method. If the method is curried, `restpe` would
+ * be another `MethodType`.
+ * Note: `MethodType(Nil, Int)` would be the type of a method defined with an empty parameter list.
+ * {{{
+ * def f(): Int
+ * }}}
+ * If the method is completely parameterless, as in
+ * {{{
+ * def f: Int
+ * }}}
+ * its type is a `NullaryMethodType`.
+ */
+ abstract class MethodTypeExtractor {
+ def apply(params: List[Symbol], resultType: Type): MethodType
+ def unapply(tpe: MethodType): Option[(List[Symbol], Type)]
+ }
+
+ /** The `NullaryMethodType` type signature is used for parameterless methods
+ * with declarations of the form `def foo: T`
+ */
+ type NullaryMethodType >: Null <: AnyRef with Type
+
+ /** A tag that preserves the identity of the `NullaryMethodType` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val NullaryMethodTypeTag: ClassTag[NullaryMethodType]
+
+ /** The constructor/deconstructor for `NullaryMethodType` instances. */
+ val NullaryMethodType: NullaryMethodTypeExtractor
+
+ /** An extractor class to create and pattern match with syntax `NullaryMethodType(resultType)`.
+ * Here, `resultType` is the result type of the parameterless method.
+ */
+ abstract class NullaryMethodTypeExtractor {
+ def apply(resultType: Type): NullaryMethodType
+ def unapply(tpe: NullaryMethodType): Option[(Type)]
+ }
+
+ /** The `PolyType` type signature is used for polymorphic methods
+ * that have at least one type parameter.
+ */
+ type PolyType >: Null <: AnyRef with Type
+
+ /** A tag that preserves the identity of the `PolyType` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val PolyTypeTag: ClassTag[PolyType]
+
+ /** The constructor/deconstructor for `PolyType` instances. */
+ val PolyType: PolyTypeExtractor
+
+ /** An extractor class to create and pattern match with syntax `PolyType(typeParams, resultType)`.
+ * Here, `typeParams` are the type parameters of the method and `resultType`
+ * is the type signature following the type parameters.
+ */
+ abstract class PolyTypeExtractor {
+ def apply(typeParams: List[Symbol], resultType: Type): PolyType
+ def unapply(tpe: PolyType): Option[(List[Symbol], Type)]
+ }
+
+ /** The `ExistentialType` type signature is used for existential types and
+ * wildcard types.
+ */
+ type ExistentialType >: Null <: AnyRef with Type
+
+ /** A tag that preserves the identity of the `ExistentialType` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val ExistentialTypeTag: ClassTag[ExistentialType]
+
+ /** The constructor/deconstructor for `ExistentialType` instances. */
+ val ExistentialType: ExistentialTypeExtractor
+
+ /** An extractor class to create and pattern match with syntax
+ * `ExistentialType(quantified, underlying)`.
+ * Here, `quantified` are the type variables bound by the existential type and `underlying`
+ * is the type that's existentially quantified.
+ */
+ abstract class ExistentialTypeExtractor {
+ def apply(quantified: List[Symbol], underlying: Type): ExistentialType
+ def unapply(tpe: ExistentialType): Option[(List[Symbol], Type)]
+ }
+
+ /** The `AnnotatedType` type signature is used for annotated types of the
+ * for `<type> @<annotation>`.
+ */
+ type AnnotatedType >: Null <: AnyRef with Type
+
+ /** A tag that preserves the identity of the `AnnotatedType` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val AnnotatedTypeTag: ClassTag[AnnotatedType]
+
+ /** The constructor/deconstructor for `AnnotatedType` instances. */
+ val AnnotatedType: AnnotatedTypeExtractor
+
+ /** An extractor class to create and pattern match with syntax
+ * `AnnotatedType(annotations, underlying, selfsym)`.
+ * Here, `annotations` are the annotations decorating the underlying type `underlying`.
+ * `selfSym` is a symbol representing the annotated type itself.
+ */
+ abstract class AnnotatedTypeExtractor {
+ def apply(annotations: List[AnnotationInfo], underlying: Type, selfsym: Symbol): AnnotatedType
+ def unapply(tpe: AnnotatedType): Option[(List[AnnotationInfo], Type, Symbol)]
+ }
+
+ /** The `TypeBounds` type signature is used to indicate lower and upper type bounds
+ * of type parameters and abstract types. It is not a first-class type.
+ * If an abstract type or type parameter is declared with any of the forms
+ * on the left, its type signature is the TypeBounds type on the right.
+ * {{{
+ * T >: L <: U TypeBounds(L, U)
+ * T >: L TypeBounds(L, Any)
+ * T <: U TypeBounds(Nothing, U)
+ * }}}
+ */
+ type TypeBounds >: Null <: AnyRef with Type
+
+ /** A tag that preserves the identity of the `TypeBounds` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val TypeBoundsTag: ClassTag[TypeBounds]
+
+ /** The constructor/deconstructor for `TypeBounds` instances. */
+ val TypeBounds: TypeBoundsExtractor
+
+ /** An extractor class to create and pattern match with syntax `TypeBound(lower, upper)`
+ * Here, `lower` is the lower bound of the `TypeBounds` pair, and `upper` is
+ * the upper bound.
+ */
+ abstract class TypeBoundsExtractor {
+ def apply(lo: Type, hi: Type): TypeBounds
+ def unapply(tpe: TypeBounds): Option[(Type, Type)]
+ }
+
+ /** An object representing an unknown type, used during type inference.
+ * If you see WildcardType outside of inference it is almost certainly a bug.
+ */
+ val WildcardType: Type
+
+ /** BoundedWildcardTypes, used only during type inference, are created in
+ * two places that I can find:
+ *
+ * 1. If the expected type of an expression is an existential type,
+ * its hidden symbols are replaced with bounded wildcards.
+ * 2. When an implicit conversion is being sought based in part on
+ * the name of a method in the converted type, a HasMethodMatching
+ * type is created: a MethodType with parameters typed as
+ * BoundedWildcardTypes.
+ */
+ type BoundedWildcardType >: Null <: AnyRef with Type
+
+ /** A tag that preserves the identity of the `BoundedWildcardType` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val BoundedWildcardTypeTag: ClassTag[BoundedWildcardType]
+
+ val BoundedWildcardType: BoundedWildcardTypeExtractor
+
+ abstract class BoundedWildcardTypeExtractor {
+ def apply(bounds: TypeBounds): BoundedWildcardType
+ def unapply(tpe: BoundedWildcardType): Option[TypeBounds]
+ }
+}
diff --git a/src/library/scala/reflect/base/Universe.scala b/src/library/scala/reflect/base/Universe.scala
new file mode 100644
index 0000000000..93ddcb9f55
--- /dev/null
+++ b/src/library/scala/reflect/base/Universe.scala
@@ -0,0 +1,18 @@
+package scala.reflect
+package base
+
+abstract class Universe extends Symbols
+ with Types
+ with FlagSets
+ with Scopes
+ with Names
+ with Trees
+ with Constants
+ with AnnotationInfos
+ with Positions
+ with TypeTags
+ with TagInterop
+ with StandardDefinitions
+ with StandardNames
+ with BuildUtils
+ with Mirrors \ No newline at end of file
diff --git a/src/library/scala/reflect/compat.scala b/src/library/scala/reflect/compat.scala
new file mode 100644
index 0000000000..7bfe9f38e1
--- /dev/null
+++ b/src/library/scala/reflect/compat.scala
@@ -0,0 +1,29 @@
+// [Eugene++] delete this once we merge with trunk and have a working IDE
+
+package scala.reflect {
+ trait ErasureTag[T]
+}
+
+package scala.reflect.api {
+ trait TypeTags {
+ trait TypeTag[T]
+ trait ConcreteTypeTag[T]
+ }
+}
+
+package scala {
+ import scala.reflect.base.{Universe => BaseUniverse}
+
+ trait reflect_compat {
+ lazy val mirror: BaseUniverse = ???
+ }
+}
+
+package scala.reflect {
+ import language.experimental.macros
+ import scala.reflect.base.{Universe => BaseUniverse}
+
+ trait internal_compat {
+ private[scala] def materializeErasureTag[T](u: BaseUniverse): ErasureTag[T] = ???
+ }
+} \ No newline at end of file
diff --git a/src/library/scala/reflect/makro/Aliases.scala b/src/library/scala/reflect/makro/Aliases.scala
index 38b1065a40..d7dd111f22 100644
--- a/src/library/scala/reflect/makro/Aliases.scala
+++ b/src/library/scala/reflect/makro/Aliases.scala
@@ -8,14 +8,16 @@ trait Aliases {
type Type = mirror.Type
type Name = mirror.Name
type Tree = mirror.Tree
- type Position = mirror.Position
+ // type Position = mirror.Position
type Scope = mirror.Scope
type Modifiers = mirror.Modifiers
type Expr[+T] = mirror.Expr[T]
type TypeTag[T] = mirror.TypeTag[T]
+ type ConcreteTypeTag[T] = mirror.ConcreteTypeTag[T]
/** Creator/extractor objects for Expr and TypeTag values */
val TypeTag = mirror.TypeTag
+ val ConcreteTypeTag = mirror.ConcreteTypeTag
val Expr = mirror.Expr
/** incantations for summoning tags */
diff --git a/src/library/scala/reflect/makro/Context.scala b/src/library/scala/reflect/makro/Context.scala
index b0e15fd572..fb77405d37 100644
--- a/src/library/scala/reflect/makro/Context.scala
+++ b/src/library/scala/reflect/makro/Context.scala
@@ -14,12 +14,13 @@ trait Context extends Aliases
with Reifiers
with FrontEnds
with Settings
- with Symbols
with Typers
+ with Exprs
+ with TypeTags
with Util {
/** The mirror that corresponds to the compile-time universe */
- val mirror: scala.reflect.api.Universe
+ val mirror: Universe
/** The type of the prefix tree from which the macro is selected */
type PrefixType
diff --git a/src/library/scala/reflect/makro/Exprs.scala b/src/library/scala/reflect/makro/Exprs.scala
new file mode 100644
index 0000000000..ab0ea83d73
--- /dev/null
+++ b/src/library/scala/reflect/makro/Exprs.scala
@@ -0,0 +1,7 @@
+package scala.reflect.makro
+
+trait Exprs {
+ self: Context =>
+
+ def Expr[T: TypeTag](tree: Tree): Expr[T]
+}
diff --git a/src/library/scala/reflect/makro/FrontEnds.scala b/src/library/scala/reflect/makro/FrontEnds.scala
index a1e24dcea3..d76907cdc8 100644
--- a/src/library/scala/reflect/makro/FrontEnds.scala
+++ b/src/library/scala/reflect/makro/FrontEnds.scala
@@ -1,10 +1,12 @@
package scala.reflect.makro
-trait FrontEnds {
+trait FrontEnds extends scala.reflect.api.FrontEnds {
self: Context =>
import mirror._
+ type Position = mirror.Position
+
/** Exposes means to control the compiler UI */
def frontEnd: FrontEnd
def setFrontEnd(frontEnd: FrontEnd): this.type
diff --git a/src/library/scala/reflect/makro/Reifiers.scala b/src/library/scala/reflect/makro/Reifiers.scala
index b1de8d9957..0e0a4a765e 100644
--- a/src/library/scala/reflect/makro/Reifiers.scala
+++ b/src/library/scala/reflect/makro/Reifiers.scala
@@ -72,6 +72,6 @@ trait Reifiers {
// made these guys non path-dependent, otherwise exception handling quickly becomes a mess
-case class ReificationError(var pos: reflect.api.Position, val msg: String) extends Throwable(msg)
+case class ReificationError(var pos: reflect.api.PositionApi, val msg: String) extends Throwable(msg)
-case class UnexpectedReificationError(val pos: reflect.api.Position, val msg: String, val cause: Throwable = null) extends Throwable(msg, cause) \ No newline at end of file
+case class UnexpectedReificationError(val pos: reflect.api.PositionApi, val msg: String, val cause: Throwable = null) extends Throwable(msg, cause)
diff --git a/src/library/scala/reflect/makro/Symbols.scala b/src/library/scala/reflect/makro/Symbols.scala
deleted file mode 100644
index ca1c17534c..0000000000
--- a/src/library/scala/reflect/makro/Symbols.scala
+++ /dev/null
@@ -1,24 +0,0 @@
-package scala.reflect.makro
-
-trait Symbols {
- self: Context =>
-
- /** Can this symbol be loaded by a reflective mirror?
- *
- * Scalac relies on `ScalaSignature' annotation to retain symbols across compilation runs.
- * Such annotations (also called "pickles") are applied on top-level classes and include information
- * about all symbols reachable from the annotee. However, local symbols (e.g. classes or definitions local to a block)
- * are typically unreachable and information about them gets lost.
- *
- * This method is useful for macro writers who wish to save certain ASTs to be used at runtime.
- * With `isLocatable' it's possible to check whether a tree can be retained as is, or it needs special treatment.
- */
- def isLocatable(sym: Symbol): Boolean
-
- /** Is this symbol static (i.e. with no outer instance)?
- * Q: When exactly is a sym marked as STATIC?
- * A: If it's a member of a toplevel object, or of an object contained in a toplevel object, or any number of levels deep.
- * http://groups.google.com/group/scala-internals/browse_thread/thread/d385bcd60b08faf6
- */
- def isStatic(sym: Symbol): Boolean
-} \ No newline at end of file
diff --git a/src/library/scala/reflect/makro/TreeBuilder.scala b/src/library/scala/reflect/makro/TreeBuilder.scala
new file mode 100644
index 0000000000..3510932c13
--- /dev/null
+++ b/src/library/scala/reflect/makro/TreeBuilder.scala
@@ -0,0 +1,59 @@
+package scala.reflect.makro
+
+// [Eugene] I added some stuff that was necessary for typetag materialization macros
+// but we should think it over and pick other generally useful stuff
+// same goes for tree traversers/transformers, type maps, etc
+// and once we expose all that, there's another question: how do we stay in sync?
+abstract class TreeBuilder {
+ val global: Universe
+
+ import global._
+ import definitions._
+
+ /** Builds a reference to value whose type is given stable prefix.
+ * The type must be suitable for this. For example, it
+ * must not be a TypeRef pointing to an abstract type variable.
+ */
+ def mkAttributedQualifier(tpe: Type): Tree
+
+ /** Builds a reference to value whose type is given stable prefix.
+ * If the type is unsuitable, e.g. it is a TypeRef for an
+ * abstract type variable, then an Ident will be made using
+ * termSym as the Ident's symbol. In that case, termSym must
+ * not be NoSymbol.
+ */
+ def mkAttributedQualifier(tpe: Type, termSym: Symbol): Tree
+
+ /** Builds a typed reference to given symbol with given stable prefix. */
+ def mkAttributedRef(pre: Type, sym: Symbol): Tree
+
+ /** Builds a typed reference to given symbol. */
+ def mkAttributedRef(sym: Symbol): Tree
+
+ /** Builds a typed This reference to given symbol. */
+ def mkAttributedThis(sym: Symbol): Tree
+
+ /** Builds a typed Ident with an underlying symbol. */
+ def mkAttributedIdent(sym: Symbol): Tree
+
+ /** Builds a typed Select with an underlying symbol. */
+ def mkAttributedSelect(qual: Tree, sym: Symbol): Tree
+
+ /** A creator for method calls, e.g. fn[T1, T2, ...](v1, v2, ...)
+ * There are a number of variations.
+ *
+ * @param receiver symbol of the method receiver
+ * @param methodName name of the method to call
+ * @param targs type arguments (if Nil, no TypeApply node will be generated)
+ * @param args value arguments
+ * @return the newly created trees.
+ */
+ def mkMethodCall(receiver: Symbol, methodName: Name, targs: List[Type], args: List[Tree]): Tree
+ def mkMethodCall(method: Symbol, targs: List[Type], args: List[Tree]): Tree
+ def mkMethodCall(method: Symbol, args: List[Tree]): Tree
+ def mkMethodCall(target: Tree, args: List[Tree]): Tree
+ def mkMethodCall(receiver: Symbol, methodName: Name, args: List[Tree]): Tree
+ def mkMethodCall(receiver: Tree, method: Symbol, targs: List[Type], args: List[Tree]): Tree
+ def mkMethodCall(target: Tree, targs: List[Type], args: List[Tree]): Tree
+ def mkNullaryCall(method: Symbol, targs: List[Type]): Tree
+}
diff --git a/src/library/scala/reflect/makro/TypeTags.scala b/src/library/scala/reflect/makro/TypeTags.scala
new file mode 100644
index 0000000000..7b98f391a7
--- /dev/null
+++ b/src/library/scala/reflect/makro/TypeTags.scala
@@ -0,0 +1,8 @@
+package scala.reflect.makro
+
+trait TypeTags {
+ self: Context =>
+
+ def TypeTag[T](tpe: Type): TypeTag[T]
+ def ConcreteTypeTag[T](tpe: Type): ConcreteTypeTag[T]
+}
diff --git a/src/library/scala/reflect/makro/Universe.scala b/src/library/scala/reflect/makro/Universe.scala
new file mode 100644
index 0000000000..d970e2474e
--- /dev/null
+++ b/src/library/scala/reflect/makro/Universe.scala
@@ -0,0 +1,117 @@
+package scala.reflect.makro
+
+abstract class Universe extends scala.reflect.api.Universe {
+
+ val treeBuild: TreeBuilder { val global: Universe.this.type }
+
+ // Symbol extensions ---------------------------------------------------------------
+
+ override type Symbol >: Null <: SymbolContextApi
+
+ /** The extended API of symbols that's supported in macro context universes
+ */
+ trait SymbolContextApi extends SymbolApi { this: Symbol =>
+
+ // [Eugene++ to Martin] should we also add mutability methods here (similarly to what's done below for trees)?
+ // I'm talking about `setAnnotations` and friends
+
+ /** Can this symbol be loaded by a reflective mirror?
+ *
+ * Scalac relies on `ScalaSignature' annotation to retain symbols across compilation runs.
+ * Such annotations (also called "pickles") are applied on top-level classes and include information
+ * about all symbols reachable from the annotee. However, local symbols (e.g. classes or definitions local to a block)
+ * are typically unreachable and information about them gets lost.
+ *
+ * This method is useful for macro writers who wish to save certain ASTs to be used at runtime.
+ * With `isLocatable' it's possible to check whether a tree can be retained as is, or it needs special treatment.
+ */
+ def isLocatable: Boolean
+
+ /** Is this symbol static (i.e. with no outer instance)?
+ * Q: When exactly is a sym marked as STATIC?
+ * A: If it's a member of a toplevel object, or of an object contained in a toplevel object, or any number of levels deep.
+ * http://groups.google.com/group/scala-internals/browse_thread/thread/d385bcd60b08faf6
+ */
+ def isStatic: Boolean
+ }
+
+ // Tree extensions ---------------------------------------------------------------
+
+ override type Tree >: Null <: TreeContextApi
+
+ /** The extended API of trees that's supported in macro context universes
+ */
+ trait TreeContextApi extends TreeApi { this: Tree =>
+
+ /** ... */
+ def pos_=(pos: Position): Unit
+
+ /** ... */
+ def setPos(newpos: Position): this.type
+
+ /** ... */
+ def tpe_=(t: Type): Unit
+
+ /** Set tpe to give `tp` and return this.
+ */
+ def setType(tp: Type): this.type
+
+ /** Like `setType`, but if this is a previously empty TypeTree that
+ * fact is remembered so that resetAllAttrs will snap back.
+ *
+ * @PP: Attempting to elaborate on the above, I find: If defineType
+ * is called on a TypeTree whose type field is null or NoType,
+ * this is recorded as "wasEmpty = true". That value is used in
+ * ResetAttrsTraverser, which nulls out the type field of TypeTrees
+ * for which wasEmpty is true, leaving the others alone.
+ *
+ * resetAllAttrs is used in situations where some speculative
+ * typing of a tree takes place, fails, and the tree needs to be
+ * returned to its former state to try again. So according to me:
+ * using `defineType` instead of `setType` is how you communicate
+ * that the type being set does not depend on any previous state,
+ * and therefore should be abandoned if the current line of type
+ * inquiry doesn't work out.
+ */
+ def defineType(tp: Type): this.type
+
+ /** ... */
+ def symbol_=(sym: Symbol): Unit
+
+ /** ... */
+ def setSymbol(sym: Symbol): this.type
+
+ /** ... */
+ def attachments: scala.reflect.base.Attachments { type Pos = Position }
+
+ /** ... */
+ def addAttachment(attachment: Any): this.type
+
+ /** ... */
+ def removeAttachment[T: ClassTag]: this.type
+ }
+
+ override type SymTree >: Null <: Tree with SymTreeContextApi
+
+ /** The extended API of sym trees that's supported in macro context universes
+ */
+ trait SymTreeContextApi extends SymTreeApi { this: SymTree =>
+ var symbol: Symbol
+ }
+
+ override type TypeTree >: Null <: TypTree with TypeTreeContextApi
+
+ /** The extended API of sym trees that's supported in macro context universes
+ */
+ trait TypeTreeContextApi extends TypeTreeApi { this: TypeTree =>
+ def setOriginal(tree: Tree): this.type
+ }
+
+ override type Ident >: Null <: RefTree with IdentContextApi
+
+ /** The extended API of idents that's supported in macro context universes
+ */
+ trait IdentContextApi extends IdentApi { this: Ident =>
+ def isBackquoted: Boolean
+ }
+} \ No newline at end of file
diff --git a/src/library/scala/reflect/makro/internal/package.scala b/src/library/scala/reflect/makro/internal/package.scala
index 4c4acec096..c0518384ab 100644
--- a/src/library/scala/reflect/makro/internal/package.scala
+++ b/src/library/scala/reflect/makro/internal/package.scala
@@ -1,17 +1,16 @@
package scala.reflect.makro
import language.experimental.macros
-import scala.reflect.api.{Universe => ApiUniverse}
+import scala.reflect.base.{Universe => BaseUniverse}
// anchors for materialization macros emitted during tag materialization in Implicits.scala
// implementation is magically hardwired into `scala.reflect.reify.Taggers`
//
// todo. once we have implicit macros for tag generation, we can remove these anchors
// [Eugene++] how do I hide this from scaladoc?
-package object internal {
- private[scala] def materializeArrayTag[T](u: ApiUniverse): ArrayTag[T] = macro ???
- private[scala] def materializeErasureTag[T](u: ApiUniverse): ErasureTag[T] = macro ???
- private[scala] def materializeClassTag[T](u: ApiUniverse): ClassTag[T] = macro ???
- private[scala] def materializeTypeTag[T](u: ApiUniverse): u.TypeTag[T] = macro ???
- private[scala] def materializeConcreteTypeTag[T](u: ApiUniverse): u.ConcreteTypeTag[T] = macro ???
+package object internal extends scala.reflect.internal_compat {
+ private[scala] def materializeArrayTag[T](u: BaseUniverse): ArrayTag[T] = macro ???
+ private[scala] def materializeClassTag[T](u: BaseUniverse): ClassTag[T] = macro ???
+ private[scala] def materializeTypeTag[T](u: BaseUniverse): u.TypeTag[T] = macro ???
+ private[scala] def materializeConcreteTypeTag[T](u: BaseUniverse): u.ConcreteTypeTag[T] = macro ???
}
diff --git a/src/library/scala/reflect/package.scala b/src/library/scala/reflect/package.scala
index 38a144cd49..ba93a1c91f 100644
--- a/src/library/scala/reflect/package.scala
+++ b/src/library/scala/reflect/package.scala
@@ -1,42 +1,8 @@
package scala
-package object reflect {
+package object reflect extends reflect_compat {
- import ReflectionUtils._
- import scala.compat.Platform.EOL
-
- // !!! This was a val; we can't throw exceptions that aggressively without breaking
- // non-standard environments, e.g. google app engine. I made it a lazy val, but
- // I think it would be better yet to throw the exception somewhere else - not during
- // initialization, but in response to a doomed attempt to utilize it.
-
- // todo. default mirror (a static object) might become a source for memory leaks (because it holds a strong reference to a classloader)!
- lazy val mirror: api.Mirror =
- try mkMirror(defaultReflectionClassLoader)
- catch {
- case ex: UnsupportedOperationException =>
- new DummyMirror(defaultReflectionClassLoader)
- }
-
- private[scala] def mirrorDiagnostics(cl: ClassLoader): String = """
- |
- | This error has happened because `scala.reflect.runtime.package` located in
- | scala-compiler.jar cannot be loaded. Classloader you are using is:
- | %s.
- |
- | For the instructions for some of the situations that might be relevant
- | visit our knowledge base at https://gist.github.com/2391081.
- """.stripMargin('|').format(show(cl))
-
- def mkMirror(classLoader: ClassLoader): api.Mirror = {
- val coreClassLoader = getClass.getClassLoader
- val instance = invokeFactoryOpt(coreClassLoader, "scala.reflect.runtime.package", "mkMirror", classLoader)
- instance match {
- case Some(x: api.Mirror) => x
- case Some(_) => throw new UnsupportedOperationException("Available scala reflection implementation is incompatible with this interface." + mirrorDiagnostics(coreClassLoader))
- case None => throw new UnsupportedOperationException("Scala reflection not available on this platform." + mirrorDiagnostics(coreClassLoader))
- }
- }
+ lazy val basis: base.Universe = new base.Base
@deprecated("Use `@scala.beans.BeanDescription` instead", "2.10.0")
type BeanDescription = scala.beans.BeanDescription
@@ -53,18 +19,12 @@ package object reflect {
@deprecated("Use `@scala.beans.ScalaBeanInfo` instead", "2.10.0")
type ScalaBeanInfo = scala.beans.ScalaBeanInfo
- // ArrayTag trait is defined separately from the mirror
- // ErasureTag trait is defined separately from the mirror
- // ConcreteErasureTag trait is defined separately from the mirror
- // ClassTag class is defined separately from the mirror
- type TypeTag[T] = scala.reflect.mirror.TypeTag[T]
- type ConcreteTypeTag[T] = scala.reflect.mirror.ConcreteTypeTag[T]
-
- // ClassTag object is defined separately from the mirror
- lazy val TypeTag = scala.reflect.mirror.TypeTag
- lazy val ConcreteTypeTag = scala.reflect.mirror.ConcreteTypeTag
+ // ArrayTag trait is defined outside the basis
+ // ClassTag class is defined outside the basis
+ type TypeTag[T] = scala.reflect.basis.TypeTag[T]
+ type ConcreteTypeTag[T] = scala.reflect.basis.ConcreteTypeTag[T]
- def arrayTagToClassManifest[T](tag: ArrayTag[T]): ClassManifest[T] = TagInterop.arrayTagToClassManifest[T](tag)
- def concreteTypeTagToManifest[T](tag: ConcreteTypeTag[T]): Manifest[T] = TagInterop.concreteTypeTagToManifest[T](tag)
- def manifestToConcreteTypeTag[T](tag: Manifest[T]): ConcreteTypeTag[T] = TagInterop.manifestToConcreteTypeTag[T](tag)
+ // ClassTag object is defined outside the basis
+ lazy val TypeTag = scala.reflect.basis.TypeTag
+ lazy val ConcreteTypeTag = scala.reflect.basis.ConcreteTypeTag
}
diff --git a/src/partest/scala/tools/partest/CompilerTest.scala b/src/partest/scala/tools/partest/CompilerTest.scala
index 86678760be..89c1a9c2ca 100644
--- a/src/partest/scala/tools/partest/CompilerTest.scala
+++ b/src/partest/scala/tools/partest/CompilerTest.scala
@@ -5,7 +5,7 @@
package scala.tools.partest
-import scala.reflect.{mirror => rm}
+import scala.reflect.{basis => rb}
import scala.tools.nsc._
/** For testing compiler internals directly.
@@ -34,7 +34,7 @@ abstract class CompilerTest extends DirectTest {
// Utility functions
class MkType(sym: Symbol) {
- def apply[M](implicit t: rm.TypeTag[M]): Type =
+ def apply[M](implicit t: rb.TypeTag[M]): Type =
if (sym eq NoSymbol) NoType
else appliedType(sym, compilerTypeFromTag(t))
}
@@ -50,7 +50,7 @@ abstract class CompilerTest extends DirectTest {
}
class SymsInPackage(pkgName: String) {
- def pkg = getRequiredModule(pkgName)
+ def pkg = rootMirror.getRequiredModule(pkgName)
def classes = allMembers(pkg) filter (_.isClass)
def modules = allMembers(pkg) filter (_.isModule)
def symbols = classes ++ terms filterNot (_ eq NoSymbol)