diff options
23 files changed, 3 insertions, 358 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 diff --git a/src/reflect/scala/reflect/macros/Context.scala b/src/reflect/scala/reflect/macros/Context.scala index 434b7c1b9c..b0c816f4ad 100644 --- a/src/reflect/scala/reflect/macros/Context.scala +++ b/src/reflect/scala/reflect/macros/Context.scala @@ -37,8 +37,7 @@ trait Context extends Aliases with Typers with Parsers with Evals - with ExprUtils - with Synthetics { + with ExprUtils { /** The compile-time universe. */ val universe: Universe diff --git a/src/reflect/scala/reflect/macros/Synthetics.scala b/src/reflect/scala/reflect/macros/Synthetics.scala deleted file mode 100644 index 5e422ee89f..0000000000 --- a/src/reflect/scala/reflect/macros/Synthetics.scala +++ /dev/null @@ -1,107 +0,0 @@ -package scala -package reflect -package macros - -/** - * <span class="badge badge-red" style="float: right;">EXPERIMENTAL</span> - * - * A slice of [[scala.reflect.macros.Context the Scala macros context]] that - * exposes functions to introduce synthetic definitions. - * - * @define TOPLEVEL_TREE Top-level tree is a tree that represents a non-inner class or object in one of the currently compiled source files. - * Note that top-level isn't equivalent to [[scala.reflect.api.Symbols#SymbolApi.isStatic]], - * because static also embraces definitions nested in static objects - * - * @define INTRODUCE_TOP_LEVEL Allowed definitions include classes (represented by `ClassDef` trees), traits (represented - * by `ClassDef` trees having the `TRAIT` flag set in `mods`) and objects (represented by `ModuleDef` trees). - * - * The definitions are put into the package with a prototype provided in `packagePrototype`. - * Supported prototypes are (see [[PackageSpec]] for more details): - * * Strings and names representing a fully-qualified name of the package - * * Trees that can work as package ids - * * Package or package class symbols - * - * Typical value for a package prototype is a fully-qualified name in a string. - * For example, to generate a class available at `foo.bar.Test`, call this method as follows: - * - * introduceTopLevel("foo.bar", ClassDef(<mods>, TypeName("Test"), <tparams>, <template>)) - * - * It is possible to add definitions to the empty package by using `nme.EMPTY_PACKAGE_NAME.toString`, but - * that's not recommended, since such definitions cannot be seen from outside the empty package. - * - * Only the multi-parameter overload of this method can be used to introduce companions. - * If companions are introduced by two different calls, then they will be put into different virtual files, and `scalac` - * will show an error about companions being defined in different files. By the way, this also means that there's currently no way - * to define a companion for an existing class or module - */ -trait Synthetics { - self: Context => - - import universe._ - - /** Looks up a top-level definition tree with a given fully-qualified name - * (term name for modules, type name for classes). $TOPLEVEL_TREE. - * If such a tree does not exist, returns `EmptyTree`. - */ - def topLevelDef(name: Name): Tree - - /** Returns a reference to a top-level definition tree with a given fully-qualified name - * (term name for modules, type name for classes). $TOPLEVEL_TREE. - * If such a tree does not exist, returns `EmptyTree`. - */ - def topLevelRef(name: Name): Tree - - /** Adds a top-level definition to the compiler's symbol table. $INTRODUCE_TOP_LEVEL. - * - * Returns a fully-qualified reference to the introduced definition. - */ - def introduceTopLevel[T: PackageSpec](packagePrototype: T, definition: ImplDef): RefTree - - /** Adds a list of top-level definitions to the compiler's symbol table. $INTRODUCE_TOP_LEVEL. - * - * Returns a list of fully-qualified references to the introduced definitions. - */ - def introduceTopLevel[T: PackageSpec](packagePrototype: T, definitions: ImplDef*): List[RefTree] - - /** A factory which can create a package def from a prototype and a list of declarations. - */ - trait PackageSpec[T] { def mkPackageDef(prototype: T, stats: List[Tree]): PackageDef } - - /** Hosts supported package specs. - */ - object PackageSpec { - /** Package def can be created from a fully-qualified name and a list of definitions. - * The name is converted into an Ident or a chain of Selects. - */ - implicit val stringIsPackageSpec = new PackageSpec[String] { - def mkPackageDef(prototype: String, stats: List[Tree]): PackageDef = self.mkPackageDef(prototype, stats) - } - - /** Package def can be created from a fully-qualified term name and a list of definitions. - * The name is converted into an Ident or a chain of Selects. - */ - implicit val termNameIsPackageSpec = new PackageSpec[TermName] { - def mkPackageDef(prototype: TermName, stats: List[Tree]): PackageDef = self.mkPackageDef(prototype, stats) - } - - /** Package def can be created from a package id tree and a list of definitions. - * If the tree is not a valid package id, i.e. is not a term-name ident or a chain of term-name selects, - * then the produced PackageDef will fail compilation at some point in the future. - */ - implicit val refTreeIsPackageSpec = new PackageSpec[RefTree] { - def mkPackageDef(prototype: RefTree, stats: List[Tree]): PackageDef = self.mkPackageDef(prototype, stats) - } - - /** Package def can be created from a package/package class symbol and a list of definitions. - * If the provided symbol is not a package symbol or a package class symbol, package construction will throw an exception. - */ - implicit val SymbolIsPackageSpec = new PackageSpec[Symbol] { - def mkPackageDef(prototype: Symbol, stats: List[Tree]): PackageDef = self.mkPackageDef(prototype, stats) - } - } - - protected def mkPackageDef(name: String, stats: List[Tree]): PackageDef - protected def mkPackageDef(name: TermName, stats: List[Tree]): PackageDef - protected def mkPackageDef(tree: RefTree, stats: List[Tree]): PackageDef - protected def mkPackageDef(sym: Symbol, stats: List[Tree]): PackageDef -} diff --git a/test/files/run/macro-expand-unapply-b.check b/test/files/run/macro-expand-unapply-b.check deleted file mode 100644 index 5272f0d00a..0000000000 --- a/test/files/run/macro-expand-unapply-b.check +++ /dev/null @@ -1,2 +0,0 @@ -(1,List(2)) -List(1) diff --git a/test/files/run/macro-expand-unapply-b.flags b/test/files/run/macro-expand-unapply-b.flags deleted file mode 100644 index cd66464f2f..0000000000 --- a/test/files/run/macro-expand-unapply-b.flags +++ /dev/null @@ -1 +0,0 @@ --language:experimental.macros
\ No newline at end of file diff --git a/test/files/run/macro-expand-unapply-b/Impls_Macros_1.scala b/test/files/run/macro-expand-unapply-b/Impls_Macros_1.scala deleted file mode 100644 index d0300bdf7e..0000000000 --- a/test/files/run/macro-expand-unapply-b/Impls_Macros_1.scala +++ /dev/null @@ -1,37 +0,0 @@ -import language.experimental.macros -import scala.reflect.macros.Context - -object Macros { - implicit class ContextExtensions(c: StringContext) { - object q { - def unapply(x: Any): Option[Any] = macro impl - } - } - - def impl(c: Context)(x: c.Expr[Any]): c.Expr[Option[Any]] = { - import c.universe._ - import Flag._ - - // parts here will be string literals - static parts of the string interpolation - // e.g. for q"$x, $y" parts will be Literal(Constant("")), Literal(Constant(", ")) and Literal(Constant("")) - val Apply(Select(Select(Apply(_, List(Apply(_, parts))), _), _), _) = c.macroApplication - val nresults = parts.length - 1 - - def results() = - ((1 to (nresults - 1)).toList map (i => Literal(Constant(i)))) :+ // (n - 1) results of type Int - Apply(Ident(TermName("List")), List(Literal(Constant(nresults)))) // and also one result of a different type - def extractorBody() = - if (nresults == 0) Literal(Constant(true)) - else if (nresults == 1) Apply(Ident(TermName("Some")), results()) - else Apply(Ident(TermName("Some")), List(Apply(Ident(TermName("Tuple" + nresults)), results()))) - - val name = TermName(java.util.UUID.randomUUID().toString.replace("-", "")) - val mdef = ModuleDef(NoMods, name, Template(List(Select(Ident(TermName("scala")), TypeName("AnyRef"))), emptyValDef, List( - DefDef(Modifiers(), nme.CONSTRUCTOR, List(), List(List()), TypeTree(), - Block(List(pendingSuperCall), Literal(Constant(())))), - DefDef(Modifiers(), TermName("unapply"), List(), List(List(ValDef(Modifiers(PARAM), TermName("x"), Ident(TypeName("Any")), EmptyTree))), TypeTree(), - extractorBody())))) - c.introduceTopLevel(nme.EMPTY_PACKAGE_NAME.toString, mdef) - c.Expr[Option[Any]](Apply(Select(Ident(name), TermName("unapply")), List(x.tree))) - } -}
\ No newline at end of file diff --git a/test/files/run/macro-expand-unapply-b/Test_2.scala b/test/files/run/macro-expand-unapply-b/Test_2.scala deleted file mode 100644 index 5352160dfe..0000000000 --- a/test/files/run/macro-expand-unapply-b/Test_2.scala +++ /dev/null @@ -1,8 +0,0 @@ -object Test extends App { - import Macros._ - def whatever() = null - val q"$x1, $y1" = whatever() - println(x1, y1) - val q"$x2" = whatever() - println(x2) -} diff --git a/test/files/run/macro-toplevel-companion-a.check b/test/files/run/macro-toplevel-companion-a.check deleted file mode 100644 index e69de29bb2..0000000000 --- a/test/files/run/macro-toplevel-companion-a.check +++ /dev/null diff --git a/test/files/run/macro-toplevel-companion-a.flags b/test/files/run/macro-toplevel-companion-a.flags deleted file mode 100644 index cd66464f2f..0000000000 --- a/test/files/run/macro-toplevel-companion-a.flags +++ /dev/null @@ -1 +0,0 @@ --language:experimental.macros
\ No newline at end of file diff --git a/test/files/run/macro-toplevel-companion-a/Impls_Macros_1.scala b/test/files/run/macro-toplevel-companion-a/Impls_Macros_1.scala deleted file mode 100644 index 23e8694ddc..0000000000 --- a/test/files/run/macro-toplevel-companion-a/Impls_Macros_1.scala +++ /dev/null @@ -1,14 +0,0 @@ -import scala.reflect.macros.Context -import language.experimental.macros - -object Macros { - def impl(c: Context) = { - import c.universe._ - val synthetic = reify{ class C { override def toString = "C" }; object C { implicit val c = new C } }.tree - val defs = synthetic.asInstanceOf[Block].stats.asInstanceOf[List[ImplDef]] - if (c.topLevelRef(TypeName("C")).isEmpty) c.introduceTopLevel(nme.EMPTY_PACKAGE_NAME.toString, defs: _*) - c.literalUnit - } - - def foo = macro impl -}
\ No newline at end of file diff --git a/test/files/run/macro-toplevel-companion-a/Test_2.scala b/test/files/run/macro-toplevel-companion-a/Test_2.scala deleted file mode 100644 index 78b65b5b1f..0000000000 --- a/test/files/run/macro-toplevel-companion-a/Test_2.scala +++ /dev/null @@ -1,8 +0,0 @@ -import Macros._ - -object Test extends App { - foo; - implicitly[C]; - foo; - implicitly[C]; -}
\ No newline at end of file diff --git a/test/files/run/macro-toplevel-companion-b.check b/test/files/run/macro-toplevel-companion-b.check deleted file mode 100644 index bd30dc75d3..0000000000 --- a/test/files/run/macro-toplevel-companion-b.check +++ /dev/null @@ -1,4 +0,0 @@ -reflective compilation has failed: - -Companions 'class C' and 'object C' must be defined in same file: - Found in <synthetic file name> and <synthetic file name> diff --git a/test/files/run/macro-toplevel-companion-b.flags b/test/files/run/macro-toplevel-companion-b.flags deleted file mode 100644 index cd66464f2f..0000000000 --- a/test/files/run/macro-toplevel-companion-b.flags +++ /dev/null @@ -1 +0,0 @@ --language:experimental.macros
\ No newline at end of file diff --git a/test/files/run/macro-toplevel-companion-b/Impls_Macros_1.scala b/test/files/run/macro-toplevel-companion-b/Impls_Macros_1.scala deleted file mode 100644 index f30adc2965..0000000000 --- a/test/files/run/macro-toplevel-companion-b/Impls_Macros_1.scala +++ /dev/null @@ -1,15 +0,0 @@ -import scala.reflect.macros.Context -import language.experimental.macros - -object Macros { - def impl(c: Context) = { - import c.universe._ - val Block(List(cdef: ClassDef), _) = reify{ class C }.tree - val classRef = c.topLevelRef(TypeName("C")) orElse c.introduceTopLevel(nme.EMPTY_PACKAGE_NAME.toString, cdef) - val Block(List(mdef: ModuleDef), _) = reify{ object C }.tree - val moduleRef = c.topLevelRef(TermName("C")) orElse c.introduceTopLevel(nme.EMPTY_PACKAGE_NAME.toString, mdef) - c.literalUnit - } - - def foo = macro impl -}
\ No newline at end of file diff --git a/test/files/run/macro-toplevel-companion-b/Test_2.scala b/test/files/run/macro-toplevel-companion-b/Test_2.scala deleted file mode 100644 index 4e766bde89..0000000000 --- a/test/files/run/macro-toplevel-companion-b/Test_2.scala +++ /dev/null @@ -1,11 +0,0 @@ -import scala.reflect.runtime.universe._ -import scala.reflect.runtime.{universe => ru} -import scala.reflect.runtime.{currentMirror => cm} -import scala.tools.reflect.{ToolBox, ToolBoxError} -import Macros._ - -object Test extends App { - val tb = cm.mkToolBox() - try tb.compile(Select(Ident(TermName("Macros")), TermName("foo"))) - catch { case ToolBoxError(message, _) => println("""(Found in|and) .*?compileLateSynthetic-.*?\.scala""".r.replaceAllIn(message, m => m.group(1) + " <synthetic file name>")) } -}
\ No newline at end of file diff --git a/test/files/run/macro-toplevel-companion-c.check b/test/files/run/macro-toplevel-companion-c.check deleted file mode 100644 index 4052c472f8..0000000000 --- a/test/files/run/macro-toplevel-companion-c.check +++ /dev/null @@ -1,3 +0,0 @@ -error: Companions 'class C' and 'object C' must be defined in same file: - Found in <synthetic file name> and newSource1.scala - diff --git a/test/files/run/macro-toplevel-companion-c.flags b/test/files/run/macro-toplevel-companion-c.flags deleted file mode 100644 index cd66464f2f..0000000000 --- a/test/files/run/macro-toplevel-companion-c.flags +++ /dev/null @@ -1 +0,0 @@ --language:experimental.macros
\ No newline at end of file diff --git a/test/files/run/macro-toplevel-companion-c.scala b/test/files/run/macro-toplevel-companion-c.scala deleted file mode 100644 index c315f8b942..0000000000 --- a/test/files/run/macro-toplevel-companion-c.scala +++ /dev/null @@ -1,51 +0,0 @@ -import scala.tools.partest._ -import java.io._ - -object Test extends DirectTest { - def code = ??? - - def macros_1 = """ - package test - - import scala.reflect.macros.Context - import language.experimental.macros - - object Macros { - def impl(c: Context) = { - import c.universe._ - val Block(List(cdef: ClassDef), _) = reify{ class C }.tree - val ref = c.topLevelRef(TypeName("test.C")) orElse c.introduceTopLevel("test", cdef) - c.literalUnit - } - - def foo = macro impl - } - """ - def compileMacros() = { - val classpath = List(sys.props("partest.lib"), sys.props("partest.reflect")) mkString sys.props("path.separator") - compileString(newCompiler("-language:experimental.macros", "-cp", classpath, "-d", testOutput.path))(macros_1) - } - - def test_2 = """ - package test - object C { Macros.foo } - """ - def compileTest() = { - val classpath = List(sys.props("partest.lib"), testOutput.path) mkString sys.props("path.separator") - compileString(newCompiler("-cp", classpath, "-d", testOutput.path))(test_2) - } - - def show(): Unit = { - // redirect err to string, for logging - val prevErr = System.err - val baos = new ByteArrayOutputStream() - System.setErr(new PrintStream(baos)) - log("Compiling Macros_1...") - if (compileMacros()) { - log("Compiling Test_2...") - if (compileTest()) log("Success!") else log("Failed...") - } - println("""(Found in|and) .*?compileLateSynthetic-.*?\.scala""".r.replaceAllIn(baos.toString, m => m.group(1) + " <synthetic file name>")) - System.setErr(prevErr) - } -}
\ No newline at end of file diff --git a/test/files/run/macro-toplevel.check b/test/files/run/macro-toplevel.check deleted file mode 100644 index 257c3764fd..0000000000 --- a/test/files/run/macro-toplevel.check +++ /dev/null @@ -1,2 +0,0 @@ -I've been created from Macros.foo -I've been created from Macros.foo diff --git a/test/files/run/macro-toplevel/Macros_1.scala b/test/files/run/macro-toplevel/Macros_1.scala deleted file mode 100644 index f681c86735..0000000000 --- a/test/files/run/macro-toplevel/Macros_1.scala +++ /dev/null @@ -1,15 +0,0 @@ -import scala.reflect.macros.Context -import language.experimental.macros - -object Macros { - def impl(c: Context) = { - import c.universe._ - val msg = "I've been created from " + c.macroApplication - val Block(List(synthetic: ClassDef), _) = reify{ class SomeUniqueName { def hello = c.literal(msg).splice } }.tree - val ref = c.topLevelRef(synthetic.name) orElse c.introduceTopLevel(nme.EMPTY_PACKAGE_NAME.toString, synthetic) - c.Expr[String](Select(Apply(Select(New(ref), nme.CONSTRUCTOR), List()), TermName("hello"))) - } - - def foo = macro impl - def foo2 = macro impl -} diff --git a/test/files/run/macro-toplevel/Test_2.scala b/test/files/run/macro-toplevel/Test_2.scala deleted file mode 100644 index eee2d6ae13..0000000000 --- a/test/files/run/macro-toplevel/Test_2.scala +++ /dev/null @@ -1,6 +0,0 @@ -import Macros._ - -object Test extends App { - println(Macros.foo) - println(Macros.foo2) -}
\ No newline at end of file |