summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
authorEugene Burmako <xeno.by@gmail.com>2013-08-10 15:16:09 +0200
committerEugene Burmako <xeno.by@gmail.com>2013-08-16 19:20:18 +0200
commit4a273659e0e25ccfe7ea9d4eafa4a9c87ee2fc82 (patch)
treeec6fbd3100fb8adb1d98dd31d6fe6872d114775b /src/compiler
parent83e95c0fa5168e64299d85b081b21c577ce4e8ef (diff)
downloadscala-4a273659e0e25ccfe7ea9d4eafa4a9c87ee2fc82.tar.gz
scala-4a273659e0e25ccfe7ea9d4eafa4a9c87ee2fc82.tar.bz2
scala-4a273659e0e25ccfe7ea9d4eafa4a9c87ee2fc82.zip
kills introduceTopLevel
As we've figured out from the practice, introduceTopLevel is seductively useful but unfortunately not robust, potentially bringing compilation order problems. Therefore, as discussed, I'm removing it from the public macro API. Alternatives are either: 1) delving into internals, or 2) using macro paradise and experimenting with macro annotations: http://docs.scala-lang.org/overviews/macros/annotations.html.
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/scala/reflect/macros/contexts/Context.scala1
-rw-r--r--src/compiler/scala/reflect/macros/contexts/Synthetics.scala66
-rw-r--r--src/compiler/scala/tools/nsc/CompilationUnits.scala4
3 files changed, 2 insertions, 69 deletions
diff --git a/src/compiler/scala/reflect/macros/contexts/Context.scala b/src/compiler/scala/reflect/macros/contexts/Context.scala
index bd1d7d5248..1355a839d9 100644
--- a/src/compiler/scala/reflect/macros/contexts/Context.scala
+++ b/src/compiler/scala/reflect/macros/contexts/Context.scala
@@ -14,7 +14,6 @@ abstract class Context extends scala.reflect.macros.Context
with Parsers
with Evals
with ExprUtils
- with Synthetics
with Traces {
val universe: Global
diff --git a/src/compiler/scala/reflect/macros/contexts/Synthetics.scala b/src/compiler/scala/reflect/macros/contexts/Synthetics.scala
deleted file mode 100644
index ada16a8113..0000000000
--- a/src/compiler/scala/reflect/macros/contexts/Synthetics.scala
+++ /dev/null
@@ -1,66 +0,0 @@
-/* NSC -- new Scala compiler
- * Copyright 2005-2013 LAMP/EPFL
- */
-
-package scala.reflect.macros
-package contexts
-
-import scala.reflect.internal.Flags._
-import scala.reflect.internal.util.BatchSourceFile
-import scala.reflect.io.VirtualFile
-
-trait Synthetics {
- self: Context =>
-
- import global._
- import mirror.wrapMissing
-
- // getClassIfDefined and getModuleIfDefined cannot be used here
- // because they don't work for stuff declared in the empty package
- // (as specified in SLS, code inside non-empty packages cannot see
- // declarations from the empty package, so compiler internals
- // default to ignoring contents of the empty package)
- // to the contrast, staticModule and staticClass are designed
- // to be a part of the reflection API and, therefore, they
- // correctly resolve all names
- private def topLevelSymbol(name: Name): Symbol = wrapMissing {
- if (name.isTermName) mirror.staticModule(name.toString)
- else mirror.staticClass(name.toString)
- }
-
- def topLevelDef(name: Name): Tree =
- enclosingRun.units.toList.map(_.body).flatMap {
- // it's okay to check `stat.symbol` here, because currently macros expand strictly after namer
- // which means that by the earliest time one can call this method all top-level definitions will have already been entered
- case PackageDef(_, stats) => stats filter (stat => stat.symbol != NoSymbol && stat.symbol == topLevelSymbol(name))
- case _ => Nil // should never happen, but better be safe than sorry
- }.headOption getOrElse EmptyTree
-
- def topLevelRef(name: Name): Tree = {
- if (topLevelDef(name).nonEmpty) gen.mkUnattributedRef(name)
- else EmptyTree
- }
-
- def introduceTopLevel[T: PackageSpec](packagePrototype: T, definition: universe.ImplDef): RefTree =
- introduceTopLevel(packagePrototype, List(definition)).head
-
- def introduceTopLevel[T: PackageSpec](packagePrototype: T, definitions: universe.ImplDef*): List[RefTree] =
- introduceTopLevel(packagePrototype, definitions.toList)
-
- private def introduceTopLevel[T: PackageSpec](packagePrototype: T, definitions: List[universe.ImplDef]): List[RefTree] = {
- val code @ PackageDef(pid, _) = implicitly[PackageSpec[T]].mkPackageDef(packagePrototype, definitions)
- universe.currentRun.compileLate(code)
- definitions map (definition => Select(pid, definition.name))
- }
-
- protected def mkPackageDef(name: String, stats: List[Tree]) = gen.mkPackageDef(name, stats)
-
- protected def mkPackageDef(name: TermName, stats: List[Tree]) = gen.mkPackageDef(name.toString, stats)
-
- protected def mkPackageDef(tree: RefTree, stats: List[Tree]) = PackageDef(tree, stats)
-
- protected def mkPackageDef(sym: Symbol, stats: List[Tree]) = {
- assert(sym hasFlag PACKAGE, s"expected a package or package class symbol, found: $sym")
- gen.mkPackageDef(sym.fullName.toString, stats)
- }
-}
diff --git a/src/compiler/scala/tools/nsc/CompilationUnits.scala b/src/compiler/scala/tools/nsc/CompilationUnits.scala
index b52e6fdf57..efe436f004 100644
--- a/src/compiler/scala/tools/nsc/CompilationUnits.scala
+++ b/src/compiler/scala/tools/nsc/CompilationUnits.scala
@@ -57,8 +57,8 @@ trait CompilationUnits { self: Global =>
// SBT compatibility (SI-6875)
//
// imagine we have a file named A.scala, which defines a trait named Foo and a module named Main
- // Main contains a call to a macro, which calls c.introduceTopLevel to define a mock for Foo
- // c.introduceTopLevel creates a virtual file Virt35af32.scala, which contains a class named FooMock extending Foo,
+ // Main contains a call to a macro, which calls compileLate to define a mock for Foo
+ // compileLate creates a virtual file Virt35af32.scala, which contains a class named FooMock extending Foo,
// and macro expansion instantiates FooMock. the stage is now set. let's see what happens next.
//
// without this workaround in scalac or without being patched itself, sbt will think that