From 6bb5975289c5b11cb8c88dd4629286956b5d3d27 Mon Sep 17 00:00:00 2001
From: Eugene Burmako
Date: Wed, 6 Jun 2012 02:46:31 +0200
Subject: The new reflection
A must read: "SIP: Scala Reflection":
https://docs.google.com/document/d/1Z1VhhNPplbUpaZPIYdc0_EUv5RiGQ2X4oqp0i-vz1qw/edit
Highlights:
* Architecture has undergone a dramatic rehash.
* Universes and mirrors are now separate entities:
universes host reflection artifacts (trees, symbols, types, etc),
mirrors abstract loading of those artifacts (e.g. JavaMirror loads stuff
using a classloader and annotation unpickler, while GlobalMirror uses
internal compiler classreader to achieve the same goal).
* No static reflection mirror is imposed on the user.
One is free to choose between lightweight mirrors and full-blown
classloader-based mirror (read below).
* Public reflection API is split into scala.reflect.base and scala.reflect.api.
The former represents a minimalistic snapshot that is exactly enough to
build reified trees and types. To build, but not to analyze - everything smart
(for example, getting a type signature) is implemented in scala.reflect.api.
* Both reflection domains have their own universe: scala.reflect.basis and
scala.reflect.runtime.universe. The former is super lightweight and doesn't
involve any classloaders, while the latter represents a stripped down compiler.
* Classloader problems from 2.10.0-M3 are solved.
* Exprs and type tags are now bound to a mirror upon creation.
* However there is an easy way to migrate exprs and type tags between mirrors
and even between universes.
* This means that no classloader is imposed on the user of type tags and exprs.
If one doesn't like a classloader that's there (associated with tag's mirror),
one can create a custom mirror and migrate the tag or the expr to it.
* There is a shortcut that works in most cases. Requesting a type tag from
a full-blown universe will create that tag in a mirror that corresponds to
the callsite classloader aka `getClass.getClassLoader`. This imposes no
obligations on the programmer, since Type construction is lazy, so one
can always migrate a tag into a different mirror.
Migration notes for 2.10.0-M3 users:
* Incantations in Predef are gone, some of them have moved to scala.reflect.
* Everything path-dependent requires implicit prefix (for example, to refer
to a type tag, you need to explicitly specify the universe it belongs to,
e.g. reflect.basis.TypeTag or reflect.runtime.universe.TypeTag).
* ArrayTags have been removed, ConcreteTypeTag have been renamed to TypeTags,
TypeTags have been renamed to AbsTypeTags. Look for the reasoning in the
nearby children of this commit. Why not in this commit? Scroll this message
to the very bottom to find out the reason.
* Some of the functions have been renamed or moved around.
The rule of thumb is to look for anything non-trivial in scala.reflect.api.
Some of tree build utils have been moved to Universe.build.
* staticModule and staticClass have been moved from universes to mirrors
* ClassTag.erasure => ClassTag.runtimeClass
* For the sake of purity, type tags no longer have erasures.
Use multiple context bounds (e.g. def foo[T: ru.TypeTag : ClassTag](...) = ...)
if you're interested in having both erasures and types for type parameters.
* reify now rolls back macro applications.
* Runtime evaluation is now explicit, requires import scala.tools.reflect.Eval
and scala-compiler.jar on the classpath.
* Macro context now has separate universe and mirror fields.
* Most of the useful stuff is declared in c.universe,
so be sure to change your "import c.universe._" to "import c.mirror._".
* Due to the changes in expressions and type tags, their regular factories
are now really difficult to use. We acknowledge that macro users need to
frequently create exprs and tags, so we added old-style factories to context.
Bottom line: almost always prepend Expr(...)/TypeTag(...) with "c.".
* Expr.eval has been renamed to Expr.splice.
* Expr.value no longer splices (it can still be used to express cross-stage
path-dependent types as specified in SIP-16).
* c.reifyTree now has a mirror parameter that lets one customize the initial
mirror the resulting Expr will be bound to. If you provide EmptyTree, then
the reifier will automatically pick a reasonable mirror (callsite classloader
mirror for a full-blown universe and rootMirror for a basis universe).
Bottom line: this parameter should be EmptyTree in 99% of cases.
* c.reifyErasure => c.reifyRuntimeClass.
Known issues:
* API is really raw, need your feedback.
* All reflection artifacts are now represented by abstract types.
This means that pattern matching against them will emit unchecked warnings.
Adriaan is working on a patch that will fix that.
WARNING, FELLOW CODE EXPLORER! You have entered a turbulence zone.
For this commit and its nearby parents and children
tests are not guaranteed to work. Things get back to normal only after
the "repairs the tests after the refactoring spree" commit.
Why so weird? These twentish changesets were once parts of a humongous blob,
which spanned 1200 files and 15 kLOC. I did my best to split up the blob,
so that the individual parts of the code compile and make sense in isolation.
However doing the same for tests would be too much work.
---
lib/scala-compiler.jar.desired.sha1 | 2 +-
lib/scala-library.jar.desired.sha1 | 2 +-
src/compiler/scala/reflect/api/JavaUniverse.scala | 19 +
src/compiler/scala/reflect/api/TagInterop.scala | 38 +
.../scala/reflect/internal/AbstractFileApi.scala | 7 +
.../scala/reflect/internal/AnnotationInfos.scala | 16 +-
.../scala/reflect/internal/BuildUtils.scala | 69 +
.../scala/reflect/internal/Constants.scala | 4 +-
.../scala/reflect/internal/Definitions.scala | 515 ++----
src/compiler/scala/reflect/internal/FlagSets.scala | 66 +
src/compiler/scala/reflect/internal/Flags.scala | 41 -
src/compiler/scala/reflect/internal/FreeVars.scala | 60 -
.../scala/reflect/internal/FrontEnds.scala | 75 -
src/compiler/scala/reflect/internal/HasFlags.scala | 1 +
.../scala/reflect/internal/Importers.scala | 9 +-
src/compiler/scala/reflect/internal/Mirrors.scala | 243 +++
src/compiler/scala/reflect/internal/Names.scala | 10 +-
.../scala/reflect/internal/Positions.scala | 1 +
src/compiler/scala/reflect/internal/Required.scala | 2 +-
src/compiler/scala/reflect/internal/Scopes.scala | 2 +
.../scala/reflect/internal/StdAttachments.scala | 2 +
.../scala/reflect/internal/StdCreators.scala | 21 +
src/compiler/scala/reflect/internal/StdNames.scala | 286 +--
.../scala/reflect/internal/SymbolTable.scala | 23 +-
src/compiler/scala/reflect/internal/Symbols.scala | 164 +-
.../scala/reflect/internal/TreeBuildUtil.scala | 66 -
src/compiler/scala/reflect/internal/TreeGen.scala | 10 +-
src/compiler/scala/reflect/internal/TreeInfo.scala | 35 +-
.../scala/reflect/internal/TreePrinters.scala | 6 +-
src/compiler/scala/reflect/internal/Trees.scala | 1325 +++++++++++++-
src/compiler/scala/reflect/internal/Types.scala | 75 +-
src/compiler/scala/reflect/internal/package.scala | 6 +
.../reflect/internal/pickling/UnPickler.scala | 15 +-
.../internal/util/TraceSymbolActivity.scala | 2 +-
.../makro/runtime/AbortMacroException.scala | 2 +-
.../scala/reflect/makro/runtime/Aliases.scala | 4 +-
.../scala/reflect/makro/runtime/Context.scala | 3 +-
.../scala/reflect/makro/runtime/Exprs.scala | 8 +
.../scala/reflect/makro/runtime/FrontEnds.scala | 4 +-
.../scala/reflect/makro/runtime/Reifiers.scala | 18 +-
.../scala/reflect/makro/runtime/Symbols.scala | 10 -
.../scala/reflect/makro/runtime/TypeTags.scala | 9 +
.../scala/reflect/reify/NodePrinters.scala | 89 +-
src/compiler/scala/reflect/reify/Taggers.scala | 17 +-
.../scala/reflect/reify/codegen/Symbols.scala | 14 +-
.../scala/reflect/reify/codegen/Trees.scala | 6 +-
.../scala/reflect/runtime/AbstractFile.scala | 2 +-
.../scala/reflect/runtime/ClassLoaders.scala | 25 -
.../scala/reflect/runtime/ConversionUtil.scala | 92 -
.../scala/reflect/runtime/JavaMirrors.scala | 981 ++++++++++
.../scala/reflect/runtime/JavaToScala.scala | 697 --------
.../scala/reflect/runtime/JavaUniverse.scala | 33 +
src/compiler/scala/reflect/runtime/Mirror.scala | 85 -
.../scala/reflect/runtime/ReflectSetup.scala | 12 +
.../scala/reflect/runtime/ReflectionUtils.scala | 80 +
.../scala/reflect/runtime/ScalaToJava.scala | 87 -
.../scala/reflect/runtime/SymbolLoaders.scala | 55 +-
.../scala/reflect/runtime/SymbolTable.scala | 5 +-
.../reflect/runtime/SynchronizedSymbols.scala | 14 +-
.../scala/reflect/runtime/SynchronizedTypes.scala | 13 +-
src/compiler/scala/reflect/runtime/ToolBoxes.scala | 351 ----
.../scala/reflect/runtime/TwoWayCache.scala | 52 +
src/compiler/scala/reflect/runtime/Universe.scala | 43 -
src/compiler/scala/reflect/runtime/package.scala | 12 +-
src/compiler/scala/tools/cmd/FromString.scala | 3 +-
src/compiler/scala/tools/nsc/ClassLoaders.scala | 64 -
src/compiler/scala/tools/nsc/Global.scala | 77 +-
src/compiler/scala/tools/nsc/ReflectGlobal.scala | 28 +-
src/compiler/scala/tools/nsc/ReflectMain.scala | 7 +-
src/compiler/scala/tools/nsc/ReflectSetup.scala | 7 +
src/compiler/scala/tools/nsc/ToolBoxes.scala | 84 -
src/compiler/scala/tools/nsc/ast/DocComments.scala | 4 +-
src/compiler/scala/tools/nsc/ast/FreeVars.scala | 26 -
.../scala/tools/nsc/ast/NodePrinters.scala | 2 +-
.../scala/tools/nsc/ast/TreeBrowsers.scala | 2 +-
src/compiler/scala/tools/nsc/ast/Trees.scala | 5 +-
.../scala/tools/nsc/ast/parser/Parsers.scala | 2 +-
.../scala/tools/nsc/ast/parser/TreeBuilder.scala | 5 +-
.../scala/tools/nsc/backend/jvm/GenASM.scala | 10 +-
.../scala/tools/nsc/backend/jvm/GenAndroid.scala | 4 +-
.../scala/tools/nsc/backend/jvm/GenJVM.scala | 8 +-
.../scala/tools/nsc/doc/Uncompilable.scala | 3 +-
.../scala/tools/nsc/doc/model/ModelFactory.scala | 5 +-
.../scala/tools/nsc/interactive/Picklers.scala | 2 +-
.../tools/nsc/interactive/RangePositions.scala | 2 +-
.../scala/tools/nsc/interpreter/ILoop.scala | 4 +-
.../scala/tools/nsc/interpreter/IMain.scala | 55 +-
.../tools/nsc/interpreter/JLineCompletion.scala | 3 +-
.../scala/tools/nsc/interpreter/NamedParam.scala | 11 +-
.../scala/tools/nsc/interpreter/Power.scala | 40 +-
.../scala/tools/nsc/interpreter/ReplVals.scala | 9 +-
.../scala/tools/nsc/interpreter/TypeStrings.scala | 22 +-
src/compiler/scala/tools/nsc/io/AbstractFile.scala | 3 +-
.../scala/tools/nsc/scratchpad/Executor.scala | 2 +-
.../nsc/symtab/classfile/ClassfileParser.scala | 14 +-
.../tools/nsc/symtab/classfile/ICodeReader.scala | 8 +-
.../scala/tools/nsc/symtab/clr/TypeParser.scala | 2 +-
.../scala/tools/nsc/transform/ExplicitOuter.scala | 2 +-
.../tools/nsc/transform/ExtensionMethods.scala | 6 +-
src/compiler/scala/tools/nsc/transform/Mixin.scala | 2 +-
.../tools/nsc/transform/SpecializeTypes.scala | 15 +-
.../scala/tools/nsc/typechecker/Contexts.scala | 8 +-
.../tools/nsc/typechecker/DestructureTypes.scala | 2 +-
.../scala/tools/nsc/typechecker/Implicits.scala | 33 +-
.../scala/tools/nsc/typechecker/Infer.scala | 2 +-
.../scala/tools/nsc/typechecker/Macros.scala | 26 +-
.../tools/nsc/typechecker/MethodSynthesis.scala | 35 +-
.../scala/tools/nsc/typechecker/Namers.scala | 2 +-
.../tools/nsc/typechecker/PatternMatching.scala | 12 +-
.../scala/tools/nsc/typechecker/RefChecks.scala | 2 +-
.../tools/nsc/typechecker/SuperAccessors.scala | 4 +-
.../tools/nsc/typechecker/SyntheticMethods.scala | 4 +-
.../scala/tools/nsc/typechecker/Taggings.scala | 2 +-
.../scala/tools/nsc/typechecker/TreeCheckers.scala | 2 +-
.../scala/tools/nsc/typechecker/Typers.scala | 14 +-
.../scala/tools/nsc/typechecker/Unapplies.scala | 5 +-
src/compiler/scala/tools/nsc/util/Position.scala | 43 +-
.../scala/tools/nsc/util/ScalaClassLoader.scala | 2 +-
src/compiler/scala/tools/reflect/FastTrack.scala | 1 -
src/compiler/scala/tools/reflect/FrontEnds.scala | 77 +
src/compiler/scala/tools/reflect/StdTags.scala | 31 +-
src/compiler/scala/tools/reflect/ToolBox.scala | 93 +
.../scala/tools/reflect/ToolBoxFactory.scala | 374 ++++
src/compiler/scala/tools/reflect/package.scala | 33 +
.../plugin/scala/tools/selectivecps/CPSUtils.scala | 16 +-
.../tools/selectivecps/SelectiveCPSTransform.scala | 2 +-
src/library/scala/Predef.scala | 2 -
src/library/scala/ref/WeakReference.scala | 16 +
src/library/scala/reflect/ArrayTag.scala | 2 +-
src/library/scala/reflect/ClassTag.scala | 8 +-
src/library/scala/reflect/DummyMirror.scala | 783 --------
src/library/scala/reflect/ErasureTag.scala | 23 -
src/library/scala/reflect/Manifest.scala | 1 -
src/library/scala/reflect/ReflectionUtils.scala | 90 -
src/library/scala/reflect/TagInterop.scala | 34 -
.../scala/reflect/api/AnnotationInfos.scala | 47 +-
src/library/scala/reflect/api/Attachment.scala | 29 -
src/library/scala/reflect/api/ClassLoaders.scala | 16 -
src/library/scala/reflect/api/Constants.scala | 18 +-
src/library/scala/reflect/api/Exprs.scala | 53 +-
src/library/scala/reflect/api/FlagSets.scala | 112 ++
src/library/scala/reflect/api/FreeVars.scala | 42 -
src/library/scala/reflect/api/FrontEnds.scala | 6 +-
src/library/scala/reflect/api/Importers.scala | 2 +
src/library/scala/reflect/api/Mirror.scala | 100 --
src/library/scala/reflect/api/Mirrors.scala | 213 +++
src/library/scala/reflect/api/Modifier.scala | 82 -
src/library/scala/reflect/api/Names.scala | 40 +-
src/library/scala/reflect/api/Positions.scala | 62 +-
src/library/scala/reflect/api/RequiredFile.scala | 7 -
src/library/scala/reflect/api/Scopes.scala | 16 -
.../scala/reflect/api/StandardDefinitions.scala | 169 +-
src/library/scala/reflect/api/StandardNames.scala | 31 +-
src/library/scala/reflect/api/Symbols.scala | 330 ++--
src/library/scala/reflect/api/ToolBoxes.scala | 90 -
src/library/scala/reflect/api/TreeBuildUtil.scala | 159 --
src/library/scala/reflect/api/TreePrinters.scala | 27 +-
src/library/scala/reflect/api/Trees.scala | 1871 +++++---------------
src/library/scala/reflect/api/TypeTags.scala | 254 ---
src/library/scala/reflect/api/Types.scala | 362 +---
src/library/scala/reflect/api/Universe.scala | 33 +-
src/library/scala/reflect/api/package.scala | 12 +
.../scala/reflect/base/AnnotationInfos.scala | 44 +
src/library/scala/reflect/base/Attachments.scala | 42 +
src/library/scala/reflect/base/Base.scala | 763 ++++++++
src/library/scala/reflect/base/BuildUtils.scala | 90 +
src/library/scala/reflect/base/Constants.scala | 20 +
src/library/scala/reflect/base/FlagSets.scala | 17 +
src/library/scala/reflect/base/MirrorOf.scala | 25 +
src/library/scala/reflect/base/Mirrors.scala | 12 +
src/library/scala/reflect/base/Names.scala | 53 +
src/library/scala/reflect/base/Positions.scala | 22 +
src/library/scala/reflect/base/Scopes.scala | 21 +
.../scala/reflect/base/StandardDefinitions.scala | 75 +
src/library/scala/reflect/base/StandardNames.scala | 29 +
src/library/scala/reflect/base/Symbols.scala | 272 +++
src/library/scala/reflect/base/TagInterop.scala | 29 +
src/library/scala/reflect/base/TreeCreator.scala | 6 +
src/library/scala/reflect/base/Trees.scala | 1459 +++++++++++++++
src/library/scala/reflect/base/TypeCreator.scala | 6 +
src/library/scala/reflect/base/TypeTags.scala | 253 +++
src/library/scala/reflect/base/Types.scala | 432 +++++
src/library/scala/reflect/base/Universe.scala | 18 +
src/library/scala/reflect/compat.scala | 29 +
src/library/scala/reflect/makro/Aliases.scala | 4 +-
src/library/scala/reflect/makro/Context.scala | 5 +-
src/library/scala/reflect/makro/Exprs.scala | 7 +
src/library/scala/reflect/makro/FrontEnds.scala | 4 +-
src/library/scala/reflect/makro/Reifiers.scala | 4 +-
src/library/scala/reflect/makro/Symbols.scala | 24 -
src/library/scala/reflect/makro/TreeBuilder.scala | 59 +
src/library/scala/reflect/makro/TypeTags.scala | 8 +
src/library/scala/reflect/makro/Universe.scala | 117 ++
.../scala/reflect/makro/internal/package.scala | 13 +-
src/library/scala/reflect/package.scala | 58 +-
src/partest/scala/tools/partest/CompilerTest.scala | 6 +-
196 files changed, 9590 insertions(+), 6992 deletions(-)
create mode 100644 src/compiler/scala/reflect/api/JavaUniverse.scala
create mode 100644 src/compiler/scala/reflect/api/TagInterop.scala
create mode 100644 src/compiler/scala/reflect/internal/AbstractFileApi.scala
create mode 100644 src/compiler/scala/reflect/internal/BuildUtils.scala
create mode 100644 src/compiler/scala/reflect/internal/FlagSets.scala
delete mode 100644 src/compiler/scala/reflect/internal/FreeVars.scala
delete mode 100644 src/compiler/scala/reflect/internal/FrontEnds.scala
create mode 100644 src/compiler/scala/reflect/internal/Mirrors.scala
create mode 100644 src/compiler/scala/reflect/internal/StdCreators.scala
delete mode 100644 src/compiler/scala/reflect/internal/TreeBuildUtil.scala
create mode 100644 src/compiler/scala/reflect/internal/package.scala
create mode 100644 src/compiler/scala/reflect/makro/runtime/Exprs.scala
delete mode 100644 src/compiler/scala/reflect/makro/runtime/Symbols.scala
create mode 100644 src/compiler/scala/reflect/makro/runtime/TypeTags.scala
delete mode 100644 src/compiler/scala/reflect/runtime/ClassLoaders.scala
delete mode 100644 src/compiler/scala/reflect/runtime/ConversionUtil.scala
create mode 100644 src/compiler/scala/reflect/runtime/JavaMirrors.scala
delete mode 100644 src/compiler/scala/reflect/runtime/JavaToScala.scala
create mode 100644 src/compiler/scala/reflect/runtime/JavaUniverse.scala
delete mode 100644 src/compiler/scala/reflect/runtime/Mirror.scala
create mode 100644 src/compiler/scala/reflect/runtime/ReflectSetup.scala
create mode 100644 src/compiler/scala/reflect/runtime/ReflectionUtils.scala
delete mode 100644 src/compiler/scala/reflect/runtime/ScalaToJava.scala
delete mode 100644 src/compiler/scala/reflect/runtime/ToolBoxes.scala
create mode 100644 src/compiler/scala/reflect/runtime/TwoWayCache.scala
delete mode 100644 src/compiler/scala/reflect/runtime/Universe.scala
delete mode 100644 src/compiler/scala/tools/nsc/ClassLoaders.scala
create mode 100644 src/compiler/scala/tools/nsc/ReflectSetup.scala
delete mode 100644 src/compiler/scala/tools/nsc/ToolBoxes.scala
delete mode 100644 src/compiler/scala/tools/nsc/ast/FreeVars.scala
create mode 100644 src/compiler/scala/tools/reflect/FrontEnds.scala
create mode 100644 src/compiler/scala/tools/reflect/ToolBox.scala
create mode 100644 src/compiler/scala/tools/reflect/ToolBoxFactory.scala
create mode 100644 src/compiler/scala/tools/reflect/package.scala
delete mode 100644 src/library/scala/reflect/DummyMirror.scala
delete mode 100644 src/library/scala/reflect/ErasureTag.scala
delete mode 100644 src/library/scala/reflect/ReflectionUtils.scala
delete mode 100644 src/library/scala/reflect/TagInterop.scala
delete mode 100644 src/library/scala/reflect/api/Attachment.scala
delete mode 100644 src/library/scala/reflect/api/ClassLoaders.scala
create mode 100644 src/library/scala/reflect/api/FlagSets.scala
delete mode 100644 src/library/scala/reflect/api/FreeVars.scala
delete mode 100644 src/library/scala/reflect/api/Mirror.scala
create mode 100644 src/library/scala/reflect/api/Mirrors.scala
delete mode 100644 src/library/scala/reflect/api/Modifier.scala
delete mode 100644 src/library/scala/reflect/api/RequiredFile.scala
delete mode 100755 src/library/scala/reflect/api/Scopes.scala
delete mode 100644 src/library/scala/reflect/api/ToolBoxes.scala
delete mode 100644 src/library/scala/reflect/api/TreeBuildUtil.scala
delete mode 100644 src/library/scala/reflect/api/TypeTags.scala
create mode 100644 src/library/scala/reflect/api/package.scala
create mode 100644 src/library/scala/reflect/base/AnnotationInfos.scala
create mode 100644 src/library/scala/reflect/base/Attachments.scala
create mode 100644 src/library/scala/reflect/base/Base.scala
create mode 100644 src/library/scala/reflect/base/BuildUtils.scala
create mode 100644 src/library/scala/reflect/base/Constants.scala
create mode 100644 src/library/scala/reflect/base/FlagSets.scala
create mode 100644 src/library/scala/reflect/base/MirrorOf.scala
create mode 100644 src/library/scala/reflect/base/Mirrors.scala
create mode 100644 src/library/scala/reflect/base/Names.scala
create mode 100644 src/library/scala/reflect/base/Positions.scala
create mode 100644 src/library/scala/reflect/base/Scopes.scala
create mode 100644 src/library/scala/reflect/base/StandardDefinitions.scala
create mode 100644 src/library/scala/reflect/base/StandardNames.scala
create mode 100644 src/library/scala/reflect/base/Symbols.scala
create mode 100644 src/library/scala/reflect/base/TagInterop.scala
create mode 100644 src/library/scala/reflect/base/TreeCreator.scala
create mode 100644 src/library/scala/reflect/base/Trees.scala
create mode 100644 src/library/scala/reflect/base/TypeCreator.scala
create mode 100644 src/library/scala/reflect/base/TypeTags.scala
create mode 100644 src/library/scala/reflect/base/Types.scala
create mode 100644 src/library/scala/reflect/base/Universe.scala
create mode 100644 src/library/scala/reflect/compat.scala
create mode 100644 src/library/scala/reflect/makro/Exprs.scala
delete mode 100644 src/library/scala/reflect/makro/Symbols.scala
create mode 100644 src/library/scala/reflect/makro/TreeBuilder.scala
create mode 100644 src/library/scala/reflect/makro/TypeTags.scala
create mode 100644 src/library/scala/reflect/makro/Universe.scala
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/compiler/scala/reflect/internal/AbstractFileApi.scala b/src/compiler/scala/reflect/internal/AbstractFileApi.scala
new file mode 100644
index 0000000000..9f37f4536f
--- /dev/null
+++ b/src/compiler/scala/reflect/internal/AbstractFileApi.scala
@@ -0,0 +1,7 @@
+package scala.reflect
+package internal
+
+trait AbstractFileApi {
+ def path: String
+ def canonicalPath: String
+}
diff --git a/src/compiler/scala/reflect/internal/AnnotationInfos.scala b/src/compiler/scala/reflect/internal/AnnotationInfos.scala
index 91e1c3d50d..c283ae408e 100644
--- a/src/compiler/scala/reflect/internal/AnnotationInfos.scala
+++ b/src/compiler/scala/reflect/internal/AnnotationInfos.scala
@@ -46,23 +46,26 @@ trait AnnotationInfos extends api.AnnotationInfos { self: SymbolTable =>
* - or nested classfile annotations
*/
abstract class ClassfileAnnotArg extends Product
+ implicit val ClassfileAnnotArgTag = ClassTag[ClassfileAnnotArg](classOf[ClassfileAnnotArg])
/** Represents a compile-time Constant (`Boolean`, `Byte`, `Short`,
* `Char`, `Int`, `Long`, `Float`, `Double`, `String`, `java.lang.Class` or
* an instance of a Java enumeration value).
*/
case class LiteralAnnotArg(const: Constant)
- extends ClassfileAnnotArg {
+ extends ClassfileAnnotArg with LiteralAnnotArgApi {
override def toString = const.escapedStringValue
}
+ implicit val LiteralAnnotArgTag = ClassTag[LiteralAnnotArg](classOf[LiteralAnnotArg])
object LiteralAnnotArg extends LiteralAnnotArgExtractor
/** Represents an array of classfile annotation arguments */
case class ArrayAnnotArg(args: Array[ClassfileAnnotArg])
- extends ClassfileAnnotArg {
+ extends ClassfileAnnotArg with ArrayAnnotArgApi {
override def toString = args.mkString("[", ", ", "]")
}
+ implicit val ArrayAnnotArgTag = ClassTag[ArrayAnnotArg](classOf[ArrayAnnotArg])
object ArrayAnnotArg extends ArrayAnnotArgExtractor
@@ -105,11 +108,12 @@ trait AnnotationInfos extends api.AnnotationInfos { self: SymbolTable =>
}
/** Represents a nested classfile annotation */
- case class NestedAnnotArg(annInfo: AnnotationInfo) extends ClassfileAnnotArg {
+ case class NestedAnnotArg(annInfo: AnnotationInfo) extends ClassfileAnnotArg with NestedAnnotArgApi {
// The nested annotation should not have any Scala annotation arguments
assert(annInfo.args.isEmpty, annInfo.args)
override def toString = annInfo.toString
}
+ implicit val NestedAnnotArgTag = ClassTag[NestedAnnotArg](classOf[NestedAnnotArg])
object NestedAnnotArg extends NestedAnnotArgExtractor
@@ -191,7 +195,7 @@ trait AnnotationInfos extends api.AnnotationInfos { self: SymbolTable =>
*
* `assocs` stores arguments to classfile annotations as name-value pairs.
*/
- sealed abstract class AnnotationInfo {
+ sealed abstract class AnnotationInfo extends AnnotationInfoApi {
def atp: Type
def args: List[Tree]
def assocs: List[(Name, ClassfileAnnotArg)]
@@ -258,7 +262,7 @@ trait AnnotationInfos extends api.AnnotationInfos { self: SymbolTable =>
/** Change all ident's with Symbol "from" to instead use symbol "to" */
def substIdentSyms(from: Symbol, to: Symbol) =
- AnnotationInfo(atp, args map (_ substTreeSyms (from -> to)), assocs) setPos pos
+ AnnotationInfo(atp, args map (_ substituteSymbols (List(from), List(to))), assocs) setPos pos
def stringArg(index: Int) = constantAtIndex(index) map (_.stringValue)
def intArg(index: Int) = constantAtIndex(index) map (_.intValue)
@@ -283,7 +287,7 @@ trait AnnotationInfos extends api.AnnotationInfos { self: SymbolTable =>
}
}
- lazy val classfileAnnotArgTag: ArrayTag[ClassfileAnnotArg] = arrayTag[ClassfileAnnotArg]
+ implicit val AnnotationInfoTag = ClassTag[AnnotationInfo](classOf[AnnotationInfo])
object UnmappableAnnotation extends CompleteAnnotationInfo(NoType, Nil, Nil)
}
diff --git a/src/compiler/scala/reflect/internal/BuildUtils.scala b/src/compiler/scala/reflect/internal/BuildUtils.scala
new file mode 100644
index 0000000000..3bde57ded8
--- /dev/null
+++ b/src/compiler/scala/reflect/internal/BuildUtils.scala
@@ -0,0 +1,69 @@
+package scala.reflect
+package internal
+
+import Flags._
+
+trait BuildUtils extends base.BuildUtils { self: SymbolTable =>
+
+ class BuildImpl extends BuildBase {
+
+ def selectType(owner: Symbol, name: String): TypeSymbol = {
+ val result = owner.info.decl(newTypeName(name))
+ if (result ne NoSymbol) result.asTypeSymbol
+ else MissingRequirementError.notFound("type %s in %s".format(name, owner.fullName))
+ }
+
+ def selectTerm(owner: Symbol, name: String): TermSymbol = {
+ val sym = owner.info.decl(newTermName(name))
+ val result =
+ if (sym.isOverloaded) sym.suchThat(!_.isMethod)
+ else sym
+ if (result ne NoSymbol) result.asTermSymbol
+ else MissingRequirementError.notFound("term %s in %s".format(name, owner.fullName))
+ }
+
+ def selectOverloadedMethod(owner: Symbol, name: String, index: Int): MethodSymbol = {
+ val result = owner.info.decl(newTermName(name)).alternatives(index)
+ if (result ne NoSymbol) result.asMethodSymbol
+ else MissingRequirementError.notFound("overloaded method %s #%d in %s".format(name, index, owner.fullName))
+ }
+
+ def newFreeTerm(name: String, info: Type, value: => Any, flags: Long = 0L, origin: String = null): FreeTermSymbol =
+ newFreeTermSymbol(newTermName(name), info, value, flags, origin)
+
+ def newFreeType(name: String, info: Type, value: => Any, flags: Long = 0L, origin: String = null): FreeTypeSymbol =
+ newFreeTypeSymbol(newTypeName(name), info, value, (if (flags == 0L) PARAM else flags) | DEFERRED, origin)
+
+ def newFreeExistential(name: String, info: Type, value: => Any, flags: Long = 0L, origin: String = null): FreeTypeSymbol =
+ newFreeTypeSymbol(newTypeName(name), info, value, (if (flags == 0L) EXISTENTIAL else flags) | DEFERRED, origin)
+
+ def newNestedSymbol(owner: Symbol, name: Name, pos: Position, flags: Long, isClass: Boolean): Symbol =
+ owner.newNestedSymbol(name, pos, flags, isClass)
+
+ def setAnnotations[S <: Symbol](sym: S, annots: List[AnnotationInfo]): S =
+ sym.setAnnotations(annots)
+
+ def setTypeSignature[S <: Symbol](sym: S, tpe: Type): S =
+ sym.setTypeSignature(tpe)
+
+ def flagsFromBits(bits: Long): FlagSet = bits
+
+ def emptyValDef: ValDef = self.emptyValDef
+
+ def This(sym: Symbol): Tree = self.This(sym)
+
+ def Select(qualifier: Tree, sym: Symbol): Select = self.Select(qualifier, sym)
+
+ def Ident(sym: Symbol): Ident = self.Ident(sym)
+
+ def TypeTree(tp: Type): TypeTree = self.TypeTree(tp)
+
+ def thisPrefix(sym: Symbol): Type = sym.thisPrefix
+
+ def setType[T <: Tree](tree: T, tpe: Type): T = { tree.setType(tpe); tree }
+
+ def setSymbol[T <: Tree](tree: T, sym: Symbol): T = { tree.setSymbol(sym); tree }
+ }
+
+ val build: BuildBase = new BuildImpl
+}
diff --git a/src/compiler/scala/reflect/internal/Constants.scala b/src/compiler/scala/reflect/internal/Constants.scala
index 861bc870a7..820dfe0868 100644
--- a/src/compiler/scala/reflect/internal/Constants.scala
+++ b/src/compiler/scala/reflect/internal/Constants.scala
@@ -30,7 +30,7 @@ trait Constants extends api.Constants {
// For supporting java enumerations inside java annotations (see ClassfileParser)
final val EnumTag = 13
- case class Constant(value: Any) extends AbsConstant {
+ case class Constant(value: Any) extends ConstantApi {
val tag: Int = value match {
case null => NullTag
case x: Unit => UnitTag
@@ -235,4 +235,6 @@ trait Constants extends api.Constants {
}
object Constant extends ConstantExtractor
+
+ implicit val ConstantTag = ClassTag[Constant](classOf[Constant])
}
diff --git a/src/compiler/scala/reflect/internal/Definitions.scala b/src/compiler/scala/reflect/internal/Definitions.scala
index 6141cc184d..b3a651563e 100644
--- a/src/compiler/scala/reflect/internal/Definitions.scala
+++ b/src/compiler/scala/reflect/internal/Definitions.scala
@@ -10,11 +10,13 @@ import annotation.{ switch, meta }
import scala.collection.{ mutable, immutable }
import Flags._
import PartialFunction._
-import scala.reflect.{ mirror => rm }
+import scala.reflect.base.{Universe => BaseUniverse}
-trait Definitions extends reflect.api.StandardDefinitions {
+trait Definitions extends api.StandardDefinitions {
self: SymbolTable =>
+ import rootMirror.{getModule, getClassByName, getRequiredClass, getRequiredModule, getRequiredPackage, getClassIfDefined, getModuleIfDefined, getPackageObject, getPackageObjectIfDefined, requiredClass, requiredModule}
+
object definitions extends DefinitionsClass
// [Eugene] find a way to make these non-lazy
@@ -99,7 +101,7 @@ trait Definitions extends reflect.api.StandardDefinitions {
case _ => catastrophicFailure()
}
}
- private def valueCompanionMember(className: Name, methodName: TermName): MethodSymbol =
+ private def valueCompanionMember(className: Name, methodName: TermName): TermSymbol =
getMemberMethod(valueClassCompanion(className.toTermName).moduleClass, methodName)
private def classesMap[T](f: Name => T) = symbolsMap(ScalaValueClassesNoUnit, f)
@@ -111,7 +113,7 @@ trait Definitions extends reflect.api.StandardDefinitions {
lazy val abbrvTag = symbolsMap(ScalaValueClasses, nameToTag) withDefaultValue OBJECT_TAG
lazy val numericWeight = symbolsMapFilt(ScalaValueClasses, nameToWeight.keySet, nameToWeight)
lazy val boxedModule = classesMap(x => getModule(boxedName(x)))
- lazy val boxedClass = classesMap(x => getClass(boxedName(x)))
+ lazy val boxedClass = classesMap(x => getClassByName(boxedName(x)))
lazy val refClass = classesMap(x => getRequiredClass("scala.runtime." + x + "Ref"))
lazy val volatileRefClass = classesMap(x => getRequiredClass("scala.runtime.Volatile" + x + "Ref"))
lazy val boxMethod = classesMap(x => valueCompanionMember(x, nme.box))
@@ -138,9 +140,9 @@ trait Definitions extends reflect.api.StandardDefinitions {
lazy val FloatClass = valueClassSymbol(tpnme.Float)
lazy val DoubleClass = valueClassSymbol(tpnme.Double)
lazy val BooleanClass = valueClassSymbol(tpnme.Boolean)
- lazy val Boolean_and = getMember(BooleanClass, nme.ZAND)
- lazy val Boolean_or = getMember(BooleanClass, nme.ZOR)
- lazy val Boolean_not = getMember(BooleanClass, nme.UNARY_!)
+ lazy val Boolean_and = getMemberMethod(BooleanClass, nme.ZAND)
+ lazy val Boolean_or = getMemberMethod(BooleanClass, nme.ZOR)
+ lazy val Boolean_not = getMemberMethod(BooleanClass, nme.UNARY_!)
lazy val ScalaNumericValueClasses = ScalaValueClasses filterNot Set[Symbol](UnitClass, BooleanClass)
@@ -160,68 +162,21 @@ trait Definitions extends reflect.api.StandardDefinitions {
def ScalaPrimitiveValueClasses: List[ClassSymbol] = ScalaValueClasses
}
- abstract class DefinitionsClass extends AbsDefinitions with ValueClassDefinitions {
+ abstract class DefinitionsClass extends DefinitionsApi with ValueClassDefinitions {
private var isInitialized = false
def isDefinitionsInitialized = isInitialized
// symbols related to packages
var emptypackagescope: Scope = null //debug
- // TODO - having these as objects means they elude the attempt to
- // add synchronization in SynchronizedSymbols. But we should either
- // flip on object overrides or find some other accomodation, because
- // lazy vals are unnecessarily expensive relative to objects and it
- // is very beneficial for a handful of bootstrap symbols to have
- // first class identities
- sealed trait WellKnownSymbol extends Symbol {
- this initFlags TopLevelCreationFlags
- }
- // Features common to RootClass and RootPackage, the roots of all
- // type and term symbols respectively.
- sealed trait RootSymbol extends WellKnownSymbol {
- final override def isRootSymbol = true
- override def owner = NoSymbol
- override def typeOfThis = thisSym.tpe
- }
- // This is the package _root_. The actual root cannot be referenced at
- // the source level, but _root_ is essentially a function => .
- 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 , the actual root of everything except the package _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/FrontEnds.scala b/src/compiler/scala/reflect/internal/FrontEnds.scala
deleted file mode 100644
index 74501c7686..0000000000
--- a/src/compiler/scala/reflect/internal/FrontEnds.scala
+++ /dev/null
@@ -1,75 +0,0 @@
-package scala.reflect
-package internal
-
-trait FrontEnds { self: SymbolTable =>
-
- import scala.tools.nsc.reporters._
- import scala.tools.nsc.Settings
-
- def mkConsoleFrontEnd(minSeverity: Int = 1): FrontEnd = {
- val settings = new Settings()
- if (minSeverity <= 0) settings.verbose.value = true
- if (minSeverity > 1) settings.nowarn.value = true
- wrapReporter(new ConsoleReporter(settings))
- }
-
- abstract class FrontEndToReporterProxy(val frontEnd: FrontEnd) extends AbstractReporter {
- import frontEnd.{Severity => ApiSeverity}
- val API_INFO = frontEnd.INFO
- val API_WARNING = frontEnd.WARNING
- val API_ERROR = frontEnd.ERROR
-
- type NscSeverity = Severity
- val NSC_INFO = INFO
- val NSC_WARNING = WARNING
- val NSC_ERROR = ERROR
-
- def display(pos: Position, msg: String, nscSeverity: NscSeverity): Unit =
- frontEnd.log(pos, msg, nscSeverity match {
- case NSC_INFO => API_INFO
- case NSC_WARNING => API_WARNING
- case NSC_ERROR => API_ERROR
- })
-
- def displayPrompt(): Unit =
- frontEnd.interactive()
- }
-
- def wrapFrontEnd(frontEnd: FrontEnd): Reporter = new FrontEndToReporterProxy(frontEnd) {
- val settings = new Settings()
- settings.verbose.value = true
- settings.nowarn.value = false
- }
-
- class ReporterToFrontEndProxy(val reporter: Reporter) extends FrontEnd {
- val API_INFO = INFO
- val API_WARNING = WARNING
- val API_ERROR = ERROR
-
- override def hasErrors = reporter.hasErrors
- override def hasWarnings = reporter.hasWarnings
-
- def display(info: Info): Unit = info.severity match {
- case API_INFO => reporter.info(info.pos, info.msg, false)
- case API_WARNING => reporter.warning(info.pos, info.msg)
- case API_ERROR => reporter.error(info.pos, info.msg)
- }
-
- def interactive(): Unit = reporter match {
- case reporter: AbstractReporter => reporter.displayPrompt()
- case _ => // do nothing
- }
-
- override def flush(): Unit = {
- super.flush()
- reporter.flush()
- }
-
- override def reset(): Unit = {
- super.reset()
- reporter.reset()
- }
- }
-
- def wrapReporter(reporter: Reporter): FrontEnd = new ReporterToFrontEndProxy(reporter)
-}
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 => .
+ 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 , the actual root of everything except the package _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 = ""
@@ -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 = ""
val CONSTRUCTOR: NameType = ""
+ 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 = "" // emitted by virtual pattern matcher, replaced by outer accessor in explicitouter
+ val ROOTPKG: NameType = "_root_"
val SELECTOR_DUMMY: NameType = ""
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 ")
+ 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).(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 .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 `..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
- * ., 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
+ * ., 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 _ => ""
- }
- 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, "") 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 _ => ""
- }
- println("classpath is: %s".format(inferClasspath(classloader)))
- def msgNoSym = "no symbol could be loaded from %s (scala equivalent is %s) by name %s".format(owner, jclazz, simpleName)
- def msgIsNotType = "not a type: symbol %s loaded from %s (scala equivalent is %s) by name %s".format(sym, owner, jclazz, simpleName)
- assert(false, if (sym == NoSymbol) msgNoSym else msgIsNotType)
- }
-
- sym
- }
-
- sym.asInstanceOf[ClassSymbol]
- }
-
- /**
- * The Scala type parameter that corresponds to a given Java type parameter.
- * @param jparam The Java type parameter
- * @return A Scala type parameter symbol that has the same owner and name as the Java type parameter
- */
- def tparamToScala(jparam: jTypeVariable[_ <: GenericDeclaration]): Symbol = tparamCache.toScala(jparam) {
- val owner = genericDeclarationToScala(jparam.getGenericDeclaration)
- owner.info match {
- case PolyType(tparams, _) => tparams.find(_.name.toString == jparam.getName).get
- }
- }
-
- /**
- * The Scala symbol that corresponds to a given Java generic declaration (class, method, or constructor)
- */
- def genericDeclarationToScala(jdecl: GenericDeclaration) = jdecl match {
- case jclazz: jClass[_] => classToScala(jclazz)
- case jmeth: jMethod => methodToScala(jmeth)
- case jconstr: jConstructor[_] => constrToScala(jconstr)
- }
-
- /**
- * Given some Java type arguments, a corresponding list of Scala types, plus potentially
- * some existentially bound type variables that represent wildcard arguments.
- */
- private def targsToScala(owner: Symbol, args: List[jType]): (List[Type], List[Symbol]) = {
- val tparams = new ListBuffer[Symbol]
- def targToScala(arg: jType): Type = arg match {
- case jwild: WildcardType =>
- val tparam = owner.newExistential(newTypeName("T$" + tparams.length))
- .setInfo(TypeBounds(
- lub(jwild.getLowerBounds.toList map typeToScala),
- glb(jwild.getUpperBounds.toList map typeToScala map objToAny)))
- tparams += tparam
- typeRef(NoPrefix, tparam, List())
- case _ =>
- typeToScala(arg)
- }
- (args map targToScala, tparams.toList)
- }
-
- /**
- * The Scala type that corresponds to given Java type
- */
- def typeToScala(jtpe: jType): Type = jtpe match {
- case jclazz: jClass[_] =>
- if (jclazz.isArray)
- arrayType(typeToScala(jclazz.getComponentType))
- else {
- val clazz = classToScala(jclazz)
- rawToExistential(typeRef(clazz.owner.thisType, clazz, List()))
- }
- case japplied: ParameterizedType =>
- val (pre, sym) = typeToScala(japplied.getRawType) match {
- case ExistentialType(tparams, TypeRef(pre, sym, _)) => (pre, sym)
- case TypeRef(pre, sym, _) => (pre, sym)
- }
- val args0 = japplied.getActualTypeArguments
- val (args, bounds) = targsToScala(pre.typeSymbol, args0.toList)
- ExistentialType(bounds, typeRef(pre, sym, args))
- case jarr: GenericArrayType =>
- arrayType(typeToScala(jarr.getGenericComponentType))
- case jtvar: jTypeVariable[_] =>
- val tparam = tparamToScala(jtvar)
- typeRef(NoPrefix, tparam, List())
- }
-
- /**
- * The Scala class that corresponds to given Java class without taking
- * Scala pickling info into account.
- * @param jclazz The Java class
- * @return A Scala class symbol that wraps all reflection info of `jclazz`
- */
- private def jclassAsScala(jclazz: jClass[_]): Symbol = jclassAsScala(jclazz, sOwner(jclazz))
-
- private def jclassAsScala(jclazz: jClass[_], owner: Symbol): Symbol = {
- val name = scalaSimpleName(jclazz)
- val completer = (clazz: Symbol, module: Symbol) => new FromJavaClassCompleter(clazz, module, jclazz)
- val (clazz, module) = createClassModule(owner, name, completer)
- classCache enter (jclazz, clazz)
- clazz
- }
-
- /**
- * The Scala field that corresponds to given Java field without taking
- * Scala pickling info into account.
- * @param jfield The Java field
- * @return A Scala value symbol that wraps all reflection info of `jfield`
- */
- private def jfieldAsScala(jfield: jField): Symbol = fieldCache.toScala(jfield) {
- val field = (
- sOwner(jfield)
- newValue(newTermName(jfield.getName), NoPosition, toScalaFieldFlags(jfield.getModifiers))
- setInfo typeToScala(jfield.getGenericType)
- )
- fieldCache enter (jfield, field)
- copyAnnotations(field, jfield)
- field
- }
-
- private def setMethType(meth: Symbol, tparams: List[Symbol], paramtpes: List[Type], restpe: Type) = {
- meth setInfo GenPolyType(tparams, MethodType(meth.owner.newSyntheticValueParams(paramtpes map objToAny), restpe))
- }
-
- /**
- * The Scala method that corresponds to given Java method without taking
- * Scala pickling info into account.
- * @param jmeth The Java method
- * @return A Scala method symbol that wraps all reflection info of `jmethod`
- */
- private def jmethodAsScala(jmeth: jMethod): Symbol = methodCache.toScala(jmeth) {
- val clazz = sOwner(jmeth)
- val meth = clazz.newMethod(newTermName(jmeth.getName), NoPosition, toScalaMethodFlags(jmeth.getModifiers))
- methodCache enter (jmeth, meth)
- val tparams = jmeth.getTypeParameters.toList map createTypeParameter
- val paramtpes = jmeth.getGenericParameterTypes.toList map typeToScala
- val resulttpe = typeToScala(jmeth.getGenericReturnType)
- setMethType(meth, tparams, paramtpes, resulttpe)
- copyAnnotations(meth, jmeth)
- if ((jmeth.getModifiers & JAVA_ACC_VARARGS) != 0) {
- meth.setInfo(arrayToRepeated(meth.info))
- }
- meth
- }
-
- /**
- * The Scala constructor that corresponds to given Java constructor without taking
- * Scala pickling info into account.
- * @param jconstr The Java constructor
- * @return A Scala constructor symbol that wraps all reflection info of `jconstr`
- */
- private def jconstrAsScala(jconstr: jConstructor[_]): Symbol = {
- // [Martin] Note: I know there's a lot of duplication wrt jmethodAsScala, but don't think it's worth it to factor this out.
- val clazz = sOwner(jconstr)
- val constr = clazz.newConstructor(NoPosition, toScalaMethodFlags(jconstr.getModifiers))
- constructorCache enter (jconstr, constr)
- val tparams = jconstr.getTypeParameters.toList map createTypeParameter
- val paramtpes = jconstr.getGenericParameterTypes.toList map typeToScala
- setMethType(constr, tparams, paramtpes, clazz.tpe)
- constr setInfo GenPolyType(tparams, MethodType(clazz.newSyntheticValueParams(paramtpes), clazz.tpe))
- copyAnnotations(constr, jconstr)
- constr
- }
-}
-
-class ReflectError(msg: String) extends java.lang.Error(msg)
diff --git a/src/compiler/scala/reflect/runtime/JavaUniverse.scala b/src/compiler/scala/reflect/runtime/JavaUniverse.scala
new file mode 100644
index 0000000000..9dcf8786c5
--- /dev/null
+++ b/src/compiler/scala/reflect/runtime/JavaUniverse.scala
@@ -0,0 +1,33 @@
+package scala.reflect
+package runtime
+
+import internal.{SomePhase, NoPhase, Phase, TreeGen}
+
+/** The universe for standard runtime reflection from Java.
+ * This type implements all abstract term members in internal.SymbolTable.
+ */
+class JavaUniverse extends internal.SymbolTable with ReflectSetup with runtime.SymbolTable { self =>
+
+ type AbstractFileType = AbstractFile
+
+ def picklerPhase = SomePhase
+
+ type TreeGen = internal.TreeGen
+
+ override type Position = scala.tools.nsc.util.Position
+
+ override val gen = new TreeGen { val global: self.type = self }
+
+ lazy val settings = new Settings
+ def forInteractive = false
+ def forScaladoc = false
+
+ def log(msg: => AnyRef): Unit = println(" [] "+msg)
+
+ type TreeCopier = TreeCopierOps
+ def newStrictTreeCopier: TreeCopier = new StrictTreeCopier
+ def newLazyTreeCopier: TreeCopier = new LazyTreeCopier
+
+ init()
+}
+
diff --git a/src/compiler/scala/reflect/runtime/Mirror.scala b/src/compiler/scala/reflect/runtime/Mirror.scala
deleted file mode 100644
index bf4bc83bea..0000000000
--- a/src/compiler/scala/reflect/runtime/Mirror.scala
+++ /dev/null
@@ -1,85 +0,0 @@
-package scala.reflect
-package runtime
-
-import java.lang.reflect.Array
-import ReflectionUtils._
-import scala.tools.nsc.util.ScalaClassLoader._
-
-/** The mirror for standard runtime reflection from Java.
- */
-class Mirror(var classLoader: ClassLoader) extends Universe with api.Mirror {
-
- definitions.init()
- import definitions._
-
- def symbolForName(name: String): Symbol = {
- val clazz = javaClass(name, classLoader)
- classToScala(clazz)
- }
-
- def companionInstance(clazz: Symbol): AnyRef = {
- val singleton = singletonInstance(classLoader, clazz.fullName)
- singleton
- }
-
- def symbolOfInstance(obj: Any): Symbol = classToScala(obj.getClass)
- def typeOfInstance(obj: Any): Type = typeToScala(obj.getClass)
- // to do add getClass/getType for instances of primitive types, probably like this:
- // def getClass[T <: AnyVal : ClassTag](x: T): Symbol = classTag[T].sym
-
- def getValueOfField(receiver: AnyRef, field: Symbol): Any = {
- fieldToJava(field).get(receiver)
- }
- def setValueOfField(receiver: AnyRef, field: Symbol, value: Any): Unit = {
- fieldToJava(field).set(receiver, value)
- }
- def invoke(receiver: AnyRef, meth: Symbol)(args: Any*): Any = {
- if (meth.owner == ArrayClass) {
- meth.name match {
- case nme.length => return Array.getLength(receiver)
- case nme.apply => return Array.get(receiver, args(0).asInstanceOf[Int])
- case nme.update => return Array.set(receiver, args(0).asInstanceOf[Int], args(1))
- }
- }
-
- val jmeth = methodToJava(meth)
- jmeth.invoke(receiver, args.asInstanceOf[Seq[AnyRef]]: _*)
- }
-
- private def validateIncomingClassLoader(wannabeCl: ClassLoader) = {
- val ourCls = loaderChain(classLoader)
- if (wannabeCl != null && !(ourCls contains wannabeCl))
- throw new Error("class doesn't belong to the classloader chain of the mirror")
- }
-
- def classToType(jclazz: java.lang.Class[_]): Type = {
- validateIncomingClassLoader(jclazz.getClassLoader)
- typeToScala(jclazz)
- }
-
- def classToSymbol(jclazz: java.lang.Class[_]): Symbol = {
- validateIncomingClassLoader(jclazz.getClassLoader)
- classToScala(jclazz)
- }
-
- def typeToClass(tpe: Type): java.lang.Class[_] =
- typeToJavaClass(tpe)
-
- def symbolToClass(sym: Symbol): java.lang.Class[_] =
- classToJava(sym)
-
- override def inReflexiveMirror = true
-}
-
-/** test code; should go to tests once things settle down a bit
- *
-
-object Test extends Mirror with App {
- val sym = classToScala(classOf[scala.collection.Iterable[_]])
- println(sym)
- println("parents = "+sym.info.parents)
- println("decls = "+(sym.info.decls.toList map (_.defString)))
- val ms = sym.info.members.toList map (_.initialize)
- println("members = "+(ms map (_.defString) mkString ("\n ")))
-}
-*/
\ No newline at end of file
diff --git a/src/compiler/scala/reflect/runtime/ReflectSetup.scala b/src/compiler/scala/reflect/runtime/ReflectSetup.scala
new file mode 100644
index 0000000000..6e28fc8520
--- /dev/null
+++ b/src/compiler/scala/reflect/runtime/ReflectSetup.scala
@@ -0,0 +1,12 @@
+package scala.reflect
+package runtime
+
+import internal.{SomePhase, NoPhase, Phase, TreeGen}
+
+/** A helper trait to initialize things that need to be set before JavaMirrors and other
+ * reflect specific traits are initialized */
+private[runtime] trait ReflectSetup extends internal.SymbolTable {
+ override val phaseWithId: Array[Phase] = Array(NoPhase, SomePhase)
+ override val currentRunId = 1 // fake a run id so that it is different from NoRunId
+ phase = SomePhase // set to a phase different from NoPhase
+}
diff --git a/src/compiler/scala/reflect/runtime/ReflectionUtils.scala b/src/compiler/scala/reflect/runtime/ReflectionUtils.scala
new file mode 100644
index 0000000000..4e82fe8ad2
--- /dev/null
+++ b/src/compiler/scala/reflect/runtime/ReflectionUtils.scala
@@ -0,0 +1,80 @@
+/* NSC -- new Scala compiler
+ * Copyright 2005-2011 LAMP/EPFL
+ * @author Paul Phillips
+ */
+
+package scala.reflect.runtime
+
+import java.lang.{Class => jClass}
+import java.lang.reflect.{ InvocationTargetException, UndeclaredThrowableException }
+
+/** A few java-reflection oriented utility functions useful during reflection bootstrapping.
+ */
+object ReflectionUtils {
+ // Unwraps some chained exceptions which arise during reflective calls.
+ def unwrapThrowable(x: Throwable): Throwable = x match {
+ case _: InvocationTargetException | // thrown by reflectively invoked method or constructor
+ _: ExceptionInInitializerError | // thrown when running a static initializer (e.g. a scala module constructor)
+ _: UndeclaredThrowableException | // invocation on a proxy instance if its invocation handler's `invoke` throws an exception
+ _: ClassNotFoundException | // no definition for a class instantiated by name
+ _: NoClassDefFoundError // the definition existed when the executing class was compiled, but can no longer be found
+ if x.getCause != null =>
+ unwrapThrowable(x.getCause)
+ case _ => x
+ }
+ // Transforms an exception handler into one which will only receive the unwrapped
+ // exceptions (for the values of wrap covered in unwrapThrowable.)
+ def unwrapHandler[T](pf: PartialFunction[Throwable, T]): PartialFunction[Throwable, T] = {
+ case ex if pf isDefinedAt unwrapThrowable(ex) => pf(unwrapThrowable(ex))
+ }
+
+ private def systemProperties: Iterator[(String, String)] = {
+ import scala.collection.JavaConverters._
+ System.getProperties.asScala.iterator
+ }
+
+ private def inferBootClasspath: String = (
+ systemProperties find (_._1 endsWith ".boot.class.path") map (_._2) getOrElse ""
+ )
+
+ def show(cl: ClassLoader) = {
+ def inferClasspath(cl: ClassLoader): String = cl match {
+ case cl: java.net.URLClassLoader =>
+ "[" + (cl.getURLs mkString ",") + "]"
+ case cl if cl != null && cl.getClass.getName == "scala.tools.nsc.interpreter.AbstractFileClassLoader" =>
+ "[" + cl.asInstanceOf[{val root: scala.reflect.internal.AbstractFileApi}].root + "] and " + inferClasspath(cl.getParent)
+ case null =>
+ inferBootClasspath
+ case _ =>
+ ""
+ }
+ cl match {
+ case cl if cl != null =>
+ "%s of type %s with classpath %s".format(cl, cl.getClass, inferClasspath(cl))
+ case null =>
+ "primordial classloader with boot classpath [%s]".format(inferClasspath(cl))
+ }
+ }
+
+ def singletonInstance(cl: ClassLoader, className: String): AnyRef = {
+ val name = if (className endsWith "$") className else className + "$"
+ val clazz = java.lang.Class.forName(name, true, cl)
+ val singleton = clazz getField "MODULE$" get null
+ singleton
+ }
+
+ // Retrieves the MODULE$ field for the given class name.
+ def singletonInstanceOpt(cl: ClassLoader, className: String): Option[AnyRef] =
+ try Some(singletonInstance(cl, className))
+ catch { case _: ClassNotFoundException => None }
+
+ def invokeFactory(cl: ClassLoader, className: String, methodName: String, args: AnyRef*): AnyRef = {
+ val singleton = singletonInstance(cl, className)
+ val method = singleton.getClass.getMethod(methodName, classOf[ClassLoader])
+ method.invoke(singleton, args: _*)
+ }
+
+ def invokeFactoryOpt(cl: ClassLoader, className: String, methodName: String, args: AnyRef*): Option[AnyRef] =
+ try Some(invokeFactory(cl, className, methodName, args: _*))
+ catch { case _: ClassNotFoundException => None }
+}
diff --git a/src/compiler/scala/reflect/runtime/ScalaToJava.scala b/src/compiler/scala/reflect/runtime/ScalaToJava.scala
deleted file mode 100644
index 87cdd11652..0000000000
--- a/src/compiler/scala/reflect/runtime/ScalaToJava.scala
+++ /dev/null
@@ -1,87 +0,0 @@
-package scala.reflect
-package runtime
-
-import java.lang.{Class => jClass, Package => jPackage}
-import java.lang.reflect.{
- Method => jMethod, Constructor => jConstructor, Modifier => jModifier, Field => jField,
- Member => jMember, Type => jType, Array => jArray, GenericDeclaration}
-
-trait ScalaToJava extends ConversionUtil { self: SymbolTable =>
-
- import definitions._
-
- /** Optionally, the Java package corresponding to a given Scala package, or None if no such Java package exists.
- * @param pkg The Scala package
- */
- def packageToJava(pkg: Symbol): Option[jPackage] = packageCache.toJavaOption(pkg) {
- Option(jPackage.getPackage(pkg.fullName.toString))
- }
-
- /** The Java class corresponding to given Scala class.
- * Note: This only works for
- * - top-level classes
- * - Scala classes that were generated via jclassToScala
- * - classes that have a class owner that has a corresponding Java class
- * @throws A `ClassNotFoundException` for all Scala classes not in one of these categories.
- */
- @throws(classOf[ClassNotFoundException])
- def classToJava(clazz: Symbol): jClass[_] = classCache.toJava(clazz) {
- def noClass = throw new ClassNotFoundException("no Java class corresponding to "+clazz+" found")
- //println("classToJava "+clazz+" "+clazz.owner+" "+clazz.owner.isPackageClass)//debug
- if (clazz.isPrimitiveValueClass)
- valueClassToJavaType(clazz)
- else if (clazz == ArrayClass)
- noClass
- else if (clazz.owner.isPackageClass)
- javaClass(clazz.javaClassName)
- else if (clazz.owner.isClass)
- classToJava(clazz.owner)
- .getDeclaredClasses
- .find(_.getSimpleName == clazz.name.toString)
- .getOrElse(noClass)
- else
- noClass
- }
-
- private def expandedName(sym: Symbol): String =
- if (sym.isPrivate) nme.expandedName(sym.name.toTermName, sym.owner).toString
- else sym.name.toString
-
- def fieldToJava(fld: Symbol): jField = fieldCache.toJava(fld) {
- val jclazz = classToJava(fld.owner)
- try jclazz getDeclaredField fld.name.toString
- catch {
- case ex: NoSuchFieldException => jclazz getDeclaredField expandedName(fld)
- }
- }
-
- def methodToJava(meth: Symbol): jMethod = methodCache.toJava(meth) {
- val jclazz = classToJava(meth.owner)
- val paramClasses = transformedType(meth).paramTypes map typeToJavaClass
- try jclazz getDeclaredMethod (meth.name.toString, paramClasses: _*)
- catch {
- case ex: NoSuchMethodException =>
- jclazz getDeclaredMethod (expandedName(meth), paramClasses: _*)
- }
- }
-
- def constrToJava(constr: Symbol): jConstructor[_] = constructorCache.toJava(constr) {
- val jclazz = classToJava(constr.owner)
- val paramClasses = transformedType(constr).paramTypes map typeToJavaClass
- jclazz getConstructor (paramClasses: _*)
- }
-
- private def jArrayClass(elemClazz: jClass[_]): jClass[_] = {
- jArray.newInstance(elemClazz, 0).getClass
- }
-
- /** The Java class that corresponds to given Scala type.
- * Pre: Scala type is already transformed to Java level.
- */
- def typeToJavaClass(tpe: Type): jClass[_] = tpe match {
- case ExistentialType(_, rtpe) => typeToJavaClass(rtpe)
- case TypeRef(_, ArrayClass, List(elemtpe)) => jArrayClass(typeToJavaClass(elemtpe))
- case TypeRef(_, sym, _) => classToJava(sym)
- case _ => throw new NoClassDefFoundError("no Java class corresponding to "+tpe+" found")
- }
-}
\ No newline at end of file
diff --git a/src/compiler/scala/reflect/runtime/SymbolLoaders.scala b/src/compiler/scala/reflect/runtime/SymbolLoaders.scala
index 7c1cc16152..c1cd5d2911 100644
--- a/src/compiler/scala/reflect/runtime/SymbolLoaders.scala
+++ b/src/compiler/scala/reflect/runtime/SymbolLoaders.scala
@@ -7,12 +7,6 @@ import collection.mutable
trait SymbolLoaders { self: SymbolTable =>
- /** The lazy type for root.
- */
- override val rootLoader = new LazyType {
- override def complete(sym: Symbol) = sym setInfo new LazyPackageType
- }
-
/** The standard completer for top-level classes
* @param clazz The top-level class
* @param module The companion object of `clazz`
@@ -35,7 +29,9 @@ trait SymbolLoaders { self: SymbolTable =>
assert(sym == clazz || sym == module || sym == module.moduleClass)
// try {
atPhaseNotLaterThan(picklerPhase) {
- unpickleClass(clazz, module, javaClass(clazz.javaClassName))
+ val loadingMirror = mirrorThatLoaded(sym)
+ val javaClass = loadingMirror.javaClass(clazz.javaClassName)
+ loadingMirror.unpickleClass(clazz, module, javaClass)
// } catch {
// case ex: ClassNotFoundException => makePackage()
// case ex: NoClassDefFoundError => makePackage()
@@ -65,8 +61,14 @@ trait SymbolLoaders { self: SymbolTable =>
assert(!(name.toString endsWith "[]"), name)
val clazz = owner.newClass(name)
val module = owner.newModule(name.toTermName)
- owner.info.decls enter clazz
- owner.info.decls enter module
+ // [Eugene++] am I doing this right?
+ // todo: drop condition, see what goes wrong
+ // [Eugene++ to Martin] test/files/run/t5256g and test/files/run/t5256h will crash
+ // reflection meeting verdict: need to enter the symbols into the first symbol in the owner chain that has a non-empty scope
+ if (owner.info.decls != EmptyScope) {
+ owner.info.decls enter clazz
+ owner.info.decls enter module
+ }
initClassModule(clazz, module, completer(clazz, module))
(clazz, module)
}
@@ -92,7 +94,7 @@ trait SymbolLoaders { self: SymbolTable =>
/** Is the given name valid for a top-level class? We exclude names with embedded $-signs, because
* these are nested classes or anonymous classes,
*/
- def invalidClassName(name: Name) = {
+ def isInvalidClassName(name: Name) = {
val dp = name pos '$'
0 < dp && dp < (name.length - 1)
}
@@ -104,20 +106,35 @@ trait SymbolLoaders { self: SymbolTable =>
val e = super.lookupEntry(name)
if (e != null)
e
- else if (invalidClassName(name) || (negatives contains name))
+ else if (isInvalidClassName(name) || (negatives contains name))
null
else {
val path =
if (pkgClass.isEmptyPackageClass) name.toString
else pkgClass.fullName + "." + name
- if (isJavaClass(path)) {
- val (clazz, module) = createClassModule(pkgClass, name.toTypeName, new TopClassCompleter(_, _))
- debugInfo("created "+module+"/"+module.moduleClass+" in "+pkgClass)
- lookupEntry(name)
- } else {
- debugInfo("*** not found : "+path)
- negatives += name
- null
+ val currentMirror = mirrorThatLoaded(pkgClass)
+ currentMirror.tryJavaClass(path) match {
+ case Some(cls) =>
+ val loadingMirror = currentMirror.mirrorDefining(cls)
+ val (clazz, module) =
+ if (loadingMirror eq currentMirror) {
+ createClassModule(pkgClass, name.toTypeName, new TopClassCompleter(_, _))
+ } else {
+ val origOwner = loadingMirror.packageNameToScala(pkgClass.fullName)
+ val clazz = origOwner.info decl name.toTypeName
+ val module = origOwner.info decl name.toTermName
+ assert(clazz != NoSymbol)
+ assert(module != NoSymbol)
+ pkgClass.info.decls enter clazz
+ pkgClass.info.decls enter module
+ (clazz, module)
+ }
+ debugInfo(s"created $module/${module.moduleClass} in $pkgClass")
+ lookupEntry(name)
+ case none =>
+ debugInfo("*** not found : "+path)
+ negatives += name
+ null
}
}
}
diff --git a/src/compiler/scala/reflect/runtime/SymbolTable.scala b/src/compiler/scala/reflect/runtime/SymbolTable.scala
index 64a5894d01..c90665508b 100644
--- a/src/compiler/scala/reflect/runtime/SymbolTable.scala
+++ b/src/compiler/scala/reflect/runtime/SymbolTable.scala
@@ -3,14 +3,15 @@ package runtime
/**
* This symbol table trait fills in the definitions so that class information is obtained by refection.
- * It can be used either from the reflexive mirror itself (class Mirror), or else from
+ * It can be used either from a reflexive universe (class scala.reflect.runtime.JavaUniverse), or else from
* a runtime compiler that uses reflection to get a class information (class scala.tools.nsc.ReflectGlobal)
*/
-trait SymbolTable extends internal.SymbolTable with JavaToScala with ScalaToJava with ClassLoaders with SymbolLoaders with SynchronizedOps {
+trait SymbolTable extends internal.SymbolTable with JavaMirrors with SymbolLoaders with SynchronizedOps {
def info(msg: => String) =
if (settings.verbose.value) println("[reflect-compiler] "+msg)
def debugInfo(msg: => String) =
if (settings.debug.value) info(msg)
+
}
diff --git a/src/compiler/scala/reflect/runtime/SynchronizedSymbols.scala b/src/compiler/scala/reflect/runtime/SynchronizedSymbols.scala
index 2322911220..3b28ddf42c 100644
--- a/src/compiler/scala/reflect/runtime/SynchronizedSymbols.scala
+++ b/src/compiler/scala/reflect/runtime/SynchronizedSymbols.scala
@@ -14,11 +14,11 @@ trait SynchronizedSymbols extends internal.Symbols { self: SymbolTable =>
override def connectModuleToClass(m: ModuleSymbol, moduleClass: ClassSymbol): ModuleSymbol =
synchronized { super.connectModuleToClass(m, moduleClass) }
- override def newFreeTermSymbol(name: TermName, info: Type, value: => Any, flags: Long = 0L, origin: String = null): FreeTerm =
- new FreeTerm(name, value, origin) with SynchronizedTermSymbol initFlags flags setInfo info
+ override def newFreeTermSymbol(name: TermName, info: Type, value: => Any, flags: Long = 0L, origin: String = null): FreeTermSymbol =
+ new FreeTermSymbol(name, value, origin) with SynchronizedTermSymbol initFlags flags setInfo info
- override def newFreeTypeSymbol(name: TypeName, info: Type, value: => Any, flags: Long = 0L, origin: String = null): FreeType =
- new FreeType(name, value, origin) with SynchronizedTypeSymbol initFlags flags setInfo info
+ override def newFreeTypeSymbol(name: TypeName, info: Type, value: => Any, flags: Long = 0L, origin: String = null): FreeTypeSymbol =
+ new FreeTypeSymbol(name, value, origin) with SynchronizedTypeSymbol initFlags flags setInfo info
override protected def makeNoSymbol: NoSymbol = new NoSymbol with SynchronizedSymbol
@@ -92,8 +92,7 @@ trait SynchronizedSymbols extends internal.Symbols { self: SymbolTable =>
override protected def createModuleSymbol(name: TermName, pos: Position, newFlags: Long): ModuleSymbol =
new ModuleSymbol(this, pos, name) with SynchronizedTermSymbol initFlags newFlags
- override protected def createPackageSymbol(name: TermName, pos: Position, newFlags: Long): PackageSymbol =
- new PackageSymbol(this, pos, name) with SynchronizedTermSymbol initFlags newFlags
+ override protected def createPackageSymbol(name: TermName, pos: Position, newFlags: Long): ModuleSymbol = createModuleSymbol(name, pos, newFlags)
// TODO
// override protected def createValueParameterSymbol(name: TermName, pos: Position, newFlags: Long)
@@ -133,7 +132,8 @@ trait SynchronizedSymbols extends internal.Symbols { self: SymbolTable =>
trait SynchronizedModuleClassSymbol extends ModuleClassSymbol with SynchronizedClassSymbol {
override def sourceModule = synchronized { super.sourceModule }
- override def sourceModule_=(module: Symbol) = synchronized { super.sourceModule_=(module: Symbol) }
+ // [Eugene++ to Martin] doesn't override anything. no longer necessary?
+ // def sourceModule_=(module: ModuleSymbol) = synchronized { super.sourceModule_=(module) }
override def implicitMembers: List[Symbol] = synchronized { super.implicitMembers }
}
}
diff --git a/src/compiler/scala/reflect/runtime/SynchronizedTypes.scala b/src/compiler/scala/reflect/runtime/SynchronizedTypes.scala
index e5a508f802..e1eb7a57fe 100644
--- a/src/compiler/scala/reflect/runtime/SynchronizedTypes.scala
+++ b/src/compiler/scala/reflect/runtime/SynchronizedTypes.scala
@@ -9,7 +9,8 @@ trait SynchronizedTypes extends internal.Types { self: SymbolTable =>
// No sharing of map objects:
override protected def commonOwnerMap = new CommonOwnerMap
- private val uniqueLock = new Object
+ private object uniqueLock
+
override def unique[T <: Type](tp: T): T = uniqueLock.synchronized { super.unique(tp) }
class SynchronizedUndoLog extends UndoLog {
@@ -29,7 +30,7 @@ trait SynchronizedTypes extends internal.Types { self: SymbolTable =>
override protected def baseTypeOfNonClassTypeRef(tpe: NonClassTypeRef, clazz: Symbol) =
synchronized { super.baseTypeOfNonClassTypeRef(tpe, clazz) }
- private val subsametypeLock = new Object
+ private object subsametypeLock
override def isSameType(tp1: Type, tp2: Type): Boolean =
subsametypeLock.synchronized { super.isSameType(tp1, tp2) }
@@ -40,7 +41,7 @@ trait SynchronizedTypes extends internal.Types { self: SymbolTable =>
override def isSubType(tp1: Type, tp2: Type, depth: Int): Boolean =
subsametypeLock.synchronized { super.isSubType(tp1, tp2, depth) }
- private val lubglbLock = new Object
+ private object lubglbLock
override def glb(ts: List[Type]): Type =
lubglbLock.synchronized { super.glb(ts) }
@@ -48,13 +49,13 @@ trait SynchronizedTypes extends internal.Types { self: SymbolTable =>
override def lub(ts: List[Type]): Type =
lubglbLock.synchronized { super.lub(ts) }
- private val indentLock = new Object
+ private object indentLock
override protected def explain[T](op: String, p: (Type, T) => Boolean, tp1: Type, arg2: T): Boolean = {
indentLock.synchronized { super.explain(op, p, tp1, arg2) }
}
- private val toStringLock = new Object
+ private object toStringLock
override protected def typeToString(tpe: Type): String =
toStringLock.synchronized(super.typeToString(tpe))
@@ -84,4 +85,4 @@ trait SynchronizedTypes extends internal.Types { self: SymbolTable =>
override protected def defineBaseTypeSeqOfTypeRef(tpe: TypeRef) =
tpe.synchronized { super.defineBaseTypeSeqOfTypeRef(tpe) }
-}
\ No newline at end of file
+}
diff --git a/src/compiler/scala/reflect/runtime/ToolBoxes.scala b/src/compiler/scala/reflect/runtime/ToolBoxes.scala
deleted file mode 100644
index 895c645c83..0000000000
--- a/src/compiler/scala/reflect/runtime/ToolBoxes.scala
+++ /dev/null
@@ -1,351 +0,0 @@
-package scala.reflect
-package runtime
-
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.ReflectGlobal
-import scala.tools.nsc.CompilerCommand
-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.reflect.internal.Flags
-import scala.tools.nsc.util.{NoSourceFile, NoFile}
-import java.lang.{Class => jClass}
-import scala.compat.Platform.EOL
-
-trait ToolBoxes extends { self: Universe =>
-
- def mkToolBox(frontEnd: FrontEnd = mkSilentFrontEnd(), options: String = "") = new ToolBox(frontEnd, options)
-
- class ToolBox(val frontEnd: FrontEnd, val options: String) extends AbsToolBox {
-
- class ToolBoxGlobal(settings: scala.tools.nsc.Settings, reporter: Reporter)
- extends ReflectGlobal(settings, reporter, ToolBox.this.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 def nextWrapperModuleName() = {
- wrapCount += 1
- newTermName("__wrapper$" + wrapCount)
- }
-
- def verifyExpr(expr: Tree): Unit = {
- // Previously toolboxes used to typecheck their inputs before compiling.
- // Actually, the initial demo by Martin first typechecked the reified tree,
- // then ran it, which typechecked it again, and only then launched the
- // reflective compiler.
- //
- // However, as observed in https://issues.scala-lang.org/browse/SI-5464
- // current implementation typechecking is not always idempotent.
- // 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")
-
- val freeTypes = this.freeTypes(expr)
- 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)
- }
- }
-
- 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]()
- 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))
- })
- var expr = new Transformer {
- override def transform(tree: Tree): Tree =
- if (tree.hasSymbol && tree.symbol.isFreeTerm) {
- tree match {
- case Ident(_) =>
- Ident(freeTermNames(tree.symbol))
- 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 dummies = freeTerms map (freeTerm => ValDef(NoMods, freeTermNames(freeTerm), TypeTree(freeTerm.info), Select(Ident(PredefModule), newTermName("$qmark$qmark$qmark"))))
- 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(""), List(ObjectClass.tpe), newScope)
- 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] _)
- val wrapper2 = if (!withMacrosDisabled) (currentTyper.context.withMacrosEnabled[Tree] _) else (currentTyper.context.withMacrosDisabled[Tree] _)
- def wrapper (tree: => Tree) = wrapper1(wrapper2(tree))
-
- phase = (new Run).typerPhase // need to set a phase to something <= typerPhase, otherwise implicits in typedSelect will be disabled
- currentTyper.context.setReportErrors() // need to manually set context mode, otherwise typer.silent will throw exceptions
- reporter.reset()
-
- trace("typing (implicit views = %s, macros = %s): ".format(!withImplicitViewsDisabled, !withMacrosDisabled))(showAttributed(expr, true, true, settings.Yshowsymkinds.value))
- wrapper(currentTyper.silent(_.typed(expr, analyzer.EXPRmode, pt)) match {
- case analyzer.SilentResultValue(result) =>
- trace("success: ")(showAttributed(result, true, true, settings.Yshowsymkinds.value))
- var Block(dummies, unwrapped) = result
- var reversedFreeTermNames = freeTermNames 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 _ =>
- super.transform(tree)
- }
- }.transform(unwrapped)
- new TreeTypeSubstituter(dummies map (_.symbol), dummies map (dummy => SingleType(NoPrefix, reversedFreeTermNames(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))
- EmptyTree
- })
- }
-
- def compileExpr(expr: Tree): (Object, java.lang.reflect.Method) = {
- 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 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 = 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) = {
- // [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 setInfo MethodType(freeTerms map makeParam, AnyClass.tpe)
- minfo.decls enter meth
- trace("wrapping ")(defOwner(expr) -> meth)
- val methdef = DefDef(meth, expr changeOwner (defOwner(expr) -> meth))
- val moduledef = ModuleDef(
- obj,
- Template(
- List(TypeTree(ObjectClass.tpe)),
- emptyValDef,
- NoMods,
- List(),
- List(List()),
- 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
- }
-
- val mdef = wrapExpr(expr)
- val pdef = PackageDef(Ident(nme.EMPTY_PACKAGE_NAME), List(mdef))
- val unit = new CompilationUnit(NoSourceFile)
- unit.body = pdef
-
- val run = new Run
- reporter.reset()
- run.compileUnits(List(unit), run.namerPhase)
- throwIfErrors()
-
- val className = mdef.symbol.fullName
- if (settings.debug.value) println("generated: "+className)
- def moduleFileName(className: String) = className + "$"
- val jclazz = jClass.forName(moduleFileName(className), true, classLoader)
- val jmeth = jclazz.getDeclaredMethods.find(_.getName == wrapperMethodName).get
- val jfield = jclazz.getDeclaredFields.find(_.getName == NameTransformer.MODULE_INSTANCE_NAME).get
- val singleton = jfield.get(null)
- (singleton, jmeth)
- }
-
- 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 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,
- // but there must have been one. So I propose to leave old version in comments to be resurrected if the problem resurfaces.
- // @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)
-// }
- val (singleton, jmeth) = compileExpr(expr)
- jmeth.invoke(singleton, thunks map (_.asInstanceOf[AnyRef]): _*)
- }
-
- def showAttributed(tree: Tree, printTypes: Boolean = true, printIds: Boolean = true, printKinds: Boolean = false): String = {
- val saved1 = settings.printtypes.value
- val saved2 = settings.uniqid.value
- val saved3 = settings.Yshowsymkinds.value
- try {
- settings.printtypes.value = printTypes
- settings.uniqid.value = printIds
- settings.Yshowsymkinds.value = printKinds
- tree.toString
- } finally {
- settings.printtypes.value = saved1
- settings.uniqid.value = saved2
- settings.Yshowsymkinds.value = saved3
- }
- }
-
- // reporter doesn't accumulate errors, but the front-end does
- def throwIfErrors() = {
- if (frontEnd.hasErrors) {
- var msg = "reflective compilation has failed: " + EOL + EOL
- msg += frontEnd.infos map (_.msg) mkString EOL
- throw new ToolBoxError(ToolBox.this, msg)
- }
- }
- }
-
- // todo. is not going to work with quoted arguments with embedded whitespaces
- lazy val arguments = options.split(" ")
-
- lazy val virtualDirectory =
- (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 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)
- }
- 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)
- }
- }
-
- // @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 exporter = importer.reverse
-
- 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 = {
- 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)
-
- 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
- }
-
- 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 = {
- val ctree: compiler.Tree = importer.importTree(tree)
- val ttree: compiler.Tree = compiler.resetAllAttrs(ctree)
- exporter.importTree(ttree)
- }
-
- def resetLocalAttrs(tree: Tree): Tree = {
- val ctree: compiler.Tree = importer.importTree(tree)
- val ttree: compiler.Tree = compiler.resetLocalAttrs(ctree)
- exporter.importTree(ttree)
- }
-
- def showAttributed(tree: 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 = {
- 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)
-
- 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/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 {
* global.settings.encoding.value
.
*
*/
-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/tools/reflect/FrontEnds.scala b/src/compiler/scala/tools/reflect/FrontEnds.scala
new file mode 100644
index 0000000000..52eadc4e04
--- /dev/null
+++ b/src/compiler/scala/tools/reflect/FrontEnds.scala
@@ -0,0 +1,77 @@
+package scala.tools
+package reflect
+
+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()
+ if (minSeverity <= 0) settings.verbose.value = true
+ if (minSeverity > 1) settings.nowarn.value = true
+ wrapReporter(new ConsoleReporter(settings))
+ }
+
+ abstract class FrontEndToReporterProxy(val frontEnd: FrontEnd) extends AbstractReporter {
+ import frontEnd.{Severity => ApiSeverity}
+ val API_INFO = frontEnd.INFO
+ val API_WARNING = frontEnd.WARNING
+ val API_ERROR = frontEnd.ERROR
+
+ type NscSeverity = Severity
+ val NSC_INFO = INFO
+ val NSC_WARNING = WARNING
+ val NSC_ERROR = ERROR
+
+ def display(pos: Position, msg: String, nscSeverity: NscSeverity): Unit =
+ frontEnd.log(pos, msg, nscSeverity match {
+ case NSC_INFO => API_INFO
+ case NSC_WARNING => API_WARNING
+ case NSC_ERROR => API_ERROR
+ })
+
+ def displayPrompt(): Unit =
+ frontEnd.interactive()
+ }
+
+ def wrapFrontEnd(frontEnd: FrontEnd): Reporter = new FrontEndToReporterProxy(frontEnd) {
+ val settings = new Settings()
+ settings.verbose.value = true
+ settings.nowarn.value = false
+ }
+
+ class ReporterToFrontEndProxy(val reporter: Reporter) extends FrontEnd {
+ val API_INFO = INFO
+ val API_WARNING = WARNING
+ val API_ERROR = ERROR
+
+ override def hasErrors = reporter.hasErrors
+ override def hasWarnings = reporter.hasWarnings
+
+ def display(info: Info): Unit = info.severity match {
+ case API_INFO => reporter.info(info.pos, info.msg, false)
+ case API_WARNING => reporter.warning(info.pos, info.msg)
+ case API_ERROR => reporter.error(info.pos, info.msg)
+ }
+
+ def interactive(): Unit = reporter match {
+ case reporter: AbstractReporter => reporter.displayPrompt()
+ case _ => // do nothing
+ }
+
+ override def flush(): Unit = {
+ super.flush()
+ reporter.flush()
+ }
+
+ override def reset(): Unit = {
+ super.reset()
+ reporter.reset()
+ }
+ }
+
+ def wrapReporter(reporter: Reporter): FrontEnd = new ReporterToFrontEndProxy(reporter)
+}
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/tools/reflect/ToolBoxFactory.scala b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala
new file mode 100644
index 0000000000..3ef2337e0f
--- /dev/null
+++ b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala
@@ -0,0 +1,374 @@
+package scala.tools
+package reflect
+
+import scala.tools.nsc.reporters._
+import scala.tools.nsc.ReflectGlobal
+import scala.tools.nsc.CompilerCommand
+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, 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
+
+// [Eugene++ to Martin] by the way, toolboxes are unable to compile anything that involves packages
+// is this intentional?
+
+abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf =>
+
+ 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, toolBoxSelf.classLoader) {
+ import definitions._
+
+ private val trace = scala.tools.nsc.util.trace when settings.debug.value
+
+ private var wrapCount = 0
+
+ private final val wrapperMethodName = "wrapper"
+
+ private def nextWrapperModuleName() = {
+ wrapCount += 1
+ // 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 = {
+ // Previously toolboxes used to typecheck their inputs before compiling.
+ // Actually, the initial demo by Martin first typechecked the reified tree,
+ // then ran it, which typechecked it again, and only then launched the
+ // reflective compiler.
+ //
+ // However, as observed in https://issues.scala-lang.org/browse/SI-5464
+ // current implementation typechecking is not always idempotent.
+ // 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 ToolBoxError("reflective toolbox has failed: cannot operate on trees that are already typed")
+
+ 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 ToolBoxError(msg)
+ }
+ }
+
+ 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)
+ if (namesakes.length > 0) name += ("$" + (namesakes.length + 1))
+ freeTermNames += (ft -> newTermName(name + nme.MIRROR_FREE_VALUE_SUFFIX))
+ })
+ var expr = new Transformer {
+ override def transform(tree: Tree): Tree =
+ if (tree.hasSymbol && tree.symbol.isFreeTerm) {
+ tree match {
+ case Ident(_) =>
+ 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))
+ }
+ } else {
+ super.transform(tree)
+ }
+ }.transform(expr0)
+ (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 = rootMirror.EmptyPackageClass.newClassSymbol(newTypeName(""))
+ 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] _)
+ val wrapper2 = if (!withMacrosDisabled) (currentTyper.context.withMacrosEnabled[Tree] _) else (currentTyper.context.withMacrosDisabled[Tree] _)
+ def wrapper (tree: => Tree) = wrapper1(wrapper2(tree))
+
+ phase = (new Run).typerPhase // need to set a phase to something <= typerPhase, otherwise implicits in typedSelect will be disabled
+ currentTyper.context.setReportErrors() // need to manually set context mode, otherwise typer.silent will throw exceptions
+ reporter.reset()
+
+ trace("typing (implicit views = %s, macros = %s): ".format(!withImplicitViewsDisabled, !withMacrosDisabled))(showAttributed(expr, true, true, settings.Yshowsymkinds.value))
+ wrapper(currentTyper.silent(_.typed(expr, analyzer.EXPRmode, pt)) match {
+ case analyzer.SilentResultValue(result) =>
+ trace("success: ")(showAttributed(result, true, true, settings.Yshowsymkinds.value))
+ var Block(dummies, unwrapped) = result
+ 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 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, invertedIndex(dummy.symbol.name)))).traverse(unwrapped)
+ unwrapped
+ case error @ analyzer.SilentTypeError(_) =>
+ trace("failed: ")(error.err.errMsg)
+ if (!silent) throw ToolBoxError("reflective typecheck has failed: %s".format(error.err.errMsg))
+ EmptyTree
+ })
+ }
+
+ def compileExpr(expr: Tree): (Object, java.lang.reflect.Method) = {
+ verifyExpr(expr)
+
+ def wrapExpr(expr0: Tree): Tree = {
+ val (expr, freeTerms) = extractFreeTerms(expr0, wrapFreeTermRefs = true)
+
+ val (obj, mclazz) = rootMirror.EmptyPackageClass.newModuleAndClassSymbol(
+ 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(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(name) setInfo 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(
+ List(TypeTree(ObjectClass.tpe)),
+ emptyValDef,
+ NoMods,
+ List(),
+ List(List()),
+ 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
+ }
+
+ val mdef = wrapExpr(expr)
+ val pdef = PackageDef(Ident(nme.EMPTY_PACKAGE_NAME), List(mdef))
+ val unit = new CompilationUnit(NoSourceFile)
+ unit.body = pdef
+
+ val run = new Run
+ reporter.reset()
+ run.compileUnits(List(unit), run.namerPhase)
+ throwIfErrors()
+
+ val className = mdef.symbol.fullName
+ if (settings.debug.value) println("generated: "+className)
+ def moduleFileName(className: String) = className + "$"
+ val jclazz = jClass.forName(moduleFileName(className), true, classLoader)
+ val jmeth = jclazz.getDeclaredMethods.find(_.getName == wrapperMethodName).get
+ val jfield = jclazz.getDeclaredFields.find(_.getName == NameTransformer.MODULE_INSTANCE_NAME).get
+ val singleton = jfield.get(null)
+ (singleton, jmeth)
+ }
+
+ def runExpr(expr: Tree, freeTypes: Map[TypeName, Type] = Map[TypeName, Type]()): Any = {
+ 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,
+ // but there must have been one. So I propose to leave old version in comments to be resurrected if the problem resurfaces.
+ // @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
+ // @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)
+ 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("", 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 = {
+ val saved1 = settings.printtypes.value
+ val saved2 = settings.uniqid.value
+ val saved3 = settings.Yshowsymkinds.value
+ try {
+ settings.printtypes.value = printTypes
+ settings.uniqid.value = printIds
+ settings.Yshowsymkinds.value = printKinds
+ tree.toString
+ } finally {
+ settings.printtypes.value = saved1
+ settings.uniqid.value = saved2
+ settings.Yshowsymkinds.value = saved3
+ }
+ }
+
+ // reporter doesn't accumulate errors, but the front-end does
+ def throwIfErrors() = {
+ if (frontEnd.hasErrors) {
+ var msg = "reflective compilation has failed: " + EOL + EOL
+ msg += frontEnd.infos map (_.msg) mkString EOL
+ throw ToolBoxError(msg)
+ }
+ }
+ }
+
+ // todo. is not going to work with quoted arguments with embedded whitespaces
+ lazy val arguments = options.split(" ")
+
+ lazy val virtualDirectory =
+ (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(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 ToolBoxError(msg)
+ }
+ instance
+ } catch {
+ case ex: Throwable =>
+ var msg = "reflective compilation has failed: cannot initialize the compiler due to %s".format(ex.toString)
+ throw ToolBoxError(msg, ex)
+ }
+ }
+
+ lazy val importer = compiler.mkImporter(u)
+ lazy val exporter = importer.reverse
+ lazy val classLoader = new AbstractFileClassLoader(virtualDirectory, mirror.classLoader)
+
+ 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.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 uttree = exporter.importTree(ttree)
+ uttree
+ }
+
+ def inferImplicitValue(pt: u.Type, silent: Boolean, withMacrosDisabled: Boolean): u.Tree =
+ // todo. implement this
+ ???
+
+ 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: u.Tree): u.Tree = {
+ val ctree: compiler.Tree = importer.importTree(tree)
+ val ttree: compiler.Tree = compiler.resetAllAttrs(ctree)
+ val uttree = exporter.importTree(ttree)
+ uttree
+ }
+
+ def resetLocalAttrs(tree: u.Tree): u.Tree = {
+ val ctree: compiler.Tree = importer.importTree(tree)
+ val ttree: compiler.Tree = compiler.resetLocalAttrs(ctree)
+ val uttree = exporter.importTree(ttree)
+ uttree
+ }
+
+ def showAttributed(tree: u.Tree, printTypes: Boolean = true, printIds: Boolean = true, printKinds: Boolean = false): String =
+ compiler.showAttributed(importer.importTree(tree), printTypes, printIds, printKinds)
+
+ 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.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)
+ }
+ }
+}
+
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 = ctx.getTrivialValue; ... <--- TODO: try/catch ??? don't bother for the moment...
// else
// ctx.flatMap { => ... }
- 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/ReflectionUtils.scala b/src/library/scala/reflect/ReflectionUtils.scala
deleted file mode 100644
index aa1285d5a0..0000000000
--- a/src/library/scala/reflect/ReflectionUtils.scala
+++ /dev/null
@@ -1,90 +0,0 @@
-/* NSC -- new Scala compiler
- * Copyright 2005-2011 LAMP/EPFL
- * @author Paul Phillips
- */
-
-package scala.reflect
-
-import java.lang.{Class => jClass}
-import java.lang.reflect.{ InvocationTargetException, UndeclaredThrowableException }
-
-/** A few java-reflection oriented utility functions useful during reflection bootstrapping.
- */
-object ReflectionUtils {
- // Unwraps some chained exceptions which arise during reflective calls.
- def unwrapThrowable(x: Throwable): Throwable = x match {
- case _: InvocationTargetException | // thrown by reflectively invoked method or constructor
- _: ExceptionInInitializerError | // thrown when running a static initializer (e.g. a scala module constructor)
- _: UndeclaredThrowableException | // invocation on a proxy instance if its invocation handler's `invoke` throws an exception
- _: ClassNotFoundException | // no definition for a class instantiated by name
- _: NoClassDefFoundError // the definition existed when the executing class was compiled, but can no longer be found
- if x.getCause != null =>
- unwrapThrowable(x.getCause)
- case _ => x
- }
- // Transforms an exception handler into one which will only receive the unwrapped
- // exceptions (for the values of wrap covered in unwrapThrowable.)
- def unwrapHandler[T](pf: PartialFunction[Throwable, T]): PartialFunction[Throwable, T] = {
- case ex if pf isDefinedAt unwrapThrowable(ex) => pf(unwrapThrowable(ex))
- }
-
- private def systemProperties: Iterator[(String, String)] = {
- import scala.collection.JavaConverters._
- System.getProperties.asScala.iterator
- }
-
- private def inferBootClasspath: String = (
- systemProperties find (_._1 endsWith ".boot.class.path") map (_._2) getOrElse ""
- )
-
- def show(cl: ClassLoader) = {
- def inferClasspath(cl: ClassLoader): String = cl match {
- case cl: java.net.URLClassLoader =>
- "[" + (cl.getURLs mkString ",") + "]"
- case cl if cl != null && cl.getClass.getName == "scala.tools.nsc.interpreter.AbstractFileClassLoader" =>
- "[" + cl.asInstanceOf[{val root: api.RequiredFile}].root + "] and " + inferClasspath(cl.getParent)
- case null =>
- inferBootClasspath
- case _ =>
- ""
- }
- cl match {
- case cl if cl != null =>
- "%s of type %s with classpath %s".format(cl, cl.getClass, inferClasspath(cl))
- case null =>
- "primordial classloader with boot classpath [%s]".format(inferClasspath(cl))
- }
- }
-
- def 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)
- val singleton = clazz getField "MODULE$" get null
- singleton
- }
-
- // Retrieves the MODULE$ field for the given class name.
- def singletonInstanceOpt(cl: ClassLoader, className: String): Option[AnyRef] =
- try Some(singletonInstance(cl, className))
- catch { case _: ClassNotFoundException => None }
-
- def invokeFactory(cl: ClassLoader, className: String, methodName: String, args: AnyRef*): AnyRef = {
- val singleton = singletonInstance(cl, className)
- val method = singleton.getClass.getMethod(methodName, classOf[ClassLoader])
- method.invoke(singleton, args: _*)
- }
-
- def invokeFactoryOpt(cl: ClassLoader, className: String, methodName: String, args: AnyRef*): Option[AnyRef] =
- try Some(invokeFactory(cl, className, methodName, args: _*))
- catch { case _: ClassNotFoundException => None }
-}
diff --git a/src/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 `.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 `.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 `.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/RequiredFile.scala b/src/library/scala/reflect/api/RequiredFile.scala
deleted file mode 100644
index 4a54595940..0000000000
--- a/src/library/scala/reflect/api/RequiredFile.scala
+++ /dev/null
@@ -1,7 +0,0 @@
-package scala.reflect
-package api
-
-trait RequiredFile {
- def path: String
- def canonicalPath: String
-}
diff --git a/src/library/scala/reflect/api/Scopes.scala b/src/library/scala/reflect/api/Scopes.scala
deleted file mode 100755
index 4a5702eadc..0000000000
--- a/src/library/scala/reflect/api/Scopes.scala
+++ /dev/null
@@ -1,16 +0,0 @@
-package scala.reflect
-package api
-
-trait Scopes { self: Universe =>
-
- type Scope <: Iterable[Symbol]
-
- /** Create a new scope */
- def newScope: Scope
-
- /** Create a new scope nested in another one with which it shares its elements */
- def newNestedScope(outer: Scope): Scope
-
- /** Create a new scope with given initial elements */
- def newScopeWith(elems: Symbol*): Scope
-}
\ No newline at end of file
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 ")
- 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).(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 . */
- 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 */
- 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 # , 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 with ... with { }, eliminated by RefCheck */
- case class CompoundTypeTree(templ: Template)
- extends TypTree
+ override type This >: Null <: TermTree with SymTree with ThisApi
- /** Applied type [ ], 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(, 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).[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/TypeTags.scala b/src/library/scala/reflect/api/TypeTags.scala
deleted file mode 100644
index c58b0fcec2..0000000000
--- a/src/library/scala/reflect/api/TypeTags.scala
+++ /dev/null
@@ -1,254 +0,0 @@
-/* NSC -- new Scala compiler
- * Copyright 2005-2011 LAMP/EPFL
- * @author Martin Odersky
- */
-
-package scala.reflect
-package api
-
-import java.lang.{ Class => jClass }
-import language.implicitConversions
-
-/**
- * Type tags encapsulate a representation of type T.
- * They are supposed to replace the pre-2.10 concept of a [[scala.reflect.Manifest]].
- * TypeTags are much better integrated with reflection than manifests are, and are consequently much simpler.
- *
- * === 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]].
- *
- * 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,
- * 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]].
- * 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]]
- * 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.
- *
- * === Splicing ===
- *
- * Tags can be spliced, i.e. if compiler generates a tag for a type that contains references to tagged
- * type parameters or abstract type members, it will retrieve the corresponding tag and embed it into the result.
- * An example that illustrates the TypeTag embedding, consider the following function:
- *
- * import reflect.mirror._
- * def f[T: TypeTag, U] = {
- * type L = T => U
- * implicitly[TypeTag[L]]
- * }
- *
- * Then a call of f[String, Int] will yield a result of the form
- *
- * TypeTag(<[ String => U ]>).
- *
- * 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 ===
- *
- * Be careful with ErasureTag and TypeTag, because they 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:
- *
- * def bind[T: TypeTag](name: String, value: T): IR.Result = bind((name, value))
- * def bind(p: NamedParam): IR.Result = bind(p.name, p.tpe, p.value)
- * object NamedParam {
- * implicit def namedValue[T: TypeTag](name: String, x: T): NamedParam = apply(name, x)
- * def apply[T: TypeTag](name: String, x: T): NamedParam = new Typed[T](name, x)
- * }
- *
- * 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
- * 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,
- * because the missing `TypeTag` will be transparently generated by the compiler, carrying meaningless information.
- * Most likely, this problem will manifest itself elsewhere, making debugging complicated.
- * If `TypeTag` context bounds were replaced with `ConcreteTypeTag`, then such errors would be reported statically.
- * But in that case we wouldn't be able to use `bind` in arbitrary contexts.
- *
- * === Backward compatibility ===
- *
- * TypeTags correspond loosely to Manifests. More precisely:
- * The previous notion of a [[scala.reflect.ClassManifest]] corresponds to a scala.reflect.ClassTag,
- * The previous notion of a [[scala.reflect.Manifest]] corresponds to scala.reflect.mirror.ConcreteTypeTag,
- * Whereas scala.reflect.mirror.TypeTag is approximated by the previous notion of [[scala.reflect.OptManifest]].
- *
- * In Scala 2.10, manifests are deprecated, so it's adviseable to migrate them to tags,
- * because manifests might be removed in the next major release.
- *
- * In most cases it will be enough to replace ClassManifests with ClassTags and Manifests with ConcreteTypeTags,
- * 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.
- *
- * 2) There's no equivalent for AnyValManifest. Consider comparing your tag with one of the core tags
- * (defined in the corresponding companion objects) to find out whether it represents a primitive value class.
- *
- * 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).
- *
- * 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.
- */
-trait TypeTags { self: Universe =>
-
- /**
- * If an implicit value of type u.TypeTag[T] is required, the compiler will make one up on demand.
- * The implicitly created value contains in its tpe field a value of type u.Type that is a reflective representation of T.
- * 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]]
- */
- @annotation.implicitNotFound(msg = "No TypeTag available for ${T}")
- trait TypeTag[T] extends ErasureTag[T] with Equals with Serializable {
-
- 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[?]"
- }
-
- object TypeTag {
- val Byte : TypeTag[scala.Byte] = ConcreteTypeTag.Byte
- val Short : TypeTag[scala.Short] = ConcreteTypeTag.Short
- val Char : TypeTag[scala.Char] = ConcreteTypeTag.Char
- val Int : TypeTag[scala.Int] = ConcreteTypeTag.Int
- val Long : TypeTag[scala.Long] = ConcreteTypeTag.Long
- val Float : TypeTag[scala.Float] = ConcreteTypeTag.Float
- val Double : TypeTag[scala.Double] = ConcreteTypeTag.Double
- val Boolean : TypeTag[scala.Boolean] = ConcreteTypeTag.Boolean
- 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 {
- case ByteTpe => TypeTag.Byte.asInstanceOf[TypeTag[T]]
- case ShortTpe => TypeTag.Short.asInstanceOf[TypeTag[T]]
- case CharTpe => TypeTag.Char.asInstanceOf[TypeTag[T]]
- case IntTpe => TypeTag.Int.asInstanceOf[TypeTag[T]]
- case LongTpe => TypeTag.Long.asInstanceOf[TypeTag[T]]
- case FloatTpe => TypeTag.Float.asInstanceOf[TypeTag[T]]
- case DoubleTpe => TypeTag.Double.asInstanceOf[TypeTag[T]]
- case BooleanTpe => TypeTag.Boolean.asInstanceOf[TypeTag[T]]
- 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 }
- }
-
- def unapply[T](ttag: TypeTag[T]): Option[Type] = Some(ttag.tpe)
- }
-
- /**
- * 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]]
- */
- @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))
- }
-
- /** 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[?]"
- }
-
- 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 {
- case ByteTpe => ConcreteTypeTag.Byte.asInstanceOf[ConcreteTypeTag[T]]
- case ShortTpe => ConcreteTypeTag.Short.asInstanceOf[ConcreteTypeTag[T]]
- case CharTpe => ConcreteTypeTag.Char.asInstanceOf[ConcreteTypeTag[T]]
- case IntTpe => ConcreteTypeTag.Int.asInstanceOf[ConcreteTypeTag[T]]
- case LongTpe => ConcreteTypeTag.Long.asInstanceOf[ConcreteTypeTag[T]]
- case FloatTpe => ConcreteTypeTag.Float.asInstanceOf[ConcreteTypeTag[T]]
- case DoubleTpe => ConcreteTypeTag.Double.asInstanceOf[ConcreteTypeTag[T]]
- case BooleanTpe => ConcreteTypeTag.Boolean.asInstanceOf[ConcreteTypeTag[T]]
- 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 }
- }
-
- def unapply[T](ttag: TypeTag[T]): Option[Type] = if (ttag.isConcrete) Some(ttag.tpe) else None
- }
-
- // 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
-}
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, )`, where `` 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 =
- * $mr.Expr[Int]($mr.Apply($mr.Select($mr.Ident($mr.newFreeVar("x", , 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", , 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("")
+ val EMPTY_PACKAGE_NAME = newTermName("")
+ val CONSTRUCTOR = newTermName("")
+ val NO_NAME = newTermName("")
+ 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""
+
+ 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/base/Scopes.scala b/src/library/scala/reflect/base/Scopes.scala
new file mode 100644
index 0000000000..a5db01c0ce
--- /dev/null
+++ b/src/library/scala/reflect/base/Scopes.scala
@@ -0,0 +1,21 @@
+package scala.reflect
+package base
+
+trait Scopes { self: Universe =>
+
+ 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
+
+ /** Create a new scope nested in another one with which it shares its elements */
+ def newNestedScope(outer: Scope): Scope
+
+ /** Create a new scope with given initial elements */
+ def newScopeWith(elems: Symbol*): Scope
+}
\ No newline at end of file
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(, 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).[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 . */
+ 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 */
+ 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 # , 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 with ... with { }, 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 [ ], 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).(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/base/TypeTags.scala b/src/library/scala/reflect/base/TypeTags.scala
new file mode 100644
index 0000000000..5c55f45cf7
--- /dev/null
+++ b/src/library/scala/reflect/base/TypeTags.scala
@@ -0,0 +1,253 @@
+/* NSC -- new Scala compiler
+ * Copyright 2005-2011 LAMP/EPFL
+ * @author Martin Odersky
+ */
+
+package scala.reflect
+package base
+
+import java.lang.{ Class => jClass }
+import language.implicitConversions
+
+/**
+ * Type tags encapsulate a representation of type T.
+ * They are supposed to replace the pre-2.10 concept of a [[scala.reflect.Manifest]].
+ * TypeTags are much better integrated with reflection than manifests are, and are consequently much simpler.
+ *
+ * === Overview ===
+ *
+ * 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 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.
+ *
+ * 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.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.
+ *
+ * It is recommended to use the tag supertypes of to precisely express your intent, i.e.:
+ * 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 ===
+ *
+ * Tags can be spliced, i.e. if compiler generates a tag for a type that contains references to tagged
+ * type parameters or abstract type members, it will retrieve the corresponding tag and embed it into the result.
+ * An example that illustrates the TypeTag embedding, consider the following function:
+ *
+ * import reflect.mirror._
+ * def f[T: TypeTag, U] = {
+ * type L = T => U
+ * implicitly[TypeTag[L]]
+ * }
+ *
+ * Then a call of f[String, Int] will yield a result of the form
+ *
+ * TypeTag(<[ String => U ]>).
+ *
+ * Note that T has been replaced by String, because it comes with a TypeTag in f, whereas U was left as a type parameter.
+ *
+ * === TypeTag vs ConcreteTypeTag ===
+ *
+ * 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:
+ *
+ * def bind[T: TypeTag](name: String, value: T): IR.Result = bind((name, value))
+ * def bind(p: NamedParam): IR.Result = bind(p.name, p.tpe, p.value)
+ * object NamedParam {
+ * implicit def namedValue[T: TypeTag](name: String, x: T): NamedParam = apply(name, x)
+ * def apply[T: TypeTag](name: String, x: T): NamedParam = new Typed[T](name, x)
+ * }
+ *
+ * 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.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,
+ * because the missing `TypeTag` will be transparently generated by the compiler, carrying meaningless information.
+ * Most likely, this problem will manifest itself elsewhere, making debugging complicated.
+ * If `TypeTag` context bounds were replaced with `ConcreteTypeTag`, then such errors would be reported statically.
+ * But in that case we wouldn't be able to use `bind` in arbitrary contexts.
+ *
+ * === Backward compatibility ===
+ *
+ * TypeTags correspond loosely to Manifests. More precisely:
+ * The previous notion of a [[scala.reflect.ClassManifest]] corresponds to a scala.reflect.ClassTag,
+ * The previous notion of a [[scala.reflect.Manifest]] corresponds to scala.reflect.mirror.ConcreteTypeTag,
+ * Whereas scala.reflect.mirror.TypeTag is approximated by the previous notion of [[scala.reflect.OptManifest]].
+ *
+ * In Scala 2.10, manifests are deprecated, so it's adviseable to migrate them to tags,
+ * because manifests might be removed in the next major release.
+ *
+ * In most cases it will be enough to replace ClassManifests with ClassTags and Manifests with ConcreteTypeTags,
+ * 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.
+ *
+ * 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 `.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).
+ *
+ * 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 =>
+
+ /**
+ * If an implicit value of type u.TypeTag[T] is required, the compiler will make one up on demand.
+ * The implicitly created value contains in its tpe field a value of type u.Type that is a reflective representation of T.
+ * 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.base.TypeTags]]
+ */
+ @annotation.implicitNotFound(msg = "No TypeTag available for ${T}")
+ 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
+
+ /** case class accessories */
+ override def canEqual(x: Any) = x.isInstanceOf[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 {
+ val Byte : TypeTag[scala.Byte] = ConcreteTypeTag.Byte
+ val Short : TypeTag[scala.Short] = ConcreteTypeTag.Short
+ val Char : TypeTag[scala.Char] = ConcreteTypeTag.Char
+ val Int : TypeTag[scala.Int] = ConcreteTypeTag.Int
+ val Long : TypeTag[scala.Long] = ConcreteTypeTag.Long
+ val Float : TypeTag[scala.Float] = ConcreteTypeTag.Float
+ val Double : TypeTag[scala.Double] = ConcreteTypeTag.Double
+ val Boolean : TypeTag[scala.Boolean] = ConcreteTypeTag.Boolean
+ val Unit : TypeTag[scala.Unit] = ConcreteTypeTag.Unit
+ val Any : TypeTag[scala.Any] = ConcreteTypeTag.Any
+ val Object : TypeTag[java.lang.Object] = ConcreteTypeTag.Object
+ val Nothing : TypeTag[scala.Nothing] = ConcreteTypeTag.Nothing
+ val Null : TypeTag[scala.Null] = ConcreteTypeTag.Null
+ val String : TypeTag[java.lang.String] = ConcreteTypeTag.String
+
+ 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]]
+ case IntTpe => TypeTag.Int.asInstanceOf[TypeTag[T]]
+ case LongTpe => TypeTag.Long.asInstanceOf[TypeTag[T]]
+ case FloatTpe => TypeTag.Float.asInstanceOf[TypeTag[T]]
+ case DoubleTpe => TypeTag.Double.asInstanceOf[TypeTag[T]]
+ case BooleanTpe => TypeTag.Boolean.asInstanceOf[TypeTag[T]]
+ case UnitTpe => TypeTag.Unit.asInstanceOf[TypeTag[T]]
+ case AnyTpe => TypeTag.Any.asInstanceOf[TypeTag[T]]
+ case ObjectTpe => TypeTag.Object.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 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.base.TypeTags]]
+ */
+ @annotation.implicitNotFound(msg = "No ConcreteTypeTag available for ${T}")
+ trait ConcreteTypeTag[T] extends TypeTag[T] with Equals with Serializable {
+ /** case class accessories */
+ 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 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]]
+ case IntTpe => ConcreteTypeTag.Int.asInstanceOf[ConcreteTypeTag[T]]
+ case LongTpe => ConcreteTypeTag.Long.asInstanceOf[ConcreteTypeTag[T]]
+ case FloatTpe => ConcreteTypeTag.Float.asInstanceOf[ConcreteTypeTag[T]]
+ case DoubleTpe => ConcreteTypeTag.Double.asInstanceOf[ConcreteTypeTag[T]]
+ case BooleanTpe => ConcreteTypeTag.Boolean.asInstanceOf[ConcreteTypeTag[T]]
+ case UnitTpe => ConcreteTypeTag.Unit.asInstanceOf[ConcreteTypeTag[T]]
+ case AnyTpe => ConcreteTypeTag.Any.asInstanceOf[ConcreteTypeTag[T]]
+ case ObjectTpe => ConcreteTypeTag.Object.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 ConcreteTypeTagImpl[T](mirror1.asInstanceOf[Mirror], tpec1)
+ }
+
+ 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)
+ }
+ }
+
+ 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, )`, where `` 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 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)
--
cgit v1.2.3