From 12a21c9f154f4f3de70e485f99320331bbc1a3a8 Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Fri, 17 May 2013 11:43:30 +0200 Subject: new starr that supports macro ??? --- lib/scala-compiler-src.jar.desired.sha1 | 2 +- lib/scala-compiler.jar.desired.sha1 | 2 +- lib/scala-library-src.jar.desired.sha1 | 2 +- lib/scala-library.jar.desired.sha1 | 2 +- lib/scala-reflect-src.jar.desired.sha1 | 2 +- lib/scala-reflect.jar.desired.sha1 | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/scala-compiler-src.jar.desired.sha1 b/lib/scala-compiler-src.jar.desired.sha1 index 7dae1a905e..debbce2d7e 100644 --- a/lib/scala-compiler-src.jar.desired.sha1 +++ b/lib/scala-compiler-src.jar.desired.sha1 @@ -1 +1 @@ -f9f41fb909df6a0178906c9fd02e5d0efa15c9ed ?scala-compiler-src.jar +19d04510ac6f25d088da82527d8435b68c00153d ?scala-compiler-src.jar diff --git a/lib/scala-compiler.jar.desired.sha1 b/lib/scala-compiler.jar.desired.sha1 index bb22879679..4ec9610bae 100644 --- a/lib/scala-compiler.jar.desired.sha1 +++ b/lib/scala-compiler.jar.desired.sha1 @@ -1 +1 @@ -c4cd524dc29d298a5034637f6b31122dccb300d6 ?scala-compiler.jar +3585351c6a62186097be55fff88bee88a985f5c0 ?scala-compiler.jar diff --git a/lib/scala-library-src.jar.desired.sha1 b/lib/scala-library-src.jar.desired.sha1 index 641324256e..6e97551fc7 100644 --- a/lib/scala-library-src.jar.desired.sha1 +++ b/lib/scala-library-src.jar.desired.sha1 @@ -1 +1 @@ -2cba5a13ef44bf93133be26cc89ba3a640a5c28f ?scala-library-src.jar +e606934dc00ced6bfac715bbdba427f9c2c18bc7 ?scala-library-src.jar diff --git a/lib/scala-library.jar.desired.sha1 b/lib/scala-library.jar.desired.sha1 index 1b4eeac625..36aedb2ad7 100644 --- a/lib/scala-library.jar.desired.sha1 +++ b/lib/scala-library.jar.desired.sha1 @@ -1 +1 @@ -d7c6e69eba3dba2f75a0f44e56480cd3dbab8931 ?scala-library.jar +36456c52b0395fc1e6e367291e45bd503fa019c5 ?scala-library.jar diff --git a/lib/scala-reflect-src.jar.desired.sha1 b/lib/scala-reflect-src.jar.desired.sha1 index f9d9618380..ebd6dcbf5a 100644 --- a/lib/scala-reflect-src.jar.desired.sha1 +++ b/lib/scala-reflect-src.jar.desired.sha1 @@ -1 +1 @@ -dbc00bd4b09012aa52e802926dee3f8a02a767ff ?scala-reflect-src.jar +51787a41cae5b0ec6910c5a1a6af392e17550856 ?scala-reflect-src.jar diff --git a/lib/scala-reflect.jar.desired.sha1 b/lib/scala-reflect.jar.desired.sha1 index 8663ef7c85..4378fec9d6 100644 --- a/lib/scala-reflect.jar.desired.sha1 +++ b/lib/scala-reflect.jar.desired.sha1 @@ -1 +1 @@ -c0eed5dee0a3204239c9b35134cad8b3ad140121 ?scala-reflect.jar +d4a4c0aab882412461fbd9d39cf47da5a619855e ?scala-reflect.jar -- cgit v1.2.3 From 81e7389ed813c815b7a6bcdddb36b622bf458cca Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Sun, 5 May 2013 16:44:43 +0200 Subject: less magic in fast track macros Now that we have a mechanism to declare not implemented macros, let's put it to good use by reducing the amount of magic applied to fast track. --- src/library/scala/StringContext.scala | 2 +- src/library/scala/reflect/package.scala | 2 +- src/reflect/scala/reflect/api/Universe.scala | 2 +- src/reflect/scala/reflect/api/package.scala | 4 ++-- src/reflect/scala/reflect/runtime/package.scala | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/library/scala/StringContext.scala b/src/library/scala/StringContext.scala index 1b5fd6c8d3..42fb2f36e8 100644 --- a/src/library/scala/StringContext.scala +++ b/src/library/scala/StringContext.scala @@ -162,7 +162,7 @@ case class StringContext(parts: String*) { */ // The implementation is hardwired to `scala.tools.reflect.MacroImplementations.macro_StringInterpolation_f` // Using the mechanism implemented in `scala.tools.reflect.FastTrack` - def f(args: Any*): String = ??? // macro + def f(args: Any*): String = macro ??? } object StringContext { diff --git a/src/library/scala/reflect/package.scala b/src/library/scala/reflect/package.scala index 97d7da3f2d..74c1f2172c 100644 --- a/src/library/scala/reflect/package.scala +++ b/src/library/scala/reflect/package.scala @@ -60,7 +60,7 @@ package object reflect { // implementation is hardwired into `scala.reflect.reify.Taggers` // using the mechanism implemented in `scala.tools.reflect.FastTrack` // todo. once we have implicit macros for tag generation, we can remove this anchor - private[scala] def materializeClassTag[T](): ClassTag[T] = ??? // macro + private[scala] def materializeClassTag[T](): ClassTag[T] = macro ??? @deprecated("Use `@scala.beans.BeanDescription` instead", "2.10.0") type BeanDescription = scala.beans.BeanDescription diff --git a/src/reflect/scala/reflect/api/Universe.scala b/src/reflect/scala/reflect/api/Universe.scala index 799fbd0dfb..cb629f9c5a 100644 --- a/src/reflect/scala/reflect/api/Universe.scala +++ b/src/reflect/scala/reflect/api/Universe.scala @@ -94,5 +94,5 @@ abstract class Universe extends Symbols */ // implementation is hardwired to `scala.reflect.reify.Taggers` // using the mechanism implemented in `scala.tools.reflect.FastTrack` - def reify[T](expr: T): Expr[T] = ??? // macro + def reify[T](expr: T): Expr[T] = macro ??? } diff --git a/src/reflect/scala/reflect/api/package.scala b/src/reflect/scala/reflect/api/package.scala index 14dcc9247f..a8f409e123 100644 --- a/src/reflect/scala/reflect/api/package.scala +++ b/src/reflect/scala/reflect/api/package.scala @@ -43,6 +43,6 @@ package object api { // implementation is hardwired into `scala.reflect.reify.Taggers` // using the mechanism implemented in `scala.tools.reflect.FastTrack` // todo. once we have implicit macros for tag generation, we can remove these anchors - private[scala] def materializeWeakTypeTag[T](u: ApiUniverse): u.WeakTypeTag[T] = ??? // macro - private[scala] def materializeTypeTag[T](u: ApiUniverse): u.TypeTag[T] = ??? // macro + private[scala] def materializeWeakTypeTag[T](u: ApiUniverse): u.WeakTypeTag[T] = macro ??? + private[scala] def materializeTypeTag[T](u: ApiUniverse): u.TypeTag[T] = macro ??? } \ No newline at end of file diff --git a/src/reflect/scala/reflect/runtime/package.scala b/src/reflect/scala/reflect/runtime/package.scala index 0354b424d2..41c1310e17 100644 --- a/src/reflect/scala/reflect/runtime/package.scala +++ b/src/reflect/scala/reflect/runtime/package.scala @@ -21,7 +21,7 @@ package object runtime { */ // implementation hardwired to the `currentMirror` method below // using the mechanism implemented in `scala.tools.reflect.FastTrack` - def currentMirror: universe.Mirror = ??? // macro + def currentMirror: universe.Mirror = macro ??? } package runtime { -- cgit v1.2.3 From 43249001a566c46d6bb3b515045ab477b42a0c77 Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Thu, 9 May 2013 12:55:15 +0200 Subject: SI-7461 c.typeCheck(silent = true) now suppresses ambiguous errors Otherwise use cases like the one shown in the attached test (trying to typecheck something, which leads to an ambiguous overload error) will mysteriously fail compilation. --- src/compiler/scala/reflect/macros/runtime/Typers.scala | 2 +- src/compiler/scala/tools/reflect/ToolBoxFactory.scala | 2 +- test/files/pos/t7461.check | 0 test/files/pos/t7461/Macros_1.scala | 13 +++++++++++++ test/files/pos/t7461/Test_2.scala | 3 +++ 5 files changed, 18 insertions(+), 2 deletions(-) create mode 100644 test/files/pos/t7461.check create mode 100644 test/files/pos/t7461/Macros_1.scala create mode 100644 test/files/pos/t7461/Test_2.scala diff --git a/src/compiler/scala/reflect/macros/runtime/Typers.scala b/src/compiler/scala/reflect/macros/runtime/Typers.scala index f60b8dfeb4..f92d99a3f2 100644 --- a/src/compiler/scala/reflect/macros/runtime/Typers.scala +++ b/src/compiler/scala/reflect/macros/runtime/Typers.scala @@ -24,7 +24,7 @@ trait Typers { // typechecking uses silent anyways (e.g. in typedSelect), so you'll only waste your time // I'd advise fixing the root cause: finding why the context is not set to report errors // (also see reflect.runtime.ToolBoxes.typeCheckExpr for a workaround that might work for you) - wrapper(callsiteTyper.silent(_.typed(tree, pt)) match { + wrapper(callsiteTyper.silent(_.typed(tree, pt), reportAmbiguousErrors = false) match { case universe.analyzer.SilentResultValue(result) => macroLogVerbose(result) result diff --git a/src/compiler/scala/tools/reflect/ToolBoxFactory.scala b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala index 6145e61c4f..c53d10bd87 100644 --- a/src/compiler/scala/tools/reflect/ToolBoxFactory.scala +++ b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala @@ -165,7 +165,7 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf => transformDuringTyper(expr, withImplicitViewsDisabled = withImplicitViewsDisabled, withMacrosDisabled = withMacrosDisabled)( (currentTyper, expr) => { trace("typing (implicit views = %s, macros = %s): ".format(!withImplicitViewsDisabled, !withMacrosDisabled))(showAttributed(expr, true, true, settings.Yshowsymkinds.value)) - currentTyper.silent(_.typed(expr, pt)) match { + currentTyper.silent(_.typed(expr, pt), reportAmbiguousErrors = false) match { case analyzer.SilentResultValue(result) => trace("success: ")(showAttributed(result, true, true, settings.Yshowsymkinds.value)) result diff --git a/test/files/pos/t7461.check b/test/files/pos/t7461.check new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/files/pos/t7461/Macros_1.scala b/test/files/pos/t7461/Macros_1.scala new file mode 100644 index 0000000000..353dec66d7 --- /dev/null +++ b/test/files/pos/t7461/Macros_1.scala @@ -0,0 +1,13 @@ +import scala.reflect.macros.Context +import language.experimental.macros + +object Macros { + def impl(c: Context) = { + import c.universe._ + val wut = c.typeCheck(Select(Literal(Constant(10)), newTermName("$minus")), silent = true) + // println(showRaw(wut, printIds = true, printTypes = true)) + c.literalUnit + } + + def foo = macro impl +} \ No newline at end of file diff --git a/test/files/pos/t7461/Test_2.scala b/test/files/pos/t7461/Test_2.scala new file mode 100644 index 0000000000..3839659c9a --- /dev/null +++ b/test/files/pos/t7461/Test_2.scala @@ -0,0 +1,3 @@ +class C { + def foo = Macros.foo +} \ No newline at end of file -- cgit v1.2.3 From e1d9805c91dbe74317e2f4f22ad59056d64d12b3 Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Mon, 14 Jan 2013 17:29:42 +0100 Subject: macro engine refactoring Macro impl bindings now store more information in signatures. Previously it was a flattened List[Int] corresponding to flattened paramss, now it's List[List[Int]] to preserve the lengths of parameter lists. Also now we distinguish between c.Expr parameters and others. Previously actual and reference macro signatures were represented as tuples of vparamss, rets, and sometimes tparams. Now they are all abstracted behind MacroImplSig. Finally this patch provides better error messages in cases of argsc <-> paramsc and argc <-> paramc mismatches. --- .../tools/nsc/typechecker/ContextErrors.scala | 38 ++- .../scala/tools/nsc/typechecker/Macros.scala | 366 +++++++++++++-------- .../scala/tools/nsc/typechecker/RefChecks.scala | 2 +- .../scala/tools/nsc/typechecker/Typers.scala | 2 +- .../scala/reflect/internal/Definitions.scala | 10 + test/files/neg/macro-qmarkqmarkqmark.check | 2 +- test/files/neg/t7157.check | 73 ++++ test/files/neg/t7157/Impls_Macros_1.scala | 32 ++ test/files/neg/t7157/Test_2.scala | 63 ++++ ...alidusage-partialapplication-with-tparams.check | 2 +- .../macro-invalidusage-partialapplication.check | 2 +- test/files/run/reify-repl-fail-gracefully.check | 2 +- test/files/run/t7157.check | 1 + test/files/run/t7157/Impls_Macros_1.scala | 15 + test/files/run/t7157/Test_2.scala | 5 + 15 files changed, 455 insertions(+), 160 deletions(-) create mode 100644 test/files/neg/t7157.check create mode 100644 test/files/neg/t7157/Impls_Macros_1.scala create mode 100644 test/files/neg/t7157/Test_2.scala create mode 100644 test/files/run/t7157.check create mode 100644 test/files/run/t7157/Impls_Macros_1.scala create mode 100644 test/files/run/t7157/Test_2.scala diff --git a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala index 135a79124d..054f96c7b7 100644 --- a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala +++ b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala @@ -476,7 +476,7 @@ trait ContextErrors { // doTypeApply //tryNamesDefaults def NamedAndDefaultArgumentsNotSupportedForMacros(tree: Tree, fun: Tree) = - NormalTypeError(tree, "macros application do not support named and/or default arguments") + NormalTypeError(tree, "macro applications do not support named and/or default arguments") def TooManyArgsNamesDefaultsError(tree: Tree, fun: Tree) = NormalTypeError(tree, "too many arguments for "+treeSymTypeMsg(fun)) @@ -571,7 +571,7 @@ trait ContextErrors { //adapt def MissingArgsForMethodTpeError(tree: Tree, meth: Symbol) = { val message = - if (meth.isMacro) MacroPartialApplicationErrorMessage + if (meth.isMacro) MacroTooFewArgumentListsMessage else "missing arguments for " + meth.fullLocationString + ( if (meth.isConstructor) "" else ";\nfollow this method with `_' if you want to treat it as a partially applied function" @@ -703,15 +703,24 @@ trait ContextErrors { throw MacroExpansionException } - def MacroPartialApplicationErrorMessage = "macros cannot be partially applied" - def MacroPartialApplicationError(expandee: Tree) = { + private def macroExpansionError2(expandee: Tree, msg: String) = { // macroExpansionError won't work => swallows positions, hence needed to do issueTypeError // kinda contradictory to the comment in `macroExpansionError`, but this is how it works - issueNormalTypeError(expandee, MacroPartialApplicationErrorMessage) + issueNormalTypeError(expandee, msg) setError(expandee) throw MacroExpansionException } + private def MacroTooFewArgumentListsMessage = "too few argument lists for macro invocation" + def MacroTooFewArgumentLists(expandee: Tree) = macroExpansionError2(expandee, MacroTooFewArgumentListsMessage) + + private def MacroTooManyArgumentListsMessage = "too many argument lists for macro invocation" + def MacroTooManyArgumentLists(expandee: Tree) = macroExpansionError2(expandee, MacroTooManyArgumentListsMessage) + + def MacroTooFewArguments(expandee: Tree) = macroExpansionError2(expandee, "too few arguments for macro invocation") + + def MacroTooManyArguments(expandee: Tree) = macroExpansionError2(expandee, "too many arguments for macro invocation") + def MacroGeneratedAbort(expandee: Tree, ex: AbortMacroException) = { // errors have been reported by the macro itself, so we do nothing here macroLogVerbose("macro expansion has been aborted") @@ -1257,10 +1266,17 @@ trait ContextErrors { // not exactly an error generator, but very related // and I dearly wanted to push it away from Macros.scala - private def checkSubType(slot: String, rtpe: Type, atpe: Type) = { - val ok = if (macroDebugVerbose) { - withTypesExplained(rtpe <:< atpe) - } else rtpe <:< atpe + private def checkConforms(slot: String, rtpe: Type, atpe: Type) = { + val verbose = macroDebugVerbose || settings.explaintypes.value + + def check(rtpe: Type, atpe: Type): Boolean = { + if (rtpe eq atpe) { if (verbose) println(rtpe + " <: " + atpe + "?" + EOL + "true"); true } + else rtpe <:< atpe + } + + val ok = + if (verbose) withTypesExplained(check(rtpe, atpe)) + else check(rtpe, atpe) if (!ok) { if (!macroDebugVerbose) explainTypes(rtpe, atpe) @@ -1341,9 +1357,9 @@ trait ContextErrors { def MacroImplMissingParamsError(aparams: List[Symbol], rparams: List[Symbol]) = compatibilityError(abbreviateCoreAliases(lengthMsg("value", "required", rparams(aparams.length)))) - def checkMacroImplParamTypeMismatch(atpe: Type, rparam: Symbol) = checkSubType("parameter " + rparam.name, rparam.tpe, atpe) + def checkMacroImplParamTypeMismatch(atpe: Type, rparam: Symbol) = checkConforms("parameter " + rparam.name, rparam.tpe, atpe) - def checkMacroImplResultTypeMismatch(atpe: Type, rret: Type) = checkSubType("return type", atpe, rret) + def checkMacroImplResultTypeMismatch(atpe: Type, rret: Type) = checkConforms("return type", atpe, rret) def MacroImplParamNameMismatchError(aparam: Symbol, rparam: Symbol) = compatibilityError("parameter names differ: " + rparam.name + " != " + aparam.name) diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala index 5ac37251ee..93f73f1bbe 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala @@ -1,6 +1,7 @@ package scala.tools.nsc package typechecker +import java.lang.Math.min import symtab.Flags._ import scala.tools.nsc.util._ import scala.reflect.runtime.ReflectionUtils @@ -82,15 +83,22 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces { // `className` and `methName` are all we need to reflectively invoke a macro implementation // because macro implementations cannot be overloaded methName: String, - // flattens the macro impl's parameter lists having symbols replaced with metadata - // currently metadata is an index of the type parameter corresponding to that type tag (if applicable) - // f.ex. for: def impl[T: WeakTypeTag, U: WeakTypeTag, V](c: Context)(x: c.Expr[T]): (U, V) = ??? - // `signature` will be equal to List(-1, -1, 0, 1) - signature: List[Int], + // flattens the macro impl's parameter lists having symbols replaced with their fingerprints + // currently fingerprints are calculated solely from types of the symbols: + // * c.Expr[T] => IMPLPARAM_EXPR + // * c.WeakTypeTag[T] => index of the type parameter corresponding to that type tag + // * everything else (e.g. scala.reflect.macros.Context) => IMPLPARAM_OTHER + // f.ex. for: def impl[T: WeakTypeTag, U, V: WeakTypeTag](c: Context)(x: c.Expr[T], y: c.Tree): (U, V) = ??? + // `signature` will be equal to List(List(-1), List(-1, -2), List(0, 2)) + signature: List[List[Int]], // type arguments part of a macro impl ref (the right-hand side of a macro definition) // these trees don't refer to a macro impl, so we can pickle them as is targs: List[Tree]) + private final val IMPLPARAM_TAG = 0 // actually it's zero and above, this is just a lower bound for >= checks + private final val IMPLPARAM_OTHER = -1 + private final val IMPLPARAM_EXPR = -2 + /** Macro def -> macro impl bindings are serialized into a `macroImpl` annotation * with synthetic content that carries the payload described in `MacroImplBinding`. * @@ -104,11 +112,11 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces { * `macro`( * "signature" = List(-1), * "methodName" = "impl", - * "versionFormat" = 1, + * "versionFormat" = , * "className" = "Macros$")) */ private object MacroImplBinding { - val versionFormat = 1 + val versionFormat = 2 def pickleAtom(obj: Any): Tree = obj match { @@ -142,9 +150,15 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces { loop(owner) } - def signature: List[Int] = { + def signature: List[List[Int]] = { + def fingerprint(tpe: Type): Int = tpe.dealiasWiden match { + case TypeRef(_, RepeatedParamClass, underlying :: Nil) => fingerprint(underlying) + case ExprClassOf(_) => IMPLPARAM_EXPR + case _ => IMPLPARAM_OTHER + } + val transformed = transformTypeTagEvidenceParams(paramss, (param, tparam) => tparam) - transformed.flatten map (p => if (p.isTerm) -1 else p.paramPos) + mmap(transformed)(p => if (p.isTerm) fingerprint(p.info) else p.paramPos) } val payload = List[(String, Any)]( @@ -193,7 +207,7 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces { val className = payload("className").asInstanceOf[String] val methodName = payload("methodName").asInstanceOf[String] - val signature = payload("signature").asInstanceOf[List[Int]] + val signature = payload("signature").asInstanceOf[List[List[Int]]] MacroImplBinding(className, methodName, signature, targs) } } @@ -235,19 +249,40 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces { if (transformed.isEmpty) paramss.init else paramss.init :+ transformed } - def computeMacroDefTypeFromMacroImpl(macroDdef: DefDef, macroImpl: Symbol): Type = { - // Step I. Transform c.Expr[T] to T - var runtimeType = macroImpl.tpe.finalResultType.dealias match { - case TypeRef(_, ExprClass, runtimeType :: Nil) => runtimeType - case _ => AnyTpe // so that macro impls with rhs = ??? don't screw up our inference - } + private def dealiasAndRewrap(tp: Type)(fn: Type => Type): Type = { + if (isRepeatedParamType(tp)) scalaRepeatedType(fn(tp.typeArgs.head.dealias)) + else fn(tp.dealias) + } + + /** Increases metalevel of the type, i.e. transforms: + * * T to c.Expr[T] + * + * @see Metalevels.scala for more information and examples about metalevels + */ + private def increaseMetalevel(c: Symbol, tp: Type): Type = dealiasAndRewrap(tp) { + case tp => typeRef(SingleType(NoPrefix, c), MacroContextExprClass, List(tp)) + } + + /** Decreases metalevel of the type, i.e. transforms: + * * c.Expr[T] to T + * + * @see Metalevels.scala for more information and examples about metalevels + */ + private def decreaseMetalevel(tp: Type): Type = dealiasAndRewrap(tp) { + case ExprClassOf(runtimeType) => runtimeType + case _ => AnyClass.tpe // so that macro impls with rhs = ??? don't screw up our inference + } + + def computeMacroDefTypeFromMacroImpl(macroDdef: DefDef, macroImplSig: MacroImplSig): Type = { + // Step I. Transform c.Expr[T] to T and c.Tree to + var runtimeType = decreaseMetalevel(macroImplSig.ret) // Step II. Transform type parameters of a macro implementation into type arguments in a macro definition's body - runtimeType = runtimeType.substituteTypes(macroImpl.typeParams, loadMacroImplBinding(macroDdef.symbol).targs.map(_.tpe)) + runtimeType = runtimeType.substituteTypes(macroImplSig.tparams, loadMacroImplBinding(macroDdef.symbol).targs.map(_.tpe)) // Step III. Transform c.prefix.value.XXX to this.XXX and implParam.value.YYY to defParam.YYY def unsigma(tpe: Type): Type = - transformTypeTagEvidenceParams(macroImpl.paramss, (param, tparam) => NoSymbol) match { + transformTypeTagEvidenceParams(macroImplSig.paramss, (param, tparam) => NoSymbol) match { case (implCtxParam :: Nil) :: implParamss => val implToDef = flatMap2(implParamss, macroDdef.vparamss)(map2(_, _)((_, _))).toMap object UnsigmaTypeMap extends TypeMap { @@ -276,39 +311,83 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces { unsigma(runtimeType) } - /** A reference macro implementation signature compatible with a given macro definition. + /** Signature of a macro implementation, used to check def <-> impl correspondence. + * + * Technically it can be just an alias to MethodType, but promoting it to a first-class entity + * provides better encapsulation and convenient syntax for pattern matching. + */ + case class MacroImplSig(tparams: List[Symbol], paramss: List[List[Symbol]], ret: Type) + + /** An actual macro implementation signature extracted from a macro implementation method. + * + * In the example above for the following macro impl: + * def fooBar[T: c.WeakTypeTag] + * (c: scala.reflect.macros.Context) + * (xs: c.Expr[List[T]]) + * : c.Expr[T] = ... + * + * This function will return: + * (c: scala.reflect.macros.Context)(xs: c.Expr[List[T]])c.Expr[T] + * + * Note that type tag evidence parameters are not included into the result. + * Type tag context bounds for macro impl tparams are optional. + * Therefore compatibility checks ignore such parameters, and we don't need to bother about them here. + * + * This method cannot be reduced to just macroImpl.info, because macro implementations might + * come in different shapes. If the implementation is an apply method of a Macro-compatible object, + * then it won't have (c: Context) in its parameters, but will rather refer to Macro.c. + * + * @param macroImpl The macro implementation symbol + */ + def macroImplSig(macroImpl: Symbol): MacroImplSig = { + val tparams = macroImpl.typeParams + val paramss = transformTypeTagEvidenceParams(macroImpl.paramss, (param, tparam) => NoSymbol) + val ret = macroImpl.info.finalResultType + MacroImplSig(tparams, paramss, ret) + } + + /** A reference macro implementation signature extracted from a given macro definition. * * In the example above for the following macro def: * def foo[T](xs: List[T]): T = macro fooBar * * This function will return: - * (c: scala.reflect.macros.Context)(xs: c.Expr[List[T]]): c.Expr[T] + * (c: scala.reflect.macros.Context)(xs: c.Expr[List[T]])c.Expr[T] * * Note that type tag evidence parameters are not included into the result. * Type tag context bounds for macro impl tparams are optional. * Therefore compatibility checks ignore such parameters, and we don't need to bother about them here. * - * @param macroDef The macro definition symbol - * @param tparams The type parameters of the macro definition - * @param vparamss The value parameters of the macro definition - * @param retTpe The return type of the macro definition + * Also note that we need a DefDef, not the corresponding MethodSymbol, because that symbol would be of no use for us. + * Macro signatures are verified when typechecking macro defs, which means that at that moment inspecting macroDef.info + * means asking for cyclic reference errors. + * + * We need macro implementation symbol as well, because the return type of the macro definition might be omitted, + * and in that case we'd need to infer it from the return type of the macro implementation. Luckily for us, we can + * use that symbol without a risk of running into cycles. + * + * @param typer Typechecker of `macroDdef` + * @param macroDdef The macro definition tree + * @param macroImpl The macro implementation symbol */ - private def macroImplSig(macroDef: Symbol, tparams: List[TypeDef], vparamss: List[List[ValDef]], retTpe: Type): (List[List[Symbol]], Type) = { + def referenceMacroImplSig(typer: Typer, macroDdef: DefDef, macroImpl: Symbol): MacroImplSig = { // had to move method's body to an object because of the recursive dependencies between sigma and param object SigGenerator { - def WeakTagClass = getMember(MacroContextClass, tpnme.WeakTypeTag) - def ExprClass = getMember(MacroContextClass, tpnme.Expr) - val cache = scala.collection.mutable.Map[Symbol, Symbol]() - val ctxParam = makeParam(nme.macroContext, macroDef.pos, MacroContextClass.tpe, SYNTHETIC) - val paramss = List(ctxParam) :: mmap(vparamss)(param) - val implReturnType = typeRef(singleType(NoPrefix, ctxParam), ExprClass, List(sigma(retTpe))) + val cache = scala.collection.mutable.Map[Symbol, Symbol]() + val macroDef = macroDdef.symbol + val ctxParam = makeParam(nme.macroContext, macroDdef.pos, MacroContextClass.tpe, SYNTHETIC) + val paramss = List(ctxParam) :: mmap(macroDdef.vparamss)(param) + val macroDefRet = + if (!macroDdef.tpt.isEmpty) typer.typedType(macroDdef.tpt).tpe + else computeMacroDefTypeFromMacroImpl(macroDdef, macroImplSig(macroImpl)) + val implReturnType = sigma(increaseMetalevel(ctxParam, macroDefRet)) object SigmaTypeMap extends TypeMap { def mapPrefix(pre: Type) = pre match { case ThisType(sym) if sym == macroDef.owner => singleType(singleType(singleType(NoPrefix, ctxParam), MacroContextPrefix), ExprValue) case SingleType(NoPrefix, sym) => - mfind(vparamss)(_.symbol == sym).fold(pre)(p => singleType(singleType(NoPrefix, param(p)), ExprValue)) + mfind(macroDdef.vparamss)(_.symbol == sym).fold(pre)(p => singleType(singleType(NoPrefix, param(p)), ExprValue)) case _ => mapOver(pre) } @@ -326,32 +405,22 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces { def makeParam(name: Name, pos: Position, tpe: Type, flags: Long) = macroDef.newValueParameter(name.toTermName, pos, flags) setInfo tpe - def implType(isType: Boolean, origTpe: Type): Type = { - def tsym = if (isType) WeakTagClass else ExprClass - def targ = origTpe.typeArgs.headOption getOrElse NoType - - if (isRepeatedParamType(origTpe)) - scalaRepeatedType(implType(isType, sigma(targ))) - else - typeRef(singleType(NoPrefix, ctxParam), tsym, List(sigma(origTpe))) - } def param(tree: Tree): Symbol = ( cache.getOrElseUpdate(tree.symbol, { val sym = tree.symbol - makeParam(sym.name, sym.pos, implType(sym.isType, sym.tpe), sym.flags) + assert(sym.isTerm, s"sym = $sym, tree = $tree") + makeParam(sym.name, sym.pos, sigma(increaseMetalevel(ctxParam, sym.tpe)), sym.flags) }) ) } import SigGenerator._ + val result = MacroImplSig(macroDdef.tparams map (_.symbol), paramss, implReturnType) macroLogVerbose(sm""" - |generating macroImplSigs for: $macroDef - |tparams are: $tparams - |vparamss are: $vparamss - |retTpe is: $retTpe - |macroImplSig is: $paramss, $implReturnType + |generating macroImplSig for: $macroDdef + |result is: $result """.trim) - (paramss, implReturnType) + result } /** Verifies that the body of a macro def typechecks to a reference to a static public non-overloaded method, @@ -435,31 +504,26 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces { // Phase III: check compatibility between the macro def and its macro impl // this check ignores type tag evidence parameters, because type tag context bounds are optional - // aXXX (e.g. aparamss) => characteristics of the macro impl ("a" stands for "actual") - // rXXX (e.g. rparamss) => characteristics of a reference macro impl signature synthesized from the macro def ("r" stands for "reference") + // aXXX (e.g. aparamss) => characteristics of the actual macro impl signature extracted from the macro impl ("a" stands for "actual") + // rXXX (e.g. rparamss) => characteristics of the reference macro impl signature synthesized from the macro def ("r" stands for "reference") val macroImpl = typed.symbol - val aparamss = transformTypeTagEvidenceParams(macroImpl.paramss, (param, tparam) => NoSymbol) - val aret = macroImpl.tpe.finalResultType - val macroDefRet = - if (!macroDdef.tpt.isEmpty) typer.typedType(macroDdef.tpt).tpe - else computeMacroDefTypeFromMacroImpl(macroDdef, macroImpl) - val (rparamss, rret) = macroImplSig(macroDef, macroDdef.tparams, macroDdef.vparamss, macroDefRet) + val MacroImplSig(atparams, aparamss, aret) = macroImplSig(macroImpl) + val MacroImplSig(_, rparamss, rret) = referenceMacroImplSig(typer, macroDdef, macroImpl) + val atvars = atparams map freshVar + def atpeToRtpe(atpe: Type) = atpe.substSym(aparamss.flatten, rparamss.flatten).instantiateTypeParams(atparams, atvars) + // we only check correspondence between value parameterss + // type parameters of macro defs and macro impls don't have to coincide with each other val implicitParams = aparamss.flatten filter (_.isImplicit) if (implicitParams.nonEmpty) MacroImplNonTagImplicitParameters(implicitParams) if (aparamss.length != rparamss.length) MacroImplParamssMismatchError() - - val atparams = macroImpl.typeParams - val atvars = atparams map freshVar - def atpeToRtpe(atpe: Type) = atpe.substSym(aparamss.flatten, rparamss.flatten).instantiateTypeParams(atparams, atvars) + map2(aparamss, rparamss)((aparams, rparams) => { + if (aparams.length < rparams.length) MacroImplMissingParamsError(aparams, rparams) + if (rparams.length < aparams.length) MacroImplExtraParamsError(aparams, rparams) + }) try { - map2(aparamss, rparamss)((aparams, rparams) => { - if (aparams.length < rparams.length) MacroImplMissingParamsError(aparams, rparams) - if (rparams.length < aparams.length) MacroImplExtraParamsError(aparams, rparams) - }) - - // cannot fuse these loops because if aparamss.flatten != rparamss.flatten + // cannot fuse this map2 and the map2 above because if aparamss.flatten != rparamss.flatten // then `atpeToRtpe` is going to fail with an unsound substitution map2(aparamss.flatten, rparamss.flatten)((aparam, rparam) => { if (aparam.name != rparam.name && !rparam.isSynthetic) MacroImplParamNameMismatchError(aparam, rparam) @@ -560,92 +624,108 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces { case class MacroArgs(c: MacroContext, others: List[Any]) private def macroArgs(typer: Typer, expandee: Tree): MacroArgs = { - val macroDef = expandee.symbol - val prefixTree = expandee.collect{ case Select(qual, name) => qual }.headOption.getOrElse(EmptyTree) - val context = expandee.attachments.get[MacroRuntimeAttachment].flatMap(_.macroContext).getOrElse(macroContext(typer, prefixTree, expandee)) - var typeArgs = List[Tree]() - val exprArgs = ListBuffer[List[Expr[_]]]() - 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 (arg => context.Expr[Nothing](arg)(TypeTag.Nothing))) - collectMacroArgs(fn) - case TypeApply(fn, args) => - typeArgs = args - collectMacroArgs(fn) - case _ => - } - collectMacroArgs(expandee) + val macroDef = expandee.symbol + val paramss = macroDef.paramss + val treeInfo.Applied(core, targs, argss) = expandee + val prefix = core match { case Select(qual, _) => qual; case _ => EmptyTree } + val context = expandee.attachments.get[MacroRuntimeAttachment].flatMap(_.macroContext).getOrElse(macroContext(typer, prefix, expandee)) - val argcDoesntMatch = macroDef.paramss.length != exprArgs.length - val nullaryArgsEmptyParams = exprArgs.isEmpty && macroDef.paramss == ListOfNil - if (argcDoesntMatch && !nullaryArgsEmptyParams) { typer.TyperErrorGen.MacroPartialApplicationError(expandee) } + macroLogVerbose(sm""" + |context: $context + |prefix: $prefix + |targs: $targs + |argss: $argss + |paramss: $paramss + """.trim) - val argss: List[List[Any]] = exprArgs.toList - macroLogVerbose(s"context: $context") - macroLogVerbose(s"argss: $argss") + import typer.TyperErrorGen._ + val isNullaryArgsEmptyParams = argss.isEmpty && paramss == ListOfNil + if (paramss.length < argss.length) MacroTooManyArgumentLists(expandee) + if (paramss.length > argss.length && !isNullaryArgsEmptyParams) MacroTooFewArgumentLists(expandee) - val preparedArgss: List[List[Any]] = + val macroImplArgs: List[Any] = if (fastTrack contains macroDef) { // Take a dry run of the fast track implementation - if (fastTrack(macroDef) validate expandee) argss - else typer.TyperErrorGen.MacroPartialApplicationError(expandee) + if (fastTrack(macroDef) validate expandee) argss.flatten + else typer.TyperErrorGen.MacroTooFewArgumentLists(expandee) } else { - // if paramss have typetag context bounds, add an arglist to argss if necessary and instantiate the corresponding evidences - // consider the following example: - // - // class D[T] { - // class C[U] { - // def foo[V] = macro Impls.foo[T, U, V] - // } - // } - // - // val outer1 = new D[Int] - // val outer2 = new outer1.C[String] - // outer2.foo[Boolean] - // - // then T and U need to be inferred from the lexical scope of the call using `asSeenFrom` - // whereas V won't be resolved by asSeenFrom and need to be loaded directly from `expandee` which needs to contain a TypeApply node - // also, macro implementation reference may contain a regular type as a type argument, then we pass it verbatim val binding = loadMacroImplBinding(macroDef) - macroLogVerbose(s"binding: $binding") - val tags = binding.signature filter (_ != -1) map (paramPos => { - val targ = binding.targs(paramPos).tpe.typeSymbol - val tpe = if (targ.isTypeParameterOrSkolem) { - if (targ.owner == macroDef) { - // doesn't work when macro def is compiled separately from its usages - // then targ is not a skolem and isn't equal to any of macroDef.typeParams - // val argPos = targ.deSkolemize.paramPos - val argPos = macroDef.typeParams.indexWhere(_.name == targ.name) - typeArgs(argPos).tpe + if (binding.className == Predef_???.owner.fullName.toString && binding.methName == Predef_???.name.encoded) Nil + else { + macroLogVerbose(s"binding: $binding") + + // STEP I: prepare value arguments of the macro expansion + // wrap argss in c.Expr if necessary (i.e. if corresponding macro impl param is of type c.Expr[T]) + // expand varargs (nb! varargs can apply to any parameter section, not necessarily to the last one) + val trees = map3(argss, paramss, binding.signature.tail)((args, defParams, implParams) => { + val isVarargs = isVarArgsList(defParams) + if (isVarargs) { + if (defParams.length > args.length + 1) MacroTooFewArguments(expandee) + } else { + if (defParams.length < args.length) MacroTooManyArguments(expandee) + if (defParams.length > args.length) MacroTooFewArguments(expandee) + } + + val wrappedArgs = mapWithIndex(args)((arg, j) => { + val fingerprint = implParams(min(j, implParams.length - 1)) + fingerprint match { + case IMPLPARAM_EXPR => context.Expr[Nothing](arg)(TypeTag.Nothing) // TODO: SI-5752 + case _ => abort(s"unexpected fingerprint $fingerprint in $binding with paramss being $paramss " + + s"corresponding to arg $arg in $argss") + } + }) + + if (isVarargs) { + val (normal, varargs) = wrappedArgs splitAt (defParams.length - 1) + normal :+ varargs // pack all varargs into a single Seq argument (varargs Scala style) + } else wrappedArgs + }) + macroLogVerbose(s"trees: $trees") + + // STEP II: prepare type arguments of the macro expansion + // if paramss have typetag context bounds, add an arglist to argss if necessary and instantiate the corresponding evidences + // consider the following example: + // + // class D[T] { + // class C[U] { + // def foo[V] = macro Impls.foo[T, U, V] + // } + // } + // + // val outer1 = new D[Int] + // val outer2 = new outer1.C[String] + // outer2.foo[Boolean] + // + // then T and U need to be inferred from the lexical scope of the call using `asSeenFrom` + // whereas V won't be resolved by asSeenFrom and need to be loaded directly from `expandee` which needs to contain a TypeApply node + // also, macro implementation reference may contain a regular type as a type argument, then we pass it verbatim + val tags = binding.signature.flatten filter (_ >= IMPLPARAM_TAG) map (paramPos => { + val targ = binding.targs(paramPos).tpe.typeSymbol + val tpe = if (targ.isTypeParameterOrSkolem) { + if (targ.owner == macroDef) { + // doesn't work when macro def is compiled separately from its usages + // then targ is not a skolem and isn't equal to any of macroDef.typeParams + // val argPos = targ.deSkolemize.paramPos + val argPos = macroDef.typeParams.indexWhere(_.name == targ.name) + targs(argPos).tpe + } else + targ.tpe.asSeenFrom( + if (prefix == EmptyTree) macroDef.owner.tpe else prefix.tpe, + macroDef.owner) } else - targ.tpe.asSeenFrom( - if (prefixTree == EmptyTree) macroDef.owner.tpe else prefixTree.tpe, - macroDef.owner) - } else - targ.tpe - context.WeakTypeTag(tpe) - }) - macroLogVerbose(s"tags: $tags") - - // transforms argss taking into account varargness of paramss - // note that typetag context bounds are only declared on macroImpls - // so this optional arglist might not match macroDef's paramlist - // nb! varargs can apply to any parameter section, not necessarily to the last one - mapWithIndex(argss :+ tags)((as, i) => { - val mapsToParamss = macroDef.paramss.indices contains i - if (mapsToParamss) { - val ps = macroDef.paramss(i) - if (isVarArgsList(ps)) { - val (normal, varargs) = as splitAt (ps.length - 1) - normal :+ varargs // pack all varargs into a single List argument - } else as - } else as - }) + targ.tpe + context.WeakTypeTag(tpe) + }) + macroLogVerbose(s"tags: $tags") + + // if present, tags always come in a separate parameter/argument list + // that's because macro impls can't have implicit parameters other than c.WeakTypeTag[T] + (trees :+ tags).flatten + } } - macroLogVerbose(s"preparedArgss: $preparedArgss") - MacroArgs(context, preparedArgss.flatten) + macroLogVerbose(s"macroImplArgs: $macroImplArgs") + MacroArgs(context, macroImplArgs) } /** Keeps track of macros in-flight. @@ -680,7 +760,7 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces { * 1) If necessary desugars the `expandee` to fit into `macroExpand1` * * Then `macroExpand1`: - * 2) Checks whether the expansion needs to be delayed (see `mustDelayMacroExpansion`) + * 2) Checks whether the expansion needs to be delayed * 3) Loads macro implementation using `macroMirror` * 4) Synthesizes invocation arguments for the macro implementation * 5) Checks that the result is a tree or an expr bound to this universe diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala index 4ccfb31878..c9849eebb5 100644 --- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala +++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala @@ -126,7 +126,7 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans val defaultMethodNames = defaultGetters map (sym => nme.defaultGetterToMethod(sym.name)) defaultMethodNames.toList.distinct foreach { name => - val methods = clazz.info.findMember(name, 0L, METHOD, false).alternatives + val methods = clazz.info.findMember(name, 0L, METHOD, stableOnly = false).alternatives def hasDefaultParam(tpe: Type): Boolean = tpe match { case MethodType(params, restpe) => (params exists (_.hasDefault)) || hasDefaultParam(restpe) case _ => false diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 238727d2e9..5916116ef3 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -5534,7 +5534,7 @@ trait Typers extends Adaptations with Tags { val isMacroBodyOkay = !tree.symbol.isErroneous && !(tree1 exists (_.isErroneous)) && tree1 != EmptyTree val shouldInheritMacroImplReturnType = ddef.tpt.isEmpty - if (isMacroBodyOkay && shouldInheritMacroImplReturnType) computeMacroDefTypeFromMacroImpl(ddef, tree1.symbol) else AnyTpe + if (isMacroBodyOkay && shouldInheritMacroImplReturnType) computeMacroDefTypeFromMacroImpl(ddef, macroImplSig(tree1.symbol)) else AnyTpe } def transformedOr(tree: Tree, op: => Tree): Tree = transformed remove tree match { diff --git a/src/reflect/scala/reflect/internal/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala index 5cd86b7eed..630572464d 100644 --- a/src/reflect/scala/reflect/internal/Definitions.scala +++ b/src/reflect/scala/reflect/internal/Definitions.scala @@ -505,6 +505,13 @@ trait Definitions extends api.StandardDefinitions { 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 + object ExprClassOf { + def unapply(tpe: Type): Option[Type] = tpe.dealias match { + case ExistentialType(_, underlying) => unapply(underlying) + case TypeRef(_, ExprClass, t :: Nil) => Some(t) + case _ => None + } + } lazy val ClassTagModule = requiredModule[scala.reflect.ClassTag[_]] lazy val ClassTagClass = requiredClass[scala.reflect.ClassTag[_]] @@ -530,6 +537,9 @@ trait Definitions extends api.StandardDefinitions { def MacroContextPrefix = if (MacroContextClass != NoSymbol) getMemberMethod(MacroContextClass, nme.prefix) else NoSymbol def MacroContextPrefixType = if (MacroContextClass != NoSymbol) getTypeMember(MacroContextClass, tpnme.PrefixType) else NoSymbol def MacroContextUniverse = if (MacroContextClass != NoSymbol) getMemberMethod(MacroContextClass, nme.universe) else NoSymbol + def MacroContextExprClass = if (MacroContextClass != NoSymbol) getTypeMember(MacroContextClass, tpnme.Expr) else NoSymbol + def MacroContextWeakTypeTagClass = if (MacroContextClass != NoSymbol) getTypeMember(MacroContextClass, tpnme.WeakTypeTag) else NoSymbol + def MacroContextTreeType = if (MacroContextClass != NoSymbol) getTypeMember(MacroContextClass, tpnme.Tree) else NoSymbol lazy val MacroImplAnnotation = requiredClass[scala.reflect.macros.internal.macroImpl] lazy val StringContextClass = requiredClass[scala.StringContext] diff --git a/test/files/neg/macro-qmarkqmarkqmark.check b/test/files/neg/macro-qmarkqmarkqmark.check index afd49e7d90..bc3e25edaf 100644 --- a/test/files/neg/macro-qmarkqmarkqmark.check +++ b/test/files/neg/macro-qmarkqmarkqmark.check @@ -1,7 +1,7 @@ macro-qmarkqmarkqmark.scala:5: error: macro implementation is missing foo1 ^ -macro-qmarkqmarkqmark.scala:8: error: macros cannot be partially applied +macro-qmarkqmarkqmark.scala:8: error: too few argument lists for macro invocation foo2 ^ macro-qmarkqmarkqmark.scala:9: error: macro implementation is missing diff --git a/test/files/neg/t7157.check b/test/files/neg/t7157.check new file mode 100644 index 0000000000..c6a7af9a23 --- /dev/null +++ b/test/files/neg/t7157.check @@ -0,0 +1,73 @@ +Test_2.scala:5: error: too many arguments for macro method m1_0_0: ()Unit + m1_0_0(1) + ^ +Test_2.scala:6: error: too many arguments for macro method m1_0_0: ()Unit + m1_0_0(1, 2) + ^ +Test_2.scala:7: error: too many arguments for macro method m1_0_0: ()Unit + m1_0_0(1, 2, 3) + ^ +Test_2.scala:9: error: macro applications do not support named and/or default arguments + m1_1_1() + ^ +Test_2.scala:11: error: too many arguments for macro method m1_1_1: (x: Int)Unit + m1_1_1(1, 2) + ^ +Test_2.scala:12: error: too many arguments for macro method m1_1_1: (x: Int)Unit + m1_1_1(1, 2, 3) + ^ +Test_2.scala:14: error: macro applications do not support named and/or default arguments + m1_2_2() + ^ +Test_2.scala:15: error: macro applications do not support named and/or default arguments + m1_2_2(1) + ^ +Test_2.scala:17: error: too many arguments for macro method m1_2_2: (x: Int, y: Int)Unit + m1_2_2(1, 2, 3) + ^ +Test_2.scala:24: error: macro applications do not support named and/or default arguments + m1_1_inf() + ^ +Test_2.scala:29: error: macro applications do not support named and/or default arguments + m1_2_inf() + ^ +Test_2.scala:30: error: macro applications do not support named and/or default arguments + m1_2_inf(1) + ^ +Test_2.scala:35: error: too many arguments for macro method m2_0_0: ()Unit + m2_0_0()(1) + ^ +Test_2.scala:36: error: too many arguments for macro method m2_0_0: ()Unit + m2_0_0()(1, 2) + ^ +Test_2.scala:37: error: too many arguments for macro method m2_0_0: ()Unit + m2_0_0()(1, 2, 3) + ^ +Test_2.scala:39: error: macro applications do not support named and/or default arguments + m2_1_1()() + ^ +Test_2.scala:41: error: too many arguments for macro method m2_1_1: (x: Int)Unit + m2_1_1()(1, 2) + ^ +Test_2.scala:42: error: too many arguments for macro method m2_1_1: (x: Int)Unit + m2_1_1()(1, 2, 3) + ^ +Test_2.scala:44: error: macro applications do not support named and/or default arguments + m2_2_2()() + ^ +Test_2.scala:45: error: macro applications do not support named and/or default arguments + m2_2_2()(1) + ^ +Test_2.scala:47: error: too many arguments for macro method m2_2_2: (x: Int, y: Int)Unit + m2_2_2()(1, 2, 3) + ^ +Test_2.scala:54: error: macro applications do not support named and/or default arguments + m2_1_inf()() + ^ +Test_2.scala:59: error: macro applications do not support named and/or default arguments + m2_2_inf()() + ^ +Test_2.scala:60: error: macro applications do not support named and/or default arguments + m2_2_inf()(1) + ^ +24 errors found diff --git a/test/files/neg/t7157/Impls_Macros_1.scala b/test/files/neg/t7157/Impls_Macros_1.scala new file mode 100644 index 0000000000..09f423fbab --- /dev/null +++ b/test/files/neg/t7157/Impls_Macros_1.scala @@ -0,0 +1,32 @@ +import scala.reflect.macros.Context +import language.experimental.macros + +object Macros { + def impl1_0_0(c: Context)() = c.literalUnit + def impl1_1_1(c: Context)(x: c.Expr[Int]) = c.literalUnit + def impl1_2_2(c: Context)(x: c.Expr[Int], y: c.Expr[Int]) = c.literalUnit + def m1_0_0() = macro impl1_0_0 + def m1_1_1(x: Int) = macro impl1_1_1 + def m1_2_2(x: Int, y: Int) = macro impl1_2_2 + + def impl1_0_inf(c: Context)(x: c.Expr[Int]*) = c.literalUnit + def impl1_1_inf(c: Context)(x: c.Expr[Int], y: c.Expr[Int]*) = c.literalUnit + def impl1_2_inf(c: Context)(x: c.Expr[Int], y: c.Expr[Int], z: c.Expr[Int]*) = c.literalUnit + def m1_0_inf(x: Int*) = macro impl1_0_inf + def m1_1_inf(x: Int, y: Int*) = macro impl1_1_inf + def m1_2_inf(x: Int, y: Int, z: Int*) = macro impl1_2_inf + + def impl2_0_0(c: Context)()() = c.literalUnit + def impl2_1_1(c: Context)()(x: c.Expr[Int]) = c.literalUnit + def impl2_2_2(c: Context)()(x: c.Expr[Int], y: c.Expr[Int]) = c.literalUnit + def m2_0_0()() = macro impl2_0_0 + def m2_1_1()(x: Int) = macro impl2_1_1 + def m2_2_2()(x: Int, y: Int) = macro impl2_2_2 + + def impl2_0_inf(c: Context)()(x: c.Expr[Int]*) = c.literalUnit + def impl2_1_inf(c: Context)()(x: c.Expr[Int], y: c.Expr[Int]*) = c.literalUnit + def impl2_2_inf(c: Context)()(x: c.Expr[Int], y: c.Expr[Int], z: c.Expr[Int]*) = c.literalUnit + def m2_0_inf()(x: Int*) = macro impl2_0_inf + def m2_1_inf()(x: Int, y: Int*) = macro impl2_1_inf + def m2_2_inf()(x: Int, y: Int, z: Int*) = macro impl2_2_inf +} \ No newline at end of file diff --git a/test/files/neg/t7157/Test_2.scala b/test/files/neg/t7157/Test_2.scala new file mode 100644 index 0000000000..45a6026399 --- /dev/null +++ b/test/files/neg/t7157/Test_2.scala @@ -0,0 +1,63 @@ +import Macros._ + +object Test extends App { + m1_0_0() + m1_0_0(1) + m1_0_0(1, 2) + m1_0_0(1, 2, 3) + + m1_1_1() + m1_1_1(1) + m1_1_1(1, 2) + m1_1_1(1, 2, 3) + + m1_2_2() + m1_2_2(1) + m1_2_2(1, 2) + m1_2_2(1, 2, 3) + + m1_0_inf() + m1_0_inf(1) + m1_0_inf(1, 2) + m1_0_inf(1, 2, 3) + + m1_1_inf() + m1_1_inf(1) + m1_1_inf(1, 2) + m1_1_inf(1, 2, 3) + + m1_2_inf() + m1_2_inf(1) + m1_2_inf(1, 2) + m1_2_inf(1, 2, 3) + + m2_0_0()() + m2_0_0()(1) + m2_0_0()(1, 2) + m2_0_0()(1, 2, 3) + + m2_1_1()() + m2_1_1()(1) + m2_1_1()(1, 2) + m2_1_1()(1, 2, 3) + + m2_2_2()() + m2_2_2()(1) + m2_2_2()(1, 2) + m2_2_2()(1, 2, 3) + + m2_0_inf()() + m2_0_inf()(1) + m2_0_inf()(1, 2) + m2_0_inf()(1, 2, 3) + + m2_1_inf()() + m2_1_inf()(1) + m2_1_inf()(1, 2) + m2_1_inf()(1, 2, 3) + + m2_2_inf()() + m2_2_inf()(1) + m2_2_inf()(1, 2) + m2_2_inf()(1, 2, 3) +} \ No newline at end of file diff --git a/test/files/run/macro-invalidusage-partialapplication-with-tparams.check b/test/files/run/macro-invalidusage-partialapplication-with-tparams.check index f1d5e925fa..326f3e08ca 100644 --- a/test/files/run/macro-invalidusage-partialapplication-with-tparams.check +++ b/test/files/run/macro-invalidusage-partialapplication-with-tparams.check @@ -1,3 +1,3 @@ reflective compilation has failed: -macros cannot be partially applied +too few argument lists for macro invocation diff --git a/test/files/run/macro-invalidusage-partialapplication.check b/test/files/run/macro-invalidusage-partialapplication.check index f1d5e925fa..326f3e08ca 100644 --- a/test/files/run/macro-invalidusage-partialapplication.check +++ b/test/files/run/macro-invalidusage-partialapplication.check @@ -1,3 +1,3 @@ reflective compilation has failed: -macros cannot be partially applied +too few argument lists for macro invocation diff --git a/test/files/run/reify-repl-fail-gracefully.check b/test/files/run/reify-repl-fail-gracefully.check index 1b0f3f2162..18cfd5a7ef 100644 --- a/test/files/run/reify-repl-fail-gracefully.check +++ b/test/files/run/reify-repl-fail-gracefully.check @@ -12,7 +12,7 @@ import scala.reflect.runtime.universe._ scala> scala> reify -:12: error: macros cannot be partially applied +:12: error: too few argument lists for macro invocation reify ^ diff --git a/test/files/run/t7157.check b/test/files/run/t7157.check new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/test/files/run/t7157.check @@ -0,0 +1 @@ +1 diff --git a/test/files/run/t7157/Impls_Macros_1.scala b/test/files/run/t7157/Impls_Macros_1.scala new file mode 100644 index 0000000000..ad3d96eb85 --- /dev/null +++ b/test/files/run/t7157/Impls_Macros_1.scala @@ -0,0 +1,15 @@ +import scala.reflect.macros.Context +import language.experimental.macros + +object Macros { + object AImpl { + def a(ctx: Context)(args: ctx.Expr[Any]*): ctx.Expr[Unit] = { + import ctx.universe._ + ctx.Expr[Unit](Apply(Ident(TermName("println")), List(Literal(Constant(1))))) + } + } + + implicit class A(context: StringContext) { + def a(args: Any*): Unit = macro AImpl.a + } +} \ No newline at end of file diff --git a/test/files/run/t7157/Test_2.scala b/test/files/run/t7157/Test_2.scala new file mode 100644 index 0000000000..cceb5ca177 --- /dev/null +++ b/test/files/run/t7157/Test_2.scala @@ -0,0 +1,5 @@ +import Macros._ + +object Test extends App { + a"" +} \ No newline at end of file -- cgit v1.2.3 From 70f001181734f76064d97ec25b1afd6aad49b684 Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Mon, 14 Jan 2013 23:55:25 +0100 Subject: refactors macro tests putting in a nutshell, this patch: * condenses some macro-XXX-a/b/c/... bundles * renames some tests to prepare for other macro flavors * introduces some additional tests --- test/files/neg/macro-invalidimpl-a.check | 4 - test/files/neg/macro-invalidimpl-a.flags | 1 - test/files/neg/macro-invalidimpl-a/Impls_1.scala | 5 -- .../neg/macro-invalidimpl-a/Macros_Test_2.scala | 9 --- test/files/neg/macro-invalidimpl-b.check | 4 - test/files/neg/macro-invalidimpl-b.flags | 1 - test/files/neg/macro-invalidimpl-b/Impls_1.scala | 5 -- .../neg/macro-invalidimpl-b/Macros_Test_2.scala | 9 --- test/files/neg/macro-invalidimpl-c.check | 4 - test/files/neg/macro-invalidimpl-c.flags | 1 - .../neg/macro-invalidimpl-c/Impls_Macros_1.scala | 9 --- test/files/neg/macro-invalidimpl-c/Test_2.scala | 3 - test/files/neg/macro-invalidimpl-d.check | 4 - test/files/neg/macro-invalidimpl-d.flags | 1 - test/files/neg/macro-invalidimpl-d/Impls_1.scala | 7 -- .../neg/macro-invalidimpl-d/Macros_Test_2.scala | 7 -- test/files/neg/macro-invalidimpl-e.check | 13 ---- test/files/neg/macro-invalidimpl-e.flags | 1 - test/files/neg/macro-invalidimpl-e/Impls_1.scala | 6 -- .../neg/macro-invalidimpl-e/Macros_Test_2.scala | 9 --- test/files/neg/macro-invalidimpl-f.check | 7 -- test/files/neg/macro-invalidimpl-f.flags | 1 - test/files/neg/macro-invalidimpl-f/Impls_1.scala | 11 --- .../neg/macro-invalidimpl-f/Macros_Test_2.scala | 9 --- test/files/neg/macro-invalidimpl-g.check | 7 -- test/files/neg/macro-invalidimpl-g.flags | 1 - test/files/neg/macro-invalidimpl-g/Impls_1.scala | 11 --- .../neg/macro-invalidimpl-g/Macros_Test_2.scala | 8 -- test/files/neg/macro-invalidimpl-h.check | 4 - test/files/neg/macro-invalidimpl-h.flags | 1 - test/files/neg/macro-invalidimpl-h/Impls_1.scala | 5 -- .../neg/macro-invalidimpl-h/Macros_Test_2.scala | 8 -- test/files/neg/macro-invalidimpl-i.check | 4 - test/files/neg/macro-invalidimpl-i.flags | 1 - test/files/neg/macro-invalidimpl-i/Impls_1.scala | 7 -- .../neg/macro-invalidimpl-i/Macros_Test_2.scala | 5 -- test/files/neg/macro-invalidimpl.check | 43 +++++++++++ test/files/neg/macro-invalidimpl.flags | 1 + test/files/neg/macro-invalidimpl/Impls_1.scala | 40 ++++++++++ .../neg/macro-invalidimpl/Macros_Test_2.scala | 55 ++++++++++++++ test/files/neg/macro-invalidret-nontree.flags | 1 - .../neg/macro-invalidret-nontree/Impls_1.scala | 5 -- .../macro-invalidret-nontree/Macros_Test_2.scala | 8 -- .../neg/macro-invalidret-nonuniversetree.flags | 1 - .../macro-invalidret-nonuniversetree/Impls_1.scala | 6 -- .../Macros_Test_2.scala | 8 -- test/files/neg/macro-invalidret.check | 13 ++++ test/files/neg/macro-invalidret.flags | 1 + test/files/neg/macro-invalidret/Impls_1.scala | 7 ++ .../files/neg/macro-invalidret/Macros_Test_2.scala | 10 +++ test/files/neg/macro-invalidshape-a.check | 5 -- test/files/neg/macro-invalidshape-a.flags | 1 - test/files/neg/macro-invalidshape-a/Impls_1.scala | 5 -- .../neg/macro-invalidshape-a/Macros_Test_2.scala | 8 -- test/files/neg/macro-invalidshape-b.check | 5 -- test/files/neg/macro-invalidshape-b.flags | 1 - test/files/neg/macro-invalidshape-b/Impls_1.scala | 5 -- .../neg/macro-invalidshape-b/Macros_Test_2.scala | 8 -- test/files/neg/macro-invalidshape-c.check | 9 --- test/files/neg/macro-invalidshape-c.flags | 1 - test/files/neg/macro-invalidshape-c/Impls_1.scala | 5 -- .../neg/macro-invalidshape-c/Macros_Test_2.scala | 8 -- test/files/neg/macro-invalidshape-d.check | 8 -- test/files/neg/macro-invalidshape-d.flags | 1 - test/files/neg/macro-invalidshape-d/Impls_1.scala | 5 -- .../neg/macro-invalidshape-d/Macros_Test_2.scala | 8 -- test/files/neg/macro-invalidshape.check | 17 +++++ test/files/neg/macro-invalidshape.flags | 1 + test/files/neg/macro-invalidshape/Impls_1.scala | 5 ++ .../neg/macro-invalidshape/Macros_Test_2.scala | 12 +++ .../macro-invalidsig-context-bounds/Impls_1.scala | 9 --- .../Macros_Test_1.scala | 8 -- .../neg/macro-invalidsig-ctx-badargc/Impls_1.scala | 3 - .../Macros_Test_2.scala | 8 -- .../neg/macro-invalidsig-ctx-badtype/Impls_1.scala | 5 -- .../Macros_Test_2.scala | 8 -- .../macro-invalidsig-ctx-badvarargs/Impls_1.scala | 5 -- .../Macros_Test_2.scala | 8 -- .../neg/macro-invalidsig-ctx-noctx/Impls_1.scala | 5 -- .../macro-invalidsig-ctx-noctx/Macros_Test_2.scala | 8 -- .../Impls_Macros_1.scala | 19 ----- .../macro-invalidsig-implicit-params/Test_2.scala | 4 - .../Impls_Macros_1.scala | 9 --- .../macro-invalidsig-params-badargc/Test_2.scala | 4 - .../macro-invalidsig-params-badtype/Test_2.scala | 4 - .../Impls_Macros_1.scala | 9 --- .../Test_2.scala | 4 - .../Impls_Macros_1.scala | 9 --- .../Test_2.scala | 4 - .../macro-invalidsig-tparams-badtype/Impls_1.scala | 5 -- .../Macros_Test_2.scala | 8 -- .../Impls_1.scala | 5 -- .../Macros_Test_2.scala | 8 -- .../Impls_1.scala | 5 -- .../Macros_Test_2.scala | 8 -- .../Impls_1.scala | 6 -- .../Macros_Test_2.scala | 8 -- .../Impls_1.scala | 11 --- .../Macros_Test_2.scala | 11 --- .../Impls_1.scala | 12 --- .../Macros_Test_2.scala | 11 --- test/files/neg/macro-invalidsig.check | 82 ++++++++++++++++++++ test/files/neg/macro-invalidsig.flags | 1 + test/files/neg/macro-invalidsig/Impls_1.scala | 88 ++++++++++++++++++++++ .../files/neg/macro-invalidsig/Macros_Test_2.scala | 83 ++++++++++++++++++++ test/files/neg/macro-invalidusage-badargs.check | 20 ++++- .../macro-invalidusage-badargs/Macros_Test_2.scala | 12 +-- .../files/neg/macro-invalidusage-badbounds-a.check | 4 - .../files/neg/macro-invalidusage-badbounds-a.flags | 1 - .../macro-invalidusage-badbounds-a/Impls_1.scala | 5 -- .../Macros_Test_2.scala | 8 -- test/files/neg/macro-invalidusage-badbounds.check | 4 + test/files/neg/macro-invalidusage-badbounds.flags | 1 + .../neg/macro-invalidusage-badbounds/Impls_1.scala | 5 ++ .../Macros_Test_2.scala | 8 ++ .../neg/macro-invalidusage-badtargs-untyped.check | 18 +++++ .../neg/macro-invalidusage-badtargs-untyped.flags | 1 + test/files/neg/macro-invalidusage-badtargs.check | 22 +++++- .../Macros_Test_2.scala | 12 ++- .../files/neg/macro-invalidusage-nontypeable.check | 4 + .../files/neg/macro-invalidusage-nontypeable.flags | 1 + .../Impls_Macros_1.scala | 13 ++++ .../macro-invalidusage-nontypeable/Test_2.scala | 3 + test/files/neg/macro-invalidusage-presuper.check | 4 + test/files/neg/macro-invalidusage-presuper.flags | 1 + .../neg/macro-invalidusage-presuper/Impls_1.scala | 5 ++ .../Macros_Test_2.scala | 3 + test/files/run/macro-declared-in-annotation.check | 1 - test/files/run/macro-declared-in-annotation.flags | 1 - .../run/macro-declared-in-annotation/Impls_1.scala | 11 --- .../macro-declared-in-annotation/Macros_2.scala | 8 -- .../run/macro-declared-in-annotation/Test_3.scala | 3 - test/files/run/macro-declared-in-anonymous.check | 2 - test/files/run/macro-declared-in-anonymous.flags | 1 - .../run/macro-declared-in-anonymous/Impls_1.scala | 11 --- .../Macros_Test_2.scala | 6 -- test/files/run/macro-declared-in-block.check | 2 - test/files/run/macro-declared-in-block.flags | 1 - .../run/macro-declared-in-block/Impls_1.scala | 11 --- .../macro-declared-in-block/Macros_Test_2.scala | 6 -- test/files/run/macro-declared-in-class-class.check | 2 - test/files/run/macro-declared-in-class-class.flags | 1 - .../macro-declared-in-class-class/Impls_1.scala | 11 --- .../Macros_Test_2.scala | 10 --- .../files/run/macro-declared-in-class-object.check | 2 - .../files/run/macro-declared-in-class-object.flags | 1 - .../macro-declared-in-class-object/Impls_1.scala | 11 --- .../Macros_Test_2.scala | 10 --- test/files/run/macro-declared-in-class.check | 2 - test/files/run/macro-declared-in-class.flags | 1 - .../run/macro-declared-in-class/Impls_1.scala | 11 --- .../macro-declared-in-class/Macros_Test_2.scala | 7 -- .../run/macro-declared-in-default-param.check | 5 -- .../run/macro-declared-in-default-param.flags | 1 - .../macro-declared-in-default-param/Impls_1.scala | 11 --- .../Macros_Test_2.scala | 7 -- .../run/macro-declared-in-implicit-class.check | 2 - .../run/macro-declared-in-implicit-class.flags | 1 - .../Impls_Macros_1.scala | 19 ----- .../macro-declared-in-implicit-class/Test_2.scala | 4 - test/files/run/macro-declared-in-method.check | 2 - test/files/run/macro-declared-in-method.flags | 1 - .../run/macro-declared-in-method/Impls_1.scala | 11 --- .../macro-declared-in-method/Macros_Test_2.scala | 8 -- .../files/run/macro-declared-in-object-class.check | 2 - .../files/run/macro-declared-in-object-class.flags | 1 - .../macro-declared-in-object-class/Impls_1.scala | 11 --- .../Macros_Test_2.scala | 10 --- .../run/macro-declared-in-object-object.check | 2 - .../run/macro-declared-in-object-object.flags | 1 - .../macro-declared-in-object-object/Impls_1.scala | 11 --- .../Macros_Test_2.scala | 10 --- test/files/run/macro-declared-in-object.check | 2 - test/files/run/macro-declared-in-object.flags | 1 - .../run/macro-declared-in-object/Impls_1.scala | 11 --- .../macro-declared-in-object/Macros_Test_2.scala | 7 -- .../run/macro-declared-in-package-object.check | 2 - .../run/macro-declared-in-package-object.flags | 1 - .../macro-declared-in-package-object/Impls_1.scala | 11 --- .../Macros_Test_2.scala | 8 -- test/files/run/macro-declared-in-refinement.check | 2 - test/files/run/macro-declared-in-refinement.flags | 1 - .../run/macro-declared-in-refinement/Impls_1.scala | 11 --- .../Macros_Test_2.scala | 9 --- test/files/run/macro-declared-in-trait.check | 15 ---- test/files/run/macro-declared-in-trait.flags | 1 - .../run/macro-declared-in-trait/Impls_1.scala | 11 --- .../macro-declared-in-trait/Macros_Test_2.scala | 13 ---- test/files/run/macro-def-infer-return-type-a.check | 1 - test/files/run/macro-def-infer-return-type-a.flags | 1 - .../macro-def-infer-return-type-a/Impls_1.scala | 5 -- .../Macros_Test_2.scala | 4 - test/files/run/macro-def-infer-return-type-b.check | 6 -- test/files/run/macro-def-infer-return-type-b.flags | 1 - .../Impls_Macros_1.scala | 10 --- .../run/macro-def-infer-return-type-b/Test_2.scala | 8 -- test/files/run/macro-def-infer-return-type-c.check | 1 - test/files/run/macro-def-infer-return-type-c.flags | 1 - .../macro-def-infer-return-type-c/Impls_1.scala | 5 -- .../Macros_Test_2.scala | 4 - test/files/run/macro-def-infer-return-type.check | 8 ++ test/files/run/macro-def-infer-return-type.flags | 1 + .../run/macro-def-infer-return-type/Impls_1.scala | 14 ++++ .../Macros_Test_2.scala | 24 ++++++ test/files/run/macro-def-path-dependent-a.check | 1 - test/files/run/macro-def-path-dependent-a.flags | 1 - .../Impls_Macros_1.scala | 21 ------ .../run/macro-def-path-dependent-a/Test_2.scala | 3 - test/files/run/macro-def-path-dependent-b.check | 1 - test/files/run/macro-def-path-dependent-b.flags | 1 - .../Impls_Macros_1.scala | 20 ----- .../run/macro-def-path-dependent-b/Test_2.scala | 3 - test/files/run/macro-def-path-dependent-c.check | 1 - test/files/run/macro-def-path-dependent-c.flags | 1 - .../Impls_Macros_1.scala | 20 ----- .../run/macro-def-path-dependent-c/Test_2.scala | 3 - test/files/run/macro-def-path-dependent-d1.check | 1 - test/files/run/macro-def-path-dependent-d1.flags | 1 - .../Impls_Macros_1.scala | 9 --- .../run/macro-def-path-dependent-d1/Test_2.scala | 3 - test/files/run/macro-def-path-dependent-d2.check | 1 - test/files/run/macro-def-path-dependent-d2.flags | 1 - .../run/macro-def-path-dependent-d2/Impls_1.scala | 7 -- .../run/macro-def-path-dependent-d2/Macros_2.scala | 7 -- .../run/macro-def-path-dependent-d2/Test_3.scala | 3 - test/files/run/macro-def-path-dependent.check | 1 + test/files/run/macro-def-path-dependent.flags | 1 + .../files/run/macro-def-path-dependent/Dummy.scala | 3 + .../run/macro-def-path-dependent/Test_1.scala | 23 ++++++ .../run/macro-def-path-dependent/Test_2.scala | 22 ++++++ .../run/macro-def-path-dependent/Test_3.scala | 22 ++++++ .../run/macro-def-path-dependent/Test_4.scala | 11 +++ .../run/macro-def-path-dependent/Test_5.scala | 9 +++ .../run/macro-def-path-dependent/Test_6.scala | 9 +++ test/files/run/macro-expand-nullary-generic.check | 10 +-- .../run/macro-expand-nullary-generic/Impls_1.scala | 12 +-- .../run/macro-expand-nullary-nongeneric.check | 10 +-- .../macro-expand-nullary-nongeneric/Impls_1.scala | 13 ++-- test/files/run/macro-expand-tparams-bounds-a.check | 0 test/files/run/macro-expand-tparams-bounds-a.flags | 1 - .../macro-expand-tparams-bounds-a/Impls_1.scala | 5 -- .../Macros_Test_2.scala | 8 -- test/files/run/macro-expand-tparams-bounds-b.check | 0 test/files/run/macro-expand-tparams-bounds-b.flags | 1 - .../macro-expand-tparams-bounds-b/Impls_1.scala | 7 -- .../Macros_Test_2.scala | 10 --- test/files/run/macro-expand-tparams-bounds.check | 0 test/files/run/macro-expand-tparams-bounds.flags | 1 + .../run/macro-expand-tparams-bounds/Impls_1.scala | 12 +++ .../Macros_Test_2.scala | 12 +++ .../run/macro-expand-tparams-only-in-impl.flags | 1 - .../Impls_1.scala | 5 -- .../Macros_Test_2.scala | 8 -- test/files/run/macro-expand-tparams-optional.check | 1 - test/files/run/macro-expand-tparams-optional.flags | 1 - .../macro-expand-tparams-optional/Impls_1.scala | 9 --- .../Macros_Test_2.scala | 4 - test/files/run/macro-expand-tparams-prefix-a.check | 4 - test/files/run/macro-expand-tparams-prefix-a.flags | 1 - .../macro-expand-tparams-prefix-a/Impls_1.scala | 11 --- .../Macros_Test_2.scala | 10 --- test/files/run/macro-expand-tparams-prefix-b.check | 2 - test/files/run/macro-expand-tparams-prefix-b.flags | 1 - .../macro-expand-tparams-prefix-b/Impls_1.scala | 12 --- .../Macros_Test_2.scala | 10 --- .../files/run/macro-expand-tparams-prefix-c1.check | 3 - .../files/run/macro-expand-tparams-prefix-c1.flags | 1 - .../macro-expand-tparams-prefix-c1/Impls_1.scala | 13 ---- .../Macros_Test_2.scala | 11 --- .../files/run/macro-expand-tparams-prefix-c2.check | 3 - .../files/run/macro-expand-tparams-prefix-c2.flags | 1 - .../Impls_Macros_1.scala | 19 ----- .../macro-expand-tparams-prefix-c2/Test_2.scala | 5 -- .../files/run/macro-expand-tparams-prefix-d1.check | 3 - .../files/run/macro-expand-tparams-prefix-d1.flags | 1 - .../macro-expand-tparams-prefix-d1/Impls_1.scala | 13 ---- .../Macros_Test_2.scala | 11 --- test/files/run/macro-expand-tparams-prefix.check | 20 +++++ test/files/run/macro-expand-tparams-prefix.flags | 1 + .../run/macro-expand-tparams-prefix/Impls_1.scala | 40 ++++++++++ .../Macros_Test_2.scala | 57 ++++++++++++++ .../files/run/macro-impl-tparam-only-in-impl.flags | 1 + .../macro-impl-tparam-only-in-impl/Impls_1.scala | 5 ++ .../Macros_Test_2.scala | 8 ++ .../macro-impl-tparam-typetag-is-optional.check | 1 + .../macro-impl-tparam-typetag-is-optional.flags | 1 + .../Impls_1.scala | 9 +++ .../Macros_Test_2.scala | 4 + .../run/macro-term-declared-in-annotation.check | 1 + .../run/macro-term-declared-in-annotation.flags | 1 + .../Impls_1.scala | 11 +++ .../Macros_2.scala | 8 ++ .../macro-term-declared-in-annotation/Test_3.scala | 3 + .../run/macro-term-declared-in-anonymous.check | 2 + .../run/macro-term-declared-in-anonymous.flags | 1 + .../macro-term-declared-in-anonymous/Impls_1.scala | 11 +++ .../Macros_Test_2.scala | 6 ++ test/files/run/macro-term-declared-in-block.check | 2 + test/files/run/macro-term-declared-in-block.flags | 1 + .../run/macro-term-declared-in-block/Impls_1.scala | 11 +++ .../Macros_Test_2.scala | 6 ++ .../run/macro-term-declared-in-class-class.check | 2 + .../run/macro-term-declared-in-class-class.flags | 1 + .../Impls_1.scala | 11 +++ .../Macros_Test_2.scala | 10 +++ .../run/macro-term-declared-in-class-object.check | 2 + .../run/macro-term-declared-in-class-object.flags | 1 + .../Impls_1.scala | 11 +++ .../Macros_Test_2.scala | 10 +++ test/files/run/macro-term-declared-in-class.check | 2 + test/files/run/macro-term-declared-in-class.flags | 1 + .../run/macro-term-declared-in-class/Impls_1.scala | 11 +++ .../Macros_Test_2.scala | 7 ++ .../run/macro-term-declared-in-default-param.check | 5 ++ .../run/macro-term-declared-in-default-param.flags | 1 + .../Impls_1.scala | 11 +++ .../Macros_Test_2.scala | 7 ++ .../macro-term-declared-in-implicit-class.check | 2 + .../macro-term-declared-in-implicit-class.flags | 1 + .../Impls_Macros_1.scala | 19 +++++ .../Test_2.scala | 4 + test/files/run/macro-term-declared-in-method.check | 2 + test/files/run/macro-term-declared-in-method.flags | 1 + .../macro-term-declared-in-method/Impls_1.scala | 11 +++ .../Macros_Test_2.scala | 8 ++ .../run/macro-term-declared-in-object-class.check | 2 + .../run/macro-term-declared-in-object-class.flags | 1 + .../Impls_1.scala | 11 +++ .../Macros_Test_2.scala | 10 +++ .../run/macro-term-declared-in-object-object.check | 2 + .../run/macro-term-declared-in-object-object.flags | 1 + .../Impls_1.scala | 11 +++ .../Macros_Test_2.scala | 10 +++ test/files/run/macro-term-declared-in-object.check | 2 + test/files/run/macro-term-declared-in-object.flags | 1 + .../macro-term-declared-in-object/Impls_1.scala | 11 +++ .../Macros_Test_2.scala | 7 ++ .../macro-term-declared-in-package-object.check | 2 + .../macro-term-declared-in-package-object.flags | 1 + .../Impls_1.scala | 11 +++ .../Macros_Test_2.scala | 8 ++ .../run/macro-term-declared-in-refinement.check | 2 + .../run/macro-term-declared-in-refinement.flags | 1 + .../Impls_1.scala | 11 +++ .../Macros_Test_2.scala | 9 +++ test/files/run/macro-term-declared-in-trait.check | 15 ++++ test/files/run/macro-term-declared-in-trait.flags | 1 + .../run/macro-term-declared-in-trait/Impls_1.scala | 11 +++ .../Macros_Test_2.scala | 13 ++++ test/files/run/repl-term-macros.check | 44 +++++++++++ test/files/run/repl-term-macros.scala | 20 +++++ ...erm-declared-in-anonymous-explicit-import.check | 0 .../Impls_1.scala | 11 +++ .../Macros_Test_2.scala | 6 ++ 354 files changed, 1364 insertions(+), 1302 deletions(-) delete mode 100644 test/files/neg/macro-invalidimpl-a.check delete mode 100644 test/files/neg/macro-invalidimpl-a.flags delete mode 100644 test/files/neg/macro-invalidimpl-a/Impls_1.scala delete mode 100644 test/files/neg/macro-invalidimpl-a/Macros_Test_2.scala delete mode 100644 test/files/neg/macro-invalidimpl-b.check delete mode 100644 test/files/neg/macro-invalidimpl-b.flags delete mode 100644 test/files/neg/macro-invalidimpl-b/Impls_1.scala delete mode 100644 test/files/neg/macro-invalidimpl-b/Macros_Test_2.scala delete mode 100644 test/files/neg/macro-invalidimpl-c.check delete mode 100644 test/files/neg/macro-invalidimpl-c.flags delete mode 100644 test/files/neg/macro-invalidimpl-c/Impls_Macros_1.scala delete mode 100644 test/files/neg/macro-invalidimpl-c/Test_2.scala delete mode 100644 test/files/neg/macro-invalidimpl-d.check delete mode 100644 test/files/neg/macro-invalidimpl-d.flags delete mode 100644 test/files/neg/macro-invalidimpl-d/Impls_1.scala delete mode 100644 test/files/neg/macro-invalidimpl-d/Macros_Test_2.scala delete mode 100644 test/files/neg/macro-invalidimpl-e.check delete mode 100644 test/files/neg/macro-invalidimpl-e.flags delete mode 100644 test/files/neg/macro-invalidimpl-e/Impls_1.scala delete mode 100644 test/files/neg/macro-invalidimpl-e/Macros_Test_2.scala delete mode 100644 test/files/neg/macro-invalidimpl-f.check delete mode 100644 test/files/neg/macro-invalidimpl-f.flags delete mode 100644 test/files/neg/macro-invalidimpl-f/Impls_1.scala delete mode 100644 test/files/neg/macro-invalidimpl-f/Macros_Test_2.scala delete mode 100644 test/files/neg/macro-invalidimpl-g.check delete mode 100644 test/files/neg/macro-invalidimpl-g.flags delete mode 100644 test/files/neg/macro-invalidimpl-g/Impls_1.scala delete mode 100644 test/files/neg/macro-invalidimpl-g/Macros_Test_2.scala delete mode 100644 test/files/neg/macro-invalidimpl-h.check delete mode 100644 test/files/neg/macro-invalidimpl-h.flags delete mode 100644 test/files/neg/macro-invalidimpl-h/Impls_1.scala delete mode 100644 test/files/neg/macro-invalidimpl-h/Macros_Test_2.scala delete mode 100644 test/files/neg/macro-invalidimpl-i.check delete mode 100644 test/files/neg/macro-invalidimpl-i.flags delete mode 100644 test/files/neg/macro-invalidimpl-i/Impls_1.scala delete mode 100644 test/files/neg/macro-invalidimpl-i/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidimpl.check create mode 100644 test/files/neg/macro-invalidimpl.flags create mode 100644 test/files/neg/macro-invalidimpl/Impls_1.scala create mode 100644 test/files/neg/macro-invalidimpl/Macros_Test_2.scala delete mode 100644 test/files/neg/macro-invalidret-nontree.flags delete mode 100644 test/files/neg/macro-invalidret-nontree/Impls_1.scala delete mode 100644 test/files/neg/macro-invalidret-nontree/Macros_Test_2.scala delete mode 100644 test/files/neg/macro-invalidret-nonuniversetree.flags delete mode 100644 test/files/neg/macro-invalidret-nonuniversetree/Impls_1.scala delete mode 100644 test/files/neg/macro-invalidret-nonuniversetree/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidret.check create mode 100644 test/files/neg/macro-invalidret.flags create mode 100644 test/files/neg/macro-invalidret/Impls_1.scala create mode 100644 test/files/neg/macro-invalidret/Macros_Test_2.scala delete mode 100644 test/files/neg/macro-invalidshape-a.check delete mode 100644 test/files/neg/macro-invalidshape-a.flags delete mode 100644 test/files/neg/macro-invalidshape-a/Impls_1.scala delete mode 100644 test/files/neg/macro-invalidshape-a/Macros_Test_2.scala delete mode 100644 test/files/neg/macro-invalidshape-b.check delete mode 100644 test/files/neg/macro-invalidshape-b.flags delete mode 100644 test/files/neg/macro-invalidshape-b/Impls_1.scala delete mode 100644 test/files/neg/macro-invalidshape-b/Macros_Test_2.scala delete mode 100644 test/files/neg/macro-invalidshape-c.check delete mode 100644 test/files/neg/macro-invalidshape-c.flags delete mode 100644 test/files/neg/macro-invalidshape-c/Impls_1.scala delete mode 100644 test/files/neg/macro-invalidshape-c/Macros_Test_2.scala delete mode 100644 test/files/neg/macro-invalidshape-d.check delete mode 100644 test/files/neg/macro-invalidshape-d.flags delete mode 100644 test/files/neg/macro-invalidshape-d/Impls_1.scala delete mode 100644 test/files/neg/macro-invalidshape-d/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidshape.check create mode 100644 test/files/neg/macro-invalidshape.flags create mode 100644 test/files/neg/macro-invalidshape/Impls_1.scala create mode 100644 test/files/neg/macro-invalidshape/Macros_Test_2.scala delete mode 100644 test/files/neg/macro-invalidsig-context-bounds/Impls_1.scala delete mode 100644 test/files/neg/macro-invalidsig-context-bounds/Macros_Test_1.scala delete mode 100644 test/files/neg/macro-invalidsig-ctx-badargc/Impls_1.scala delete mode 100644 test/files/neg/macro-invalidsig-ctx-badargc/Macros_Test_2.scala delete mode 100644 test/files/neg/macro-invalidsig-ctx-badtype/Impls_1.scala delete mode 100644 test/files/neg/macro-invalidsig-ctx-badtype/Macros_Test_2.scala delete mode 100644 test/files/neg/macro-invalidsig-ctx-badvarargs/Impls_1.scala delete mode 100644 test/files/neg/macro-invalidsig-ctx-badvarargs/Macros_Test_2.scala delete mode 100644 test/files/neg/macro-invalidsig-ctx-noctx/Impls_1.scala delete mode 100644 test/files/neg/macro-invalidsig-ctx-noctx/Macros_Test_2.scala delete mode 100644 test/files/neg/macro-invalidsig-implicit-params/Impls_Macros_1.scala delete mode 100644 test/files/neg/macro-invalidsig-implicit-params/Test_2.scala delete mode 100644 test/files/neg/macro-invalidsig-params-badargc/Impls_Macros_1.scala delete mode 100644 test/files/neg/macro-invalidsig-params-badargc/Test_2.scala delete mode 100644 test/files/neg/macro-invalidsig-params-badtype/Test_2.scala delete mode 100644 test/files/neg/macro-invalidsig-params-badvarargs/Impls_Macros_1.scala delete mode 100644 test/files/neg/macro-invalidsig-params-badvarargs/Test_2.scala delete mode 100644 test/files/neg/macro-invalidsig-params-namemismatch/Impls_Macros_1.scala delete mode 100644 test/files/neg/macro-invalidsig-params-namemismatch/Test_2.scala delete mode 100644 test/files/neg/macro-invalidsig-tparams-badtype/Impls_1.scala delete mode 100644 test/files/neg/macro-invalidsig-tparams-badtype/Macros_Test_2.scala delete mode 100644 test/files/neg/macro-invalidsig-tparams-bounds-a/Impls_1.scala delete mode 100644 test/files/neg/macro-invalidsig-tparams-bounds-a/Macros_Test_2.scala delete mode 100644 test/files/neg/macro-invalidsig-tparams-bounds-b/Impls_1.scala delete mode 100644 test/files/neg/macro-invalidsig-tparams-bounds-b/Macros_Test_2.scala delete mode 100644 test/files/neg/macro-invalidsig-tparams-notparams-a/Impls_1.scala delete mode 100644 test/files/neg/macro-invalidsig-tparams-notparams-a/Macros_Test_2.scala delete mode 100644 test/files/neg/macro-invalidsig-tparams-notparams-b/Impls_1.scala delete mode 100644 test/files/neg/macro-invalidsig-tparams-notparams-b/Macros_Test_2.scala delete mode 100644 test/files/neg/macro-invalidsig-tparams-notparams-c/Impls_1.scala delete mode 100644 test/files/neg/macro-invalidsig-tparams-notparams-c/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidsig.check create mode 100644 test/files/neg/macro-invalidsig.flags create mode 100644 test/files/neg/macro-invalidsig/Impls_1.scala create mode 100644 test/files/neg/macro-invalidsig/Macros_Test_2.scala delete mode 100644 test/files/neg/macro-invalidusage-badbounds-a.check delete mode 100644 test/files/neg/macro-invalidusage-badbounds-a.flags delete mode 100644 test/files/neg/macro-invalidusage-badbounds-a/Impls_1.scala delete mode 100644 test/files/neg/macro-invalidusage-badbounds-a/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidusage-badbounds.check create mode 100644 test/files/neg/macro-invalidusage-badbounds.flags create mode 100644 test/files/neg/macro-invalidusage-badbounds/Impls_1.scala create mode 100644 test/files/neg/macro-invalidusage-badbounds/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidusage-badtargs-untyped.check create mode 100644 test/files/neg/macro-invalidusage-badtargs-untyped.flags create mode 100644 test/files/neg/macro-invalidusage-nontypeable.check create mode 100644 test/files/neg/macro-invalidusage-nontypeable.flags create mode 100644 test/files/neg/macro-invalidusage-nontypeable/Impls_Macros_1.scala create mode 100644 test/files/neg/macro-invalidusage-nontypeable/Test_2.scala create mode 100644 test/files/neg/macro-invalidusage-presuper.check create mode 100644 test/files/neg/macro-invalidusage-presuper.flags create mode 100644 test/files/neg/macro-invalidusage-presuper/Impls_1.scala create mode 100644 test/files/neg/macro-invalidusage-presuper/Macros_Test_2.scala delete mode 100644 test/files/run/macro-declared-in-annotation.check delete mode 100644 test/files/run/macro-declared-in-annotation.flags delete mode 100644 test/files/run/macro-declared-in-annotation/Impls_1.scala delete mode 100644 test/files/run/macro-declared-in-annotation/Macros_2.scala delete mode 100644 test/files/run/macro-declared-in-annotation/Test_3.scala delete mode 100644 test/files/run/macro-declared-in-anonymous.check delete mode 100644 test/files/run/macro-declared-in-anonymous.flags delete mode 100644 test/files/run/macro-declared-in-anonymous/Impls_1.scala delete mode 100644 test/files/run/macro-declared-in-anonymous/Macros_Test_2.scala delete mode 100644 test/files/run/macro-declared-in-block.check delete mode 100644 test/files/run/macro-declared-in-block.flags delete mode 100644 test/files/run/macro-declared-in-block/Impls_1.scala delete mode 100644 test/files/run/macro-declared-in-block/Macros_Test_2.scala delete mode 100644 test/files/run/macro-declared-in-class-class.check delete mode 100644 test/files/run/macro-declared-in-class-class.flags delete mode 100644 test/files/run/macro-declared-in-class-class/Impls_1.scala delete mode 100644 test/files/run/macro-declared-in-class-class/Macros_Test_2.scala delete mode 100644 test/files/run/macro-declared-in-class-object.check delete mode 100644 test/files/run/macro-declared-in-class-object.flags delete mode 100644 test/files/run/macro-declared-in-class-object/Impls_1.scala delete mode 100644 test/files/run/macro-declared-in-class-object/Macros_Test_2.scala delete mode 100644 test/files/run/macro-declared-in-class.check delete mode 100644 test/files/run/macro-declared-in-class.flags delete mode 100644 test/files/run/macro-declared-in-class/Impls_1.scala delete mode 100644 test/files/run/macro-declared-in-class/Macros_Test_2.scala delete mode 100644 test/files/run/macro-declared-in-default-param.check delete mode 100644 test/files/run/macro-declared-in-default-param.flags delete mode 100644 test/files/run/macro-declared-in-default-param/Impls_1.scala delete mode 100644 test/files/run/macro-declared-in-default-param/Macros_Test_2.scala delete mode 100644 test/files/run/macro-declared-in-implicit-class.check delete mode 100644 test/files/run/macro-declared-in-implicit-class.flags delete mode 100644 test/files/run/macro-declared-in-implicit-class/Impls_Macros_1.scala delete mode 100644 test/files/run/macro-declared-in-implicit-class/Test_2.scala delete mode 100644 test/files/run/macro-declared-in-method.check delete mode 100644 test/files/run/macro-declared-in-method.flags delete mode 100644 test/files/run/macro-declared-in-method/Impls_1.scala delete mode 100644 test/files/run/macro-declared-in-method/Macros_Test_2.scala delete mode 100644 test/files/run/macro-declared-in-object-class.check delete mode 100644 test/files/run/macro-declared-in-object-class.flags delete mode 100644 test/files/run/macro-declared-in-object-class/Impls_1.scala delete mode 100644 test/files/run/macro-declared-in-object-class/Macros_Test_2.scala delete mode 100644 test/files/run/macro-declared-in-object-object.check delete mode 100644 test/files/run/macro-declared-in-object-object.flags delete mode 100644 test/files/run/macro-declared-in-object-object/Impls_1.scala delete mode 100644 test/files/run/macro-declared-in-object-object/Macros_Test_2.scala delete mode 100644 test/files/run/macro-declared-in-object.check delete mode 100644 test/files/run/macro-declared-in-object.flags delete mode 100644 test/files/run/macro-declared-in-object/Impls_1.scala delete mode 100644 test/files/run/macro-declared-in-object/Macros_Test_2.scala delete mode 100644 test/files/run/macro-declared-in-package-object.check delete mode 100644 test/files/run/macro-declared-in-package-object.flags delete mode 100644 test/files/run/macro-declared-in-package-object/Impls_1.scala delete mode 100644 test/files/run/macro-declared-in-package-object/Macros_Test_2.scala delete mode 100644 test/files/run/macro-declared-in-refinement.check delete mode 100644 test/files/run/macro-declared-in-refinement.flags delete mode 100644 test/files/run/macro-declared-in-refinement/Impls_1.scala delete mode 100644 test/files/run/macro-declared-in-refinement/Macros_Test_2.scala delete mode 100644 test/files/run/macro-declared-in-trait.check delete mode 100644 test/files/run/macro-declared-in-trait.flags delete mode 100644 test/files/run/macro-declared-in-trait/Impls_1.scala delete mode 100644 test/files/run/macro-declared-in-trait/Macros_Test_2.scala delete mode 100644 test/files/run/macro-def-infer-return-type-a.check delete mode 100644 test/files/run/macro-def-infer-return-type-a.flags delete mode 100644 test/files/run/macro-def-infer-return-type-a/Impls_1.scala delete mode 100644 test/files/run/macro-def-infer-return-type-a/Macros_Test_2.scala delete mode 100644 test/files/run/macro-def-infer-return-type-b.check delete mode 100644 test/files/run/macro-def-infer-return-type-b.flags delete mode 100644 test/files/run/macro-def-infer-return-type-b/Impls_Macros_1.scala delete mode 100644 test/files/run/macro-def-infer-return-type-b/Test_2.scala delete mode 100644 test/files/run/macro-def-infer-return-type-c.check delete mode 100644 test/files/run/macro-def-infer-return-type-c.flags delete mode 100644 test/files/run/macro-def-infer-return-type-c/Impls_1.scala delete mode 100644 test/files/run/macro-def-infer-return-type-c/Macros_Test_2.scala create mode 100644 test/files/run/macro-def-infer-return-type.check create mode 100644 test/files/run/macro-def-infer-return-type.flags create mode 100644 test/files/run/macro-def-infer-return-type/Impls_1.scala create mode 100644 test/files/run/macro-def-infer-return-type/Macros_Test_2.scala delete mode 100644 test/files/run/macro-def-path-dependent-a.check delete mode 100644 test/files/run/macro-def-path-dependent-a.flags delete mode 100644 test/files/run/macro-def-path-dependent-a/Impls_Macros_1.scala delete mode 100644 test/files/run/macro-def-path-dependent-a/Test_2.scala delete mode 100644 test/files/run/macro-def-path-dependent-b.check delete mode 100644 test/files/run/macro-def-path-dependent-b.flags delete mode 100644 test/files/run/macro-def-path-dependent-b/Impls_Macros_1.scala delete mode 100644 test/files/run/macro-def-path-dependent-b/Test_2.scala delete mode 100644 test/files/run/macro-def-path-dependent-c.check delete mode 100644 test/files/run/macro-def-path-dependent-c.flags delete mode 100644 test/files/run/macro-def-path-dependent-c/Impls_Macros_1.scala delete mode 100644 test/files/run/macro-def-path-dependent-c/Test_2.scala delete mode 100644 test/files/run/macro-def-path-dependent-d1.check delete mode 100644 test/files/run/macro-def-path-dependent-d1.flags delete mode 100644 test/files/run/macro-def-path-dependent-d1/Impls_Macros_1.scala delete mode 100644 test/files/run/macro-def-path-dependent-d1/Test_2.scala delete mode 100644 test/files/run/macro-def-path-dependent-d2.check delete mode 100644 test/files/run/macro-def-path-dependent-d2.flags delete mode 100644 test/files/run/macro-def-path-dependent-d2/Impls_1.scala delete mode 100644 test/files/run/macro-def-path-dependent-d2/Macros_2.scala delete mode 100644 test/files/run/macro-def-path-dependent-d2/Test_3.scala create mode 100644 test/files/run/macro-def-path-dependent.check create mode 100644 test/files/run/macro-def-path-dependent.flags create mode 100644 test/files/run/macro-def-path-dependent/Dummy.scala create mode 100644 test/files/run/macro-def-path-dependent/Test_1.scala create mode 100644 test/files/run/macro-def-path-dependent/Test_2.scala create mode 100644 test/files/run/macro-def-path-dependent/Test_3.scala create mode 100644 test/files/run/macro-def-path-dependent/Test_4.scala create mode 100644 test/files/run/macro-def-path-dependent/Test_5.scala create mode 100644 test/files/run/macro-def-path-dependent/Test_6.scala delete mode 100644 test/files/run/macro-expand-tparams-bounds-a.check delete mode 100644 test/files/run/macro-expand-tparams-bounds-a.flags delete mode 100644 test/files/run/macro-expand-tparams-bounds-a/Impls_1.scala delete mode 100644 test/files/run/macro-expand-tparams-bounds-a/Macros_Test_2.scala delete mode 100644 test/files/run/macro-expand-tparams-bounds-b.check delete mode 100644 test/files/run/macro-expand-tparams-bounds-b.flags delete mode 100644 test/files/run/macro-expand-tparams-bounds-b/Impls_1.scala delete mode 100644 test/files/run/macro-expand-tparams-bounds-b/Macros_Test_2.scala create mode 100644 test/files/run/macro-expand-tparams-bounds.check create mode 100644 test/files/run/macro-expand-tparams-bounds.flags create mode 100644 test/files/run/macro-expand-tparams-bounds/Impls_1.scala create mode 100644 test/files/run/macro-expand-tparams-bounds/Macros_Test_2.scala delete mode 100644 test/files/run/macro-expand-tparams-only-in-impl.flags delete mode 100644 test/files/run/macro-expand-tparams-only-in-impl/Impls_1.scala delete mode 100644 test/files/run/macro-expand-tparams-only-in-impl/Macros_Test_2.scala delete mode 100644 test/files/run/macro-expand-tparams-optional.check delete mode 100644 test/files/run/macro-expand-tparams-optional.flags delete mode 100644 test/files/run/macro-expand-tparams-optional/Impls_1.scala delete mode 100644 test/files/run/macro-expand-tparams-optional/Macros_Test_2.scala delete mode 100644 test/files/run/macro-expand-tparams-prefix-a.check delete mode 100644 test/files/run/macro-expand-tparams-prefix-a.flags delete mode 100644 test/files/run/macro-expand-tparams-prefix-a/Impls_1.scala delete mode 100644 test/files/run/macro-expand-tparams-prefix-a/Macros_Test_2.scala delete mode 100644 test/files/run/macro-expand-tparams-prefix-b.check delete mode 100644 test/files/run/macro-expand-tparams-prefix-b.flags delete mode 100644 test/files/run/macro-expand-tparams-prefix-b/Impls_1.scala delete mode 100644 test/files/run/macro-expand-tparams-prefix-b/Macros_Test_2.scala delete mode 100644 test/files/run/macro-expand-tparams-prefix-c1.check delete mode 100644 test/files/run/macro-expand-tparams-prefix-c1.flags delete mode 100644 test/files/run/macro-expand-tparams-prefix-c1/Impls_1.scala delete mode 100644 test/files/run/macro-expand-tparams-prefix-c1/Macros_Test_2.scala delete mode 100644 test/files/run/macro-expand-tparams-prefix-c2.check delete mode 100644 test/files/run/macro-expand-tparams-prefix-c2.flags delete mode 100644 test/files/run/macro-expand-tparams-prefix-c2/Impls_Macros_1.scala delete mode 100644 test/files/run/macro-expand-tparams-prefix-c2/Test_2.scala delete mode 100644 test/files/run/macro-expand-tparams-prefix-d1.check delete mode 100644 test/files/run/macro-expand-tparams-prefix-d1.flags delete mode 100644 test/files/run/macro-expand-tparams-prefix-d1/Impls_1.scala delete mode 100644 test/files/run/macro-expand-tparams-prefix-d1/Macros_Test_2.scala create mode 100644 test/files/run/macro-expand-tparams-prefix.check create mode 100644 test/files/run/macro-expand-tparams-prefix.flags create mode 100644 test/files/run/macro-expand-tparams-prefix/Impls_1.scala create mode 100644 test/files/run/macro-expand-tparams-prefix/Macros_Test_2.scala create mode 100644 test/files/run/macro-impl-tparam-only-in-impl.flags create mode 100644 test/files/run/macro-impl-tparam-only-in-impl/Impls_1.scala create mode 100644 test/files/run/macro-impl-tparam-only-in-impl/Macros_Test_2.scala create mode 100644 test/files/run/macro-impl-tparam-typetag-is-optional.check create mode 100644 test/files/run/macro-impl-tparam-typetag-is-optional.flags create mode 100644 test/files/run/macro-impl-tparam-typetag-is-optional/Impls_1.scala create mode 100644 test/files/run/macro-impl-tparam-typetag-is-optional/Macros_Test_2.scala create mode 100644 test/files/run/macro-term-declared-in-annotation.check create mode 100644 test/files/run/macro-term-declared-in-annotation.flags create mode 100644 test/files/run/macro-term-declared-in-annotation/Impls_1.scala create mode 100644 test/files/run/macro-term-declared-in-annotation/Macros_2.scala create mode 100644 test/files/run/macro-term-declared-in-annotation/Test_3.scala create mode 100644 test/files/run/macro-term-declared-in-anonymous.check create mode 100644 test/files/run/macro-term-declared-in-anonymous.flags create mode 100644 test/files/run/macro-term-declared-in-anonymous/Impls_1.scala create mode 100644 test/files/run/macro-term-declared-in-anonymous/Macros_Test_2.scala create mode 100644 test/files/run/macro-term-declared-in-block.check create mode 100644 test/files/run/macro-term-declared-in-block.flags create mode 100644 test/files/run/macro-term-declared-in-block/Impls_1.scala create mode 100644 test/files/run/macro-term-declared-in-block/Macros_Test_2.scala create mode 100644 test/files/run/macro-term-declared-in-class-class.check create mode 100644 test/files/run/macro-term-declared-in-class-class.flags create mode 100644 test/files/run/macro-term-declared-in-class-class/Impls_1.scala create mode 100644 test/files/run/macro-term-declared-in-class-class/Macros_Test_2.scala create mode 100644 test/files/run/macro-term-declared-in-class-object.check create mode 100644 test/files/run/macro-term-declared-in-class-object.flags create mode 100644 test/files/run/macro-term-declared-in-class-object/Impls_1.scala create mode 100644 test/files/run/macro-term-declared-in-class-object/Macros_Test_2.scala create mode 100644 test/files/run/macro-term-declared-in-class.check create mode 100644 test/files/run/macro-term-declared-in-class.flags create mode 100644 test/files/run/macro-term-declared-in-class/Impls_1.scala create mode 100644 test/files/run/macro-term-declared-in-class/Macros_Test_2.scala create mode 100644 test/files/run/macro-term-declared-in-default-param.check create mode 100644 test/files/run/macro-term-declared-in-default-param.flags create mode 100644 test/files/run/macro-term-declared-in-default-param/Impls_1.scala create mode 100644 test/files/run/macro-term-declared-in-default-param/Macros_Test_2.scala create mode 100644 test/files/run/macro-term-declared-in-implicit-class.check create mode 100644 test/files/run/macro-term-declared-in-implicit-class.flags create mode 100644 test/files/run/macro-term-declared-in-implicit-class/Impls_Macros_1.scala create mode 100644 test/files/run/macro-term-declared-in-implicit-class/Test_2.scala create mode 100644 test/files/run/macro-term-declared-in-method.check create mode 100644 test/files/run/macro-term-declared-in-method.flags create mode 100644 test/files/run/macro-term-declared-in-method/Impls_1.scala create mode 100644 test/files/run/macro-term-declared-in-method/Macros_Test_2.scala create mode 100644 test/files/run/macro-term-declared-in-object-class.check create mode 100644 test/files/run/macro-term-declared-in-object-class.flags create mode 100644 test/files/run/macro-term-declared-in-object-class/Impls_1.scala create mode 100644 test/files/run/macro-term-declared-in-object-class/Macros_Test_2.scala create mode 100644 test/files/run/macro-term-declared-in-object-object.check create mode 100644 test/files/run/macro-term-declared-in-object-object.flags create mode 100644 test/files/run/macro-term-declared-in-object-object/Impls_1.scala create mode 100644 test/files/run/macro-term-declared-in-object-object/Macros_Test_2.scala create mode 100644 test/files/run/macro-term-declared-in-object.check create mode 100644 test/files/run/macro-term-declared-in-object.flags create mode 100644 test/files/run/macro-term-declared-in-object/Impls_1.scala create mode 100644 test/files/run/macro-term-declared-in-object/Macros_Test_2.scala create mode 100644 test/files/run/macro-term-declared-in-package-object.check create mode 100644 test/files/run/macro-term-declared-in-package-object.flags create mode 100644 test/files/run/macro-term-declared-in-package-object/Impls_1.scala create mode 100644 test/files/run/macro-term-declared-in-package-object/Macros_Test_2.scala create mode 100644 test/files/run/macro-term-declared-in-refinement.check create mode 100644 test/files/run/macro-term-declared-in-refinement.flags create mode 100644 test/files/run/macro-term-declared-in-refinement/Impls_1.scala create mode 100644 test/files/run/macro-term-declared-in-refinement/Macros_Test_2.scala create mode 100644 test/files/run/macro-term-declared-in-trait.check create mode 100644 test/files/run/macro-term-declared-in-trait.flags create mode 100644 test/files/run/macro-term-declared-in-trait/Impls_1.scala create mode 100644 test/files/run/macro-term-declared-in-trait/Macros_Test_2.scala create mode 100644 test/files/run/repl-term-macros.check create mode 100644 test/files/run/repl-term-macros.scala create mode 100644 test/pending/run/macro-term-declared-in-anonymous-explicit-import.check create mode 100644 test/pending/run/macro-term-declared-in-anonymous-explicit-import/Impls_1.scala create mode 100644 test/pending/run/macro-term-declared-in-anonymous-explicit-import/Macros_Test_2.scala diff --git a/test/files/neg/macro-invalidimpl-a.check b/test/files/neg/macro-invalidimpl-a.check deleted file mode 100644 index 7f11f3b865..0000000000 --- a/test/files/neg/macro-invalidimpl-a.check +++ /dev/null @@ -1,4 +0,0 @@ -Macros_Test_2.scala:3: error: macro implementation must be in statically accessible object - def foo(x: Any) = macro impls.foo - ^ -one error found diff --git a/test/files/neg/macro-invalidimpl-a.flags b/test/files/neg/macro-invalidimpl-a.flags deleted file mode 100644 index cd66464f2f..0000000000 --- a/test/files/neg/macro-invalidimpl-a.flags +++ /dev/null @@ -1 +0,0 @@ --language:experimental.macros \ No newline at end of file diff --git a/test/files/neg/macro-invalidimpl-a/Impls_1.scala b/test/files/neg/macro-invalidimpl-a/Impls_1.scala deleted file mode 100644 index cfa1218038..0000000000 --- a/test/files/neg/macro-invalidimpl-a/Impls_1.scala +++ /dev/null @@ -1,5 +0,0 @@ -import scala.reflect.macros.{Context => Ctx} - -class Impls { - def foo(c: Ctx)(x: c.Expr[Any]) = ??? -} diff --git a/test/files/neg/macro-invalidimpl-a/Macros_Test_2.scala b/test/files/neg/macro-invalidimpl-a/Macros_Test_2.scala deleted file mode 100644 index 2220ddae0c..0000000000 --- a/test/files/neg/macro-invalidimpl-a/Macros_Test_2.scala +++ /dev/null @@ -1,9 +0,0 @@ -object Macros { - val impls = new Impls - def foo(x: Any) = macro impls.foo -} - -object Test extends App { - import Macros._ - foo(42) -} \ No newline at end of file diff --git a/test/files/neg/macro-invalidimpl-b.check b/test/files/neg/macro-invalidimpl-b.check deleted file mode 100644 index 7f11f3b865..0000000000 --- a/test/files/neg/macro-invalidimpl-b.check +++ /dev/null @@ -1,4 +0,0 @@ -Macros_Test_2.scala:3: error: macro implementation must be in statically accessible object - def foo(x: Any) = macro impls.foo - ^ -one error found diff --git a/test/files/neg/macro-invalidimpl-b.flags b/test/files/neg/macro-invalidimpl-b.flags deleted file mode 100644 index cd66464f2f..0000000000 --- a/test/files/neg/macro-invalidimpl-b.flags +++ /dev/null @@ -1 +0,0 @@ --language:experimental.macros \ No newline at end of file diff --git a/test/files/neg/macro-invalidimpl-b/Impls_1.scala b/test/files/neg/macro-invalidimpl-b/Impls_1.scala deleted file mode 100644 index 4467021545..0000000000 --- a/test/files/neg/macro-invalidimpl-b/Impls_1.scala +++ /dev/null @@ -1,5 +0,0 @@ -import scala.reflect.macros.{Context => Ctx} - -object Impls { - def foo(c: Ctx)(x: c.Expr[Any]) = ??? -} diff --git a/test/files/neg/macro-invalidimpl-b/Macros_Test_2.scala b/test/files/neg/macro-invalidimpl-b/Macros_Test_2.scala deleted file mode 100644 index 81e40837d2..0000000000 --- a/test/files/neg/macro-invalidimpl-b/Macros_Test_2.scala +++ /dev/null @@ -1,9 +0,0 @@ -object Macros { - val impls = Impls - def foo(x: Any) = macro impls.foo -} - -object Test extends App { - import Macros._ - foo(42) -} \ No newline at end of file diff --git a/test/files/neg/macro-invalidimpl-c.check b/test/files/neg/macro-invalidimpl-c.check deleted file mode 100644 index 9e0181c0a3..0000000000 --- a/test/files/neg/macro-invalidimpl-c.check +++ /dev/null @@ -1,4 +0,0 @@ -Impls_Macros_1.scala:8: error: macro implementation must be in statically accessible object - def foo(x: Any) = macro Impls.foo - ^ -one error found diff --git a/test/files/neg/macro-invalidimpl-c.flags b/test/files/neg/macro-invalidimpl-c.flags deleted file mode 100644 index cd66464f2f..0000000000 --- a/test/files/neg/macro-invalidimpl-c.flags +++ /dev/null @@ -1 +0,0 @@ --language:experimental.macros \ No newline at end of file diff --git a/test/files/neg/macro-invalidimpl-c/Impls_Macros_1.scala b/test/files/neg/macro-invalidimpl-c/Impls_Macros_1.scala deleted file mode 100644 index 67a0eb348b..0000000000 --- a/test/files/neg/macro-invalidimpl-c/Impls_Macros_1.scala +++ /dev/null @@ -1,9 +0,0 @@ -import scala.reflect.macros.{Context => Ctx} - -class Macros { - object Impls { - def foo(c: Ctx)(x: c.Expr[Any]) = ??? - } - - def foo(x: Any) = macro Impls.foo -} \ No newline at end of file diff --git a/test/files/neg/macro-invalidimpl-c/Test_2.scala b/test/files/neg/macro-invalidimpl-c/Test_2.scala deleted file mode 100644 index e75a8ba101..0000000000 --- a/test/files/neg/macro-invalidimpl-c/Test_2.scala +++ /dev/null @@ -1,3 +0,0 @@ -object Test extends App { - new Macros().foo(42) -} \ No newline at end of file diff --git a/test/files/neg/macro-invalidimpl-d.check b/test/files/neg/macro-invalidimpl-d.check deleted file mode 100644 index 76a5ba9c8c..0000000000 --- a/test/files/neg/macro-invalidimpl-d.check +++ /dev/null @@ -1,4 +0,0 @@ -Macros_Test_2.scala:2: error: macro implementation must be in statically accessible object - def foo(x: Any) = macro Impls.foo - ^ -one error found diff --git a/test/files/neg/macro-invalidimpl-d.flags b/test/files/neg/macro-invalidimpl-d.flags deleted file mode 100644 index cd66464f2f..0000000000 --- a/test/files/neg/macro-invalidimpl-d.flags +++ /dev/null @@ -1 +0,0 @@ --language:experimental.macros \ No newline at end of file diff --git a/test/files/neg/macro-invalidimpl-d/Impls_1.scala b/test/files/neg/macro-invalidimpl-d/Impls_1.scala deleted file mode 100644 index e0819c938c..0000000000 --- a/test/files/neg/macro-invalidimpl-d/Impls_1.scala +++ /dev/null @@ -1,7 +0,0 @@ -import scala.reflect.macros.{Context => Ctx} - -trait MacroHelpers { - object Impls { - def foo(c: Ctx)(x: c.Expr[Any]) = x - } -} \ No newline at end of file diff --git a/test/files/neg/macro-invalidimpl-d/Macros_Test_2.scala b/test/files/neg/macro-invalidimpl-d/Macros_Test_2.scala deleted file mode 100644 index 067ab1ddec..0000000000 --- a/test/files/neg/macro-invalidimpl-d/Macros_Test_2.scala +++ /dev/null @@ -1,7 +0,0 @@ -class Macros extends MacroHelpers { - def foo(x: Any) = macro Impls.foo -} - -object Test extends App { - println(new Macros().foo(42)) -} \ No newline at end of file diff --git a/test/files/neg/macro-invalidimpl-e.check b/test/files/neg/macro-invalidimpl-e.check deleted file mode 100644 index e0910b2899..0000000000 --- a/test/files/neg/macro-invalidimpl-e.check +++ /dev/null @@ -1,13 +0,0 @@ -Macros_Test_2.scala:2: error: ambiguous reference to overloaded definition, -both method foo in object Impls of type (c: scala.reflect.macros.Context)(x: c.Expr[Any], y: c.Expr[Any])Nothing -and method foo in object Impls of type (c: scala.reflect.macros.Context)(x: c.Expr[Any])Nothing -match expected type ? - def foo(x: Any) = macro Impls.foo - ^ -Macros_Test_2.scala:3: error: ambiguous reference to overloaded definition, -both method foo in object Impls of type (c: scala.reflect.macros.Context)(x: c.Expr[Any], y: c.Expr[Any])Nothing -and method foo in object Impls of type (c: scala.reflect.macros.Context)(x: c.Expr[Any])Nothing -match expected type ? - def foo(x: Any, y: Any) = macro Impls.foo - ^ -two errors found diff --git a/test/files/neg/macro-invalidimpl-e.flags b/test/files/neg/macro-invalidimpl-e.flags deleted file mode 100644 index cd66464f2f..0000000000 --- a/test/files/neg/macro-invalidimpl-e.flags +++ /dev/null @@ -1 +0,0 @@ --language:experimental.macros \ No newline at end of file diff --git a/test/files/neg/macro-invalidimpl-e/Impls_1.scala b/test/files/neg/macro-invalidimpl-e/Impls_1.scala deleted file mode 100644 index fd40119c31..0000000000 --- a/test/files/neg/macro-invalidimpl-e/Impls_1.scala +++ /dev/null @@ -1,6 +0,0 @@ -import scala.reflect.macros.{Context => Ctx} - -object Impls { - def foo(c: Ctx)(x: c.Expr[Any]) = ??? - def foo(c: Ctx)(x: c.Expr[Any], y: c.Expr[Any]) = ??? -} diff --git a/test/files/neg/macro-invalidimpl-e/Macros_Test_2.scala b/test/files/neg/macro-invalidimpl-e/Macros_Test_2.scala deleted file mode 100644 index 6edde08167..0000000000 --- a/test/files/neg/macro-invalidimpl-e/Macros_Test_2.scala +++ /dev/null @@ -1,9 +0,0 @@ -object Macros { - def foo(x: Any) = macro Impls.foo - def foo(x: Any, y: Any) = macro Impls.foo -} - -object Test extends App { - import Macros._ - foo(42) -} \ No newline at end of file diff --git a/test/files/neg/macro-invalidimpl-f.check b/test/files/neg/macro-invalidimpl-f.check deleted file mode 100644 index 4e5851f566..0000000000 --- a/test/files/neg/macro-invalidimpl-f.check +++ /dev/null @@ -1,7 +0,0 @@ -Macros_Test_2.scala:2: error: macro implementation has wrong shape: - required: (c: scala.reflect.macros.Context)(): c.Expr[Unit] - found : (c: scala.reflect.macros.Context): c.Expr[Unit] -number of parameter sections differ - def bar1() = macro Impls.fooNullary - ^ -one error found diff --git a/test/files/neg/macro-invalidimpl-f.flags b/test/files/neg/macro-invalidimpl-f.flags deleted file mode 100644 index cd66464f2f..0000000000 --- a/test/files/neg/macro-invalidimpl-f.flags +++ /dev/null @@ -1 +0,0 @@ --language:experimental.macros \ No newline at end of file diff --git a/test/files/neg/macro-invalidimpl-f/Impls_1.scala b/test/files/neg/macro-invalidimpl-f/Impls_1.scala deleted file mode 100644 index 0e4da86d22..0000000000 --- a/test/files/neg/macro-invalidimpl-f/Impls_1.scala +++ /dev/null @@ -1,11 +0,0 @@ -import scala.reflect.macros.{Context => Ctx} - -object Impls { - def fooNullary(c: Ctx) = { - import c.universe._ - val body = Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant("it works")))) - c.Expr[Unit](body) - } - - def fooEmpty(c: Ctx)() = fooNullary(c) -} \ No newline at end of file diff --git a/test/files/neg/macro-invalidimpl-f/Macros_Test_2.scala b/test/files/neg/macro-invalidimpl-f/Macros_Test_2.scala deleted file mode 100644 index 493edf1df8..0000000000 --- a/test/files/neg/macro-invalidimpl-f/Macros_Test_2.scala +++ /dev/null @@ -1,9 +0,0 @@ -object Macros { - def bar1() = macro Impls.fooNullary -} - -object Test extends App { - Macros.bar1 - Macros.bar1() - println("kkthxbai") -} \ No newline at end of file diff --git a/test/files/neg/macro-invalidimpl-g.check b/test/files/neg/macro-invalidimpl-g.check deleted file mode 100644 index 7342f7336f..0000000000 --- a/test/files/neg/macro-invalidimpl-g.check +++ /dev/null @@ -1,7 +0,0 @@ -Macros_Test_2.scala:2: error: macro implementation has wrong shape: - required: (c: scala.reflect.macros.Context): c.Expr[Unit] - found : (c: scala.reflect.macros.Context)(): c.Expr[Unit] -number of parameter sections differ - def foo1 = macro Impls.fooEmpty - ^ -one error found diff --git a/test/files/neg/macro-invalidimpl-g.flags b/test/files/neg/macro-invalidimpl-g.flags deleted file mode 100644 index cd66464f2f..0000000000 --- a/test/files/neg/macro-invalidimpl-g.flags +++ /dev/null @@ -1 +0,0 @@ --language:experimental.macros \ No newline at end of file diff --git a/test/files/neg/macro-invalidimpl-g/Impls_1.scala b/test/files/neg/macro-invalidimpl-g/Impls_1.scala deleted file mode 100644 index 0e4da86d22..0000000000 --- a/test/files/neg/macro-invalidimpl-g/Impls_1.scala +++ /dev/null @@ -1,11 +0,0 @@ -import scala.reflect.macros.{Context => Ctx} - -object Impls { - def fooNullary(c: Ctx) = { - import c.universe._ - val body = Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant("it works")))) - c.Expr[Unit](body) - } - - def fooEmpty(c: Ctx)() = fooNullary(c) -} \ No newline at end of file diff --git a/test/files/neg/macro-invalidimpl-g/Macros_Test_2.scala b/test/files/neg/macro-invalidimpl-g/Macros_Test_2.scala deleted file mode 100644 index 5561db9f9a..0000000000 --- a/test/files/neg/macro-invalidimpl-g/Macros_Test_2.scala +++ /dev/null @@ -1,8 +0,0 @@ -object Macros { - def foo1 = macro Impls.fooEmpty -} - -object Test extends App { - Macros.foo1 - println("kkthxbai") -} \ No newline at end of file diff --git a/test/files/neg/macro-invalidimpl-h.check b/test/files/neg/macro-invalidimpl-h.check deleted file mode 100644 index ea76e1aeac..0000000000 --- a/test/files/neg/macro-invalidimpl-h.check +++ /dev/null @@ -1,4 +0,0 @@ -Macros_Test_2.scala:2: error: type arguments [String] do not conform to method foo's type parameter bounds [U <: Int] - def foo = macro Impls.foo[String] - ^ -one error found diff --git a/test/files/neg/macro-invalidimpl-h.flags b/test/files/neg/macro-invalidimpl-h.flags deleted file mode 100644 index cd66464f2f..0000000000 --- a/test/files/neg/macro-invalidimpl-h.flags +++ /dev/null @@ -1 +0,0 @@ --language:experimental.macros \ No newline at end of file diff --git a/test/files/neg/macro-invalidimpl-h/Impls_1.scala b/test/files/neg/macro-invalidimpl-h/Impls_1.scala deleted file mode 100644 index 427fd3d5c0..0000000000 --- a/test/files/neg/macro-invalidimpl-h/Impls_1.scala +++ /dev/null @@ -1,5 +0,0 @@ -import scala.reflect.macros.{Context => Ctx} - -object Impls { - def foo[U <: Int](c: Ctx) = ??? -} diff --git a/test/files/neg/macro-invalidimpl-h/Macros_Test_2.scala b/test/files/neg/macro-invalidimpl-h/Macros_Test_2.scala deleted file mode 100644 index 218c7aec7f..0000000000 --- a/test/files/neg/macro-invalidimpl-h/Macros_Test_2.scala +++ /dev/null @@ -1,8 +0,0 @@ -object Macros { - def foo = macro Impls.foo[String] -} - -object Test extends App { - import Macros._ - foo -} \ No newline at end of file diff --git a/test/files/neg/macro-invalidimpl-i.check b/test/files/neg/macro-invalidimpl-i.check deleted file mode 100644 index 846ed8d134..0000000000 --- a/test/files/neg/macro-invalidimpl-i.check +++ /dev/null @@ -1,4 +0,0 @@ -Macros_Test_2.scala:4: error: macro implementation must be public - def foo = macro Impls.impl - ^ -one error found diff --git a/test/files/neg/macro-invalidimpl-i.flags b/test/files/neg/macro-invalidimpl-i.flags deleted file mode 100644 index cd66464f2f..0000000000 --- a/test/files/neg/macro-invalidimpl-i.flags +++ /dev/null @@ -1 +0,0 @@ --language:experimental.macros \ No newline at end of file diff --git a/test/files/neg/macro-invalidimpl-i/Impls_1.scala b/test/files/neg/macro-invalidimpl-i/Impls_1.scala deleted file mode 100644 index c35d8ab3c1..0000000000 --- a/test/files/neg/macro-invalidimpl-i/Impls_1.scala +++ /dev/null @@ -1,7 +0,0 @@ -package foo - -import scala.reflect.macros.Context - -object Impls { - private[foo] def impl(c: Context) = ??? -} \ No newline at end of file diff --git a/test/files/neg/macro-invalidimpl-i/Macros_Test_2.scala b/test/files/neg/macro-invalidimpl-i/Macros_Test_2.scala deleted file mode 100644 index fb129c70be..0000000000 --- a/test/files/neg/macro-invalidimpl-i/Macros_Test_2.scala +++ /dev/null @@ -1,5 +0,0 @@ -package foo - -object Test extends App { - def foo = macro Impls.impl -} diff --git a/test/files/neg/macro-invalidimpl.check b/test/files/neg/macro-invalidimpl.check new file mode 100644 index 0000000000..7177a8cdee --- /dev/null +++ b/test/files/neg/macro-invalidimpl.check @@ -0,0 +1,43 @@ +Macros_Test_2.scala:5: error: macro implementation must be in statically accessible object + def foo(x: Any) = macro impls.foo + ^ +Macros_Test_2.scala:10: error: macro implementation must be in statically accessible object + def foo(x: Any) = macro impls.foo + ^ +Macros_Test_2.scala:18: error: macro implementation must be in statically accessible object + def foo(x: Any) = macro Impls3.foo + ^ +Macros_Test_2.scala:22: error: macro implementation must be in statically accessible object + def foo(x: Any) = macro Impls4.foo + ^ +Macros_Test_2.scala:26: error: ambiguous reference to overloaded definition, +both method foo in object Impls5 of type (c: scala.reflect.macros.Context)(x: c.Expr[Any], y: c.Expr[Any])Nothing +and method foo in object Impls5 of type (c: scala.reflect.macros.Context)(x: c.Expr[Any])Nothing +match expected type ? + def foo(x: Any) = macro Impls5.foo + ^ +Macros_Test_2.scala:27: error: ambiguous reference to overloaded definition, +both method foo in object Impls5 of type (c: scala.reflect.macros.Context)(x: c.Expr[Any], y: c.Expr[Any])Nothing +and method foo in object Impls5 of type (c: scala.reflect.macros.Context)(x: c.Expr[Any])Nothing +match expected type ? + def foo(x: Any, y: Any) = macro Impls5.foo + ^ +Macros_Test_2.scala:31: error: macro implementation has wrong shape: + required: (c: scala.reflect.macros.Context): c.Expr[Unit] + found : (c: scala.reflect.macros.Context)(): c.Expr[Unit] +number of parameter sections differ + def foo1 = macro Impls6.fooEmpty + ^ +Macros_Test_2.scala:32: error: macro implementation has wrong shape: + required: (c: scala.reflect.macros.Context)(): c.Expr[Unit] + found : (c: scala.reflect.macros.Context): c.Expr[Unit] +number of parameter sections differ + def bar1() = macro Impls6.fooNullary + ^ +Macros_Test_2.scala:36: error: type arguments [String] do not conform to method foo's type parameter bounds [U <: Int] + def foo = macro Impls7.foo[String] + ^ +Macros_Test_2.scala:53: error: macro implementation must be public + def foo = macro Impls8.impl + ^ +10 errors found diff --git a/test/files/neg/macro-invalidimpl.flags b/test/files/neg/macro-invalidimpl.flags new file mode 100644 index 0000000000..cd66464f2f --- /dev/null +++ b/test/files/neg/macro-invalidimpl.flags @@ -0,0 +1 @@ +-language:experimental.macros \ No newline at end of file diff --git a/test/files/neg/macro-invalidimpl/Impls_1.scala b/test/files/neg/macro-invalidimpl/Impls_1.scala new file mode 100644 index 0000000000..cf78ecc65a --- /dev/null +++ b/test/files/neg/macro-invalidimpl/Impls_1.scala @@ -0,0 +1,40 @@ +import scala.reflect.macros.Context + +class Impls1 { + def foo(c: Context)(x: c.Expr[Any]) = ??? +} + +object Impls2 { + def foo(c: Context)(x: c.Expr[Any]) = ??? +} + +trait MacroHelpers { + object Impls4 { + def foo(c: Context)(x: c.Expr[Any]) = x + } +} + +object Impls5 { + def foo(c: Context)(x: c.Expr[Any]) = ??? + def foo(c: Context)(x: c.Expr[Any], y: c.Expr[Any]) = ??? +} + +object Impls6 { + def fooNullary(c: Context) = { + import c.universe._ + val body = Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant("it works")))) + c.Expr[Unit](body) + } + + def fooEmpty(c: Context)() = fooNullary(c) +} + +object Impls7 { + def foo[U <: Int](c: Context) = ??? +} + +package foo { + object Impls8 { + private[foo] def impl(c: Context) = ??? + } +} \ No newline at end of file diff --git a/test/files/neg/macro-invalidimpl/Macros_Test_2.scala b/test/files/neg/macro-invalidimpl/Macros_Test_2.scala new file mode 100644 index 0000000000..8aae9553f5 --- /dev/null +++ b/test/files/neg/macro-invalidimpl/Macros_Test_2.scala @@ -0,0 +1,55 @@ +import scala.reflect.macros.Context + +object Macros1 { + val impls = new Impls1 + def foo(x: Any) = macro impls.foo +} + +object Macros2 { + val impls = Impls2 + def foo(x: Any) = macro impls.foo +} + +class Macros3 { + object Impls3 { + def foo(c: Context)(x: c.Expr[Any]) = ??? + } + + def foo(x: Any) = macro Impls3.foo +} + +class Macros4 extends MacroHelpers { + def foo(x: Any) = macro Impls4.foo +} + +object Macros5 { + def foo(x: Any) = macro Impls5.foo + def foo(x: Any, y: Any) = macro Impls5.foo +} + +object Macros6 { + def foo1 = macro Impls6.fooEmpty + def bar1() = macro Impls6.fooNullary +} + +object Macros7 { + def foo = macro Impls7.foo[String] +} + +object Test extends App { + println(Macros1.foo(42)) + println(Macros2.foo(42)) + println(new Macros3().foo(42)) + println(new Macros4().foo(42)) + println(Macros5.foo(42)) + println(Macros6.foo1) + println(Macros6.bar1) + println(Macros6.bar1()) + println(Macros7.foo) +} + +package foo { + object Test extends App { + def foo = macro Impls8.impl + } +} \ No newline at end of file diff --git a/test/files/neg/macro-invalidret-nontree.flags b/test/files/neg/macro-invalidret-nontree.flags deleted file mode 100644 index cd66464f2f..0000000000 --- a/test/files/neg/macro-invalidret-nontree.flags +++ /dev/null @@ -1 +0,0 @@ --language:experimental.macros \ No newline at end of file diff --git a/test/files/neg/macro-invalidret-nontree/Impls_1.scala b/test/files/neg/macro-invalidret-nontree/Impls_1.scala deleted file mode 100644 index ef19b1b405..0000000000 --- a/test/files/neg/macro-invalidret-nontree/Impls_1.scala +++ /dev/null @@ -1,5 +0,0 @@ -import scala.reflect.macros.{Context => Ctx} - -object Impls { - def foo(c: Ctx) = 2 -} diff --git a/test/files/neg/macro-invalidret-nontree/Macros_Test_2.scala b/test/files/neg/macro-invalidret-nontree/Macros_Test_2.scala deleted file mode 100644 index 96a8de2832..0000000000 --- a/test/files/neg/macro-invalidret-nontree/Macros_Test_2.scala +++ /dev/null @@ -1,8 +0,0 @@ -object Macros { - def foo = macro Impls.foo -} - -object Test extends App { - import Macros._ - foo -} \ No newline at end of file diff --git a/test/files/neg/macro-invalidret-nonuniversetree.flags b/test/files/neg/macro-invalidret-nonuniversetree.flags deleted file mode 100644 index cd66464f2f..0000000000 --- a/test/files/neg/macro-invalidret-nonuniversetree.flags +++ /dev/null @@ -1 +0,0 @@ --language:experimental.macros \ No newline at end of file diff --git a/test/files/neg/macro-invalidret-nonuniversetree/Impls_1.scala b/test/files/neg/macro-invalidret-nonuniversetree/Impls_1.scala deleted file mode 100644 index f98376a2ba..0000000000 --- a/test/files/neg/macro-invalidret-nonuniversetree/Impls_1.scala +++ /dev/null @@ -1,6 +0,0 @@ -import scala.reflect.macros.{Context => Ctx} -import scala.reflect.runtime.{universe => ru} - -object Impls { - def foo(c: Ctx) = ru.Literal(ru.Constant(42)) -} diff --git a/test/files/neg/macro-invalidret-nonuniversetree/Macros_Test_2.scala b/test/files/neg/macro-invalidret-nonuniversetree/Macros_Test_2.scala deleted file mode 100644 index 96a8de2832..0000000000 --- a/test/files/neg/macro-invalidret-nonuniversetree/Macros_Test_2.scala +++ /dev/null @@ -1,8 +0,0 @@ -object Macros { - def foo = macro Impls.foo -} - -object Test extends App { - import Macros._ - foo -} \ No newline at end of file diff --git a/test/files/neg/macro-invalidret.check b/test/files/neg/macro-invalidret.check new file mode 100644 index 0000000000..d6664e6882 --- /dev/null +++ b/test/files/neg/macro-invalidret.check @@ -0,0 +1,13 @@ +Macros_Test_2.scala:2: error: macro implementation has wrong shape: + required: (c: scala.reflect.macros.Context): c.Expr[Any] + found : (c: scala.reflect.macros.Context): Int +type mismatch for return type: Int does not conform to c.Expr[Any] + def foo1 = macro Impls.foo1 + ^ +Macros_Test_2.scala:3: error: macro implementation has wrong shape: + required: (c: scala.reflect.macros.Context): c.Expr[Any] + found : (c: scala.reflect.macros.Context): reflect.runtime.universe.Literal +type mismatch for return type: reflect.runtime.universe.Literal does not conform to c.Expr[Any] + def foo2 = macro Impls.foo2 + ^ +two errors found diff --git a/test/files/neg/macro-invalidret.flags b/test/files/neg/macro-invalidret.flags new file mode 100644 index 0000000000..cd66464f2f --- /dev/null +++ b/test/files/neg/macro-invalidret.flags @@ -0,0 +1 @@ +-language:experimental.macros \ No newline at end of file diff --git a/test/files/neg/macro-invalidret/Impls_1.scala b/test/files/neg/macro-invalidret/Impls_1.scala new file mode 100644 index 0000000000..a58af1a23c --- /dev/null +++ b/test/files/neg/macro-invalidret/Impls_1.scala @@ -0,0 +1,7 @@ +import scala.reflect.macros.Context +import scala.reflect.runtime.{universe => ru} + +object Impls { + def foo1(c: Context) = 2 + def foo2(c: Context) = ru.Literal(ru.Constant(42)) +} diff --git a/test/files/neg/macro-invalidret/Macros_Test_2.scala b/test/files/neg/macro-invalidret/Macros_Test_2.scala new file mode 100644 index 0000000000..f8880fa023 --- /dev/null +++ b/test/files/neg/macro-invalidret/Macros_Test_2.scala @@ -0,0 +1,10 @@ +object Macros { + def foo1 = macro Impls.foo1 + def foo2 = macro Impls.foo2 +} + +object Test extends App { + import Macros._ + foo1 + foo2 +} \ No newline at end of file diff --git a/test/files/neg/macro-invalidshape-a.check b/test/files/neg/macro-invalidshape-a.check deleted file mode 100644 index f38a90819e..0000000000 --- a/test/files/neg/macro-invalidshape-a.check +++ /dev/null @@ -1,5 +0,0 @@ -Macros_Test_2.scala:2: error: macro body has wrong shape: - required: macro [].[[]] - def foo(x: Any) = macro 2 - ^ -one error found diff --git a/test/files/neg/macro-invalidshape-a.flags b/test/files/neg/macro-invalidshape-a.flags deleted file mode 100644 index cd66464f2f..0000000000 --- a/test/files/neg/macro-invalidshape-a.flags +++ /dev/null @@ -1 +0,0 @@ --language:experimental.macros \ No newline at end of file diff --git a/test/files/neg/macro-invalidshape-a/Impls_1.scala b/test/files/neg/macro-invalidshape-a/Impls_1.scala deleted file mode 100644 index 4467021545..0000000000 --- a/test/files/neg/macro-invalidshape-a/Impls_1.scala +++ /dev/null @@ -1,5 +0,0 @@ -import scala.reflect.macros.{Context => Ctx} - -object Impls { - def foo(c: Ctx)(x: c.Expr[Any]) = ??? -} diff --git a/test/files/neg/macro-invalidshape-a/Macros_Test_2.scala b/test/files/neg/macro-invalidshape-a/Macros_Test_2.scala deleted file mode 100644 index ffff17d1e7..0000000000 --- a/test/files/neg/macro-invalidshape-a/Macros_Test_2.scala +++ /dev/null @@ -1,8 +0,0 @@ -object Macros { - def foo(x: Any) = macro 2 -} - -object Test extends App { - import Macros._ - foo(42) -} \ No newline at end of file diff --git a/test/files/neg/macro-invalidshape-b.check b/test/files/neg/macro-invalidshape-b.check deleted file mode 100644 index 976685c6bd..0000000000 --- a/test/files/neg/macro-invalidshape-b.check +++ /dev/null @@ -1,5 +0,0 @@ -Macros_Test_2.scala:2: error: macro body has wrong shape: - required: macro [].[[]] - def foo(x: Any) = macro Impls.foo(null)(null) - ^ -one error found diff --git a/test/files/neg/macro-invalidshape-b.flags b/test/files/neg/macro-invalidshape-b.flags deleted file mode 100644 index cd66464f2f..0000000000 --- a/test/files/neg/macro-invalidshape-b.flags +++ /dev/null @@ -1 +0,0 @@ --language:experimental.macros \ No newline at end of file diff --git a/test/files/neg/macro-invalidshape-b/Impls_1.scala b/test/files/neg/macro-invalidshape-b/Impls_1.scala deleted file mode 100644 index 4467021545..0000000000 --- a/test/files/neg/macro-invalidshape-b/Impls_1.scala +++ /dev/null @@ -1,5 +0,0 @@ -import scala.reflect.macros.{Context => Ctx} - -object Impls { - def foo(c: Ctx)(x: c.Expr[Any]) = ??? -} diff --git a/test/files/neg/macro-invalidshape-b/Macros_Test_2.scala b/test/files/neg/macro-invalidshape-b/Macros_Test_2.scala deleted file mode 100644 index b67cd32a6e..0000000000 --- a/test/files/neg/macro-invalidshape-b/Macros_Test_2.scala +++ /dev/null @@ -1,8 +0,0 @@ -object Macros { - def foo(x: Any) = macro Impls.foo(null)(null) -} - -object Test extends App { - import Macros._ - foo(42) -} \ No newline at end of file diff --git a/test/files/neg/macro-invalidshape-c.check b/test/files/neg/macro-invalidshape-c.check deleted file mode 100644 index 0b2e9cfe4f..0000000000 --- a/test/files/neg/macro-invalidshape-c.check +++ /dev/null @@ -1,9 +0,0 @@ -Macros_Test_2.scala:2: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses - def foo(x: Any) = macro {2; Impls.foo} - ^ -Macros_Test_2.scala:2: error: missing arguments for method foo in object Impls; -follow this method with `_' if you want to treat it as a partially applied function - def foo(x: Any) = macro {2; Impls.foo} - ^ -one warning found -one error found diff --git a/test/files/neg/macro-invalidshape-c.flags b/test/files/neg/macro-invalidshape-c.flags deleted file mode 100644 index cd66464f2f..0000000000 --- a/test/files/neg/macro-invalidshape-c.flags +++ /dev/null @@ -1 +0,0 @@ --language:experimental.macros \ No newline at end of file diff --git a/test/files/neg/macro-invalidshape-c/Impls_1.scala b/test/files/neg/macro-invalidshape-c/Impls_1.scala deleted file mode 100644 index 4467021545..0000000000 --- a/test/files/neg/macro-invalidshape-c/Impls_1.scala +++ /dev/null @@ -1,5 +0,0 @@ -import scala.reflect.macros.{Context => Ctx} - -object Impls { - def foo(c: Ctx)(x: c.Expr[Any]) = ??? -} diff --git a/test/files/neg/macro-invalidshape-c/Macros_Test_2.scala b/test/files/neg/macro-invalidshape-c/Macros_Test_2.scala deleted file mode 100644 index 552c3710c7..0000000000 --- a/test/files/neg/macro-invalidshape-c/Macros_Test_2.scala +++ /dev/null @@ -1,8 +0,0 @@ -object Macros { - def foo(x: Any) = macro {2; Impls.foo} -} - -object Test extends App { - import Macros._ - foo(42) -} \ No newline at end of file diff --git a/test/files/neg/macro-invalidshape-d.check b/test/files/neg/macro-invalidshape-d.check deleted file mode 100644 index e43a2ca0ab..0000000000 --- a/test/files/neg/macro-invalidshape-d.check +++ /dev/null @@ -1,8 +0,0 @@ -Macros_Test_2.scala:2: warning: macro is now a reserved word; usage as an identifier is deprecated - def foo(x: Any) = {2; macro Impls.foo} - ^ -Macros_Test_2.scala:2: error: ';' expected but '.' found. - def foo(x: Any) = {2; macro Impls.foo} - ^ -one warning found -one error found diff --git a/test/files/neg/macro-invalidshape-d.flags b/test/files/neg/macro-invalidshape-d.flags deleted file mode 100644 index 83b7265eb9..0000000000 --- a/test/files/neg/macro-invalidshape-d.flags +++ /dev/null @@ -1 +0,0 @@ --deprecation -language:experimental.macros diff --git a/test/files/neg/macro-invalidshape-d/Impls_1.scala b/test/files/neg/macro-invalidshape-d/Impls_1.scala deleted file mode 100644 index 4467021545..0000000000 --- a/test/files/neg/macro-invalidshape-d/Impls_1.scala +++ /dev/null @@ -1,5 +0,0 @@ -import scala.reflect.macros.{Context => Ctx} - -object Impls { - def foo(c: Ctx)(x: c.Expr[Any]) = ??? -} diff --git a/test/files/neg/macro-invalidshape-d/Macros_Test_2.scala b/test/files/neg/macro-invalidshape-d/Macros_Test_2.scala deleted file mode 100644 index bacd9a6e7c..0000000000 --- a/test/files/neg/macro-invalidshape-d/Macros_Test_2.scala +++ /dev/null @@ -1,8 +0,0 @@ -object Macros { - def foo(x: Any) = {2; macro Impls.foo} -} - -object Test extends App { - import Macros._ - foo(42) -} \ No newline at end of file diff --git a/test/files/neg/macro-invalidshape.check b/test/files/neg/macro-invalidshape.check new file mode 100644 index 0000000000..cefc95b763 --- /dev/null +++ b/test/files/neg/macro-invalidshape.check @@ -0,0 +1,17 @@ +Macros_Test_2.scala:2: error: macro body has wrong shape: + required: macro [].[[]] + def foo1(x: Any) = macro 2 + ^ +Macros_Test_2.scala:3: error: macro body has wrong shape: + required: macro [].[[]] + def foo2(x: Any) = macro Impls.foo(null)(null) + ^ +Macros_Test_2.scala:4: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses + def foo3(x: Any) = macro {2; Impls.foo} + ^ +Macros_Test_2.scala:4: error: missing arguments for method foo in object Impls; +follow this method with `_' if you want to treat it as a partially applied function + def foo3(x: Any) = macro {2; Impls.foo} + ^ +one warning found +three errors found diff --git a/test/files/neg/macro-invalidshape.flags b/test/files/neg/macro-invalidshape.flags new file mode 100644 index 0000000000..cd66464f2f --- /dev/null +++ b/test/files/neg/macro-invalidshape.flags @@ -0,0 +1 @@ +-language:experimental.macros \ No newline at end of file diff --git a/test/files/neg/macro-invalidshape/Impls_1.scala b/test/files/neg/macro-invalidshape/Impls_1.scala new file mode 100644 index 0000000000..4467021545 --- /dev/null +++ b/test/files/neg/macro-invalidshape/Impls_1.scala @@ -0,0 +1,5 @@ +import scala.reflect.macros.{Context => Ctx} + +object Impls { + def foo(c: Ctx)(x: c.Expr[Any]) = ??? +} diff --git a/test/files/neg/macro-invalidshape/Macros_Test_2.scala b/test/files/neg/macro-invalidshape/Macros_Test_2.scala new file mode 100644 index 0000000000..f39ad20c5d --- /dev/null +++ b/test/files/neg/macro-invalidshape/Macros_Test_2.scala @@ -0,0 +1,12 @@ +object Macros { + def foo1(x: Any) = macro 2 + def foo2(x: Any) = macro Impls.foo(null)(null) + def foo3(x: Any) = macro {2; Impls.foo} +} + +object Test extends App { + import Macros._ + foo1(42) + foo2(42) + foo3(42) +} \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-context-bounds/Impls_1.scala b/test/files/neg/macro-invalidsig-context-bounds/Impls_1.scala deleted file mode 100644 index c066c485b1..0000000000 --- a/test/files/neg/macro-invalidsig-context-bounds/Impls_1.scala +++ /dev/null @@ -1,9 +0,0 @@ -import scala.reflect.runtime.universe._ -import scala.reflect.macros.{Context => Ctx} - -object Impls { - def foo[U: c.WeakTypeTag: Numeric](c: Ctx) = { - import c.universe._ - Literal(Constant(42)) - } -} \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-context-bounds/Macros_Test_1.scala b/test/files/neg/macro-invalidsig-context-bounds/Macros_Test_1.scala deleted file mode 100644 index 5b4602f328..0000000000 --- a/test/files/neg/macro-invalidsig-context-bounds/Macros_Test_1.scala +++ /dev/null @@ -1,8 +0,0 @@ -object Macros { - def foo[U] = macro Impls.foo[U] -} - -object Test extends App { - import Macros._ - println(foo[String]) -} \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-ctx-badargc/Impls_1.scala b/test/files/neg/macro-invalidsig-ctx-badargc/Impls_1.scala deleted file mode 100644 index 4d5d29158f..0000000000 --- a/test/files/neg/macro-invalidsig-ctx-badargc/Impls_1.scala +++ /dev/null @@ -1,3 +0,0 @@ -object Impls { - def foo = ??? -} diff --git a/test/files/neg/macro-invalidsig-ctx-badargc/Macros_Test_2.scala b/test/files/neg/macro-invalidsig-ctx-badargc/Macros_Test_2.scala deleted file mode 100644 index 96a8de2832..0000000000 --- a/test/files/neg/macro-invalidsig-ctx-badargc/Macros_Test_2.scala +++ /dev/null @@ -1,8 +0,0 @@ -object Macros { - def foo = macro Impls.foo -} - -object Test extends App { - import Macros._ - foo -} \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-ctx-badtype/Impls_1.scala b/test/files/neg/macro-invalidsig-ctx-badtype/Impls_1.scala deleted file mode 100644 index cf1a4cf85c..0000000000 --- a/test/files/neg/macro-invalidsig-ctx-badtype/Impls_1.scala +++ /dev/null @@ -1,5 +0,0 @@ -import scala.reflect.api.{Universe => Ctx} - -object Impls { - def foo(c: Ctx) = ??? -} diff --git a/test/files/neg/macro-invalidsig-ctx-badtype/Macros_Test_2.scala b/test/files/neg/macro-invalidsig-ctx-badtype/Macros_Test_2.scala deleted file mode 100644 index 96a8de2832..0000000000 --- a/test/files/neg/macro-invalidsig-ctx-badtype/Macros_Test_2.scala +++ /dev/null @@ -1,8 +0,0 @@ -object Macros { - def foo = macro Impls.foo -} - -object Test extends App { - import Macros._ - foo -} \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-ctx-badvarargs/Impls_1.scala b/test/files/neg/macro-invalidsig-ctx-badvarargs/Impls_1.scala deleted file mode 100644 index c4ed8be91e..0000000000 --- a/test/files/neg/macro-invalidsig-ctx-badvarargs/Impls_1.scala +++ /dev/null @@ -1,5 +0,0 @@ -import scala.reflect.macros.{Context => Ctx} - -object Impls { - def foo(cs: Ctx*) = ??? -} diff --git a/test/files/neg/macro-invalidsig-ctx-badvarargs/Macros_Test_2.scala b/test/files/neg/macro-invalidsig-ctx-badvarargs/Macros_Test_2.scala deleted file mode 100644 index 96a8de2832..0000000000 --- a/test/files/neg/macro-invalidsig-ctx-badvarargs/Macros_Test_2.scala +++ /dev/null @@ -1,8 +0,0 @@ -object Macros { - def foo = macro Impls.foo -} - -object Test extends App { - import Macros._ - foo -} \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-ctx-noctx/Impls_1.scala b/test/files/neg/macro-invalidsig-ctx-noctx/Impls_1.scala deleted file mode 100644 index 6904cfb1dc..0000000000 --- a/test/files/neg/macro-invalidsig-ctx-noctx/Impls_1.scala +++ /dev/null @@ -1,5 +0,0 @@ -import scala.reflect.macros.{Context => Ctx} - -object Impls { - def foo(c: Ctx) = ??? -} diff --git a/test/files/neg/macro-invalidsig-ctx-noctx/Macros_Test_2.scala b/test/files/neg/macro-invalidsig-ctx-noctx/Macros_Test_2.scala deleted file mode 100644 index e053cf99df..0000000000 --- a/test/files/neg/macro-invalidsig-ctx-noctx/Macros_Test_2.scala +++ /dev/null @@ -1,8 +0,0 @@ -object Macros { - def foo(x: Any) = macro Impls.foo -} - -object Test extends App { - import Macros._ - foo(42) -} \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-implicit-params/Impls_Macros_1.scala b/test/files/neg/macro-invalidsig-implicit-params/Impls_Macros_1.scala deleted file mode 100644 index 8205694768..0000000000 --- a/test/files/neg/macro-invalidsig-implicit-params/Impls_Macros_1.scala +++ /dev/null @@ -1,19 +0,0 @@ -import scala.reflect.runtime.universe._ -import scala.reflect.macros.{Context => Ctx} - -object Impls { - def foo_targs[T, U: c.WeakTypeTag](c: Ctx)(implicit x: c.Expr[Int]) = { - import c.{prefix => prefix} - import c.universe._ - val body = Block(List( - Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant("invoking foo_targs...")))), - Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant("type of prefix is: " + prefix.staticType)))), - Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant("U is: " + implicitly[c.WeakTypeTag[U]].tpe))))), - Literal(Constant(()))) - c.Expr[Unit](body) - } -} - -class Macros[T] { - def foo_targs[U](x: Int) = macro Impls.foo_targs[T, U] -} \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-implicit-params/Test_2.scala b/test/files/neg/macro-invalidsig-implicit-params/Test_2.scala deleted file mode 100644 index 90e850df21..0000000000 --- a/test/files/neg/macro-invalidsig-implicit-params/Test_2.scala +++ /dev/null @@ -1,4 +0,0 @@ -object Test extends App { - println("foo_targs:") - new Macros[Int]().foo_targs[String](42) -} \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-params-badargc/Impls_Macros_1.scala b/test/files/neg/macro-invalidsig-params-badargc/Impls_Macros_1.scala deleted file mode 100644 index ae16612b93..0000000000 --- a/test/files/neg/macro-invalidsig-params-badargc/Impls_Macros_1.scala +++ /dev/null @@ -1,9 +0,0 @@ -import scala.reflect.macros.{Context => Ctx} - -object Impls { - def foo(c: Ctx)(x: c.Expr[Int], y: c.Expr[Int]) = ??? -} - -object Macros { - def foo(x: Int) = macro Impls.foo -} diff --git a/test/files/neg/macro-invalidsig-params-badargc/Test_2.scala b/test/files/neg/macro-invalidsig-params-badargc/Test_2.scala deleted file mode 100644 index cbd6232073..0000000000 --- a/test/files/neg/macro-invalidsig-params-badargc/Test_2.scala +++ /dev/null @@ -1,4 +0,0 @@ -object Test extends App { - import Macros._ - foo(42) -} \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-params-badtype/Test_2.scala b/test/files/neg/macro-invalidsig-params-badtype/Test_2.scala deleted file mode 100644 index cbd6232073..0000000000 --- a/test/files/neg/macro-invalidsig-params-badtype/Test_2.scala +++ /dev/null @@ -1,4 +0,0 @@ -object Test extends App { - import Macros._ - foo(42) -} \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-params-badvarargs/Impls_Macros_1.scala b/test/files/neg/macro-invalidsig-params-badvarargs/Impls_Macros_1.scala deleted file mode 100644 index b4c75ad0ba..0000000000 --- a/test/files/neg/macro-invalidsig-params-badvarargs/Impls_Macros_1.scala +++ /dev/null @@ -1,9 +0,0 @@ -import scala.reflect.macros.{Context => Ctx} - -object Impls { - def foo(c: Ctx)(xs: c.Expr[Int]*) = ??? -} - -object Macros { - def foo(x: Int, y: Int) = macro Impls.foo -} diff --git a/test/files/neg/macro-invalidsig-params-badvarargs/Test_2.scala b/test/files/neg/macro-invalidsig-params-badvarargs/Test_2.scala deleted file mode 100644 index fa50ac4f73..0000000000 --- a/test/files/neg/macro-invalidsig-params-badvarargs/Test_2.scala +++ /dev/null @@ -1,4 +0,0 @@ -object Test extends App { - import Macros._ - foo(42, 100) -} \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-params-namemismatch/Impls_Macros_1.scala b/test/files/neg/macro-invalidsig-params-namemismatch/Impls_Macros_1.scala deleted file mode 100644 index c7cf0b06c4..0000000000 --- a/test/files/neg/macro-invalidsig-params-namemismatch/Impls_Macros_1.scala +++ /dev/null @@ -1,9 +0,0 @@ -import scala.reflect.macros.{Context => Ctx} - -object Impls { - def foo(c: Ctx)(y: c.Expr[Int], x: c.Expr[Int]) = ??? -} - -object Macros { - def foo(x: Int, y: Int) = macro Impls.foo -} diff --git a/test/files/neg/macro-invalidsig-params-namemismatch/Test_2.scala b/test/files/neg/macro-invalidsig-params-namemismatch/Test_2.scala deleted file mode 100644 index fa50ac4f73..0000000000 --- a/test/files/neg/macro-invalidsig-params-namemismatch/Test_2.scala +++ /dev/null @@ -1,4 +0,0 @@ -object Test extends App { - import Macros._ - foo(42, 100) -} \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-tparams-badtype/Impls_1.scala b/test/files/neg/macro-invalidsig-tparams-badtype/Impls_1.scala deleted file mode 100644 index dbeca178a7..0000000000 --- a/test/files/neg/macro-invalidsig-tparams-badtype/Impls_1.scala +++ /dev/null @@ -1,5 +0,0 @@ -import scala.reflect.macros.{Context => Ctx} - -object Impls { - def foo[U](c: Ctx)(U: c.universe.Type) = ??? -} diff --git a/test/files/neg/macro-invalidsig-tparams-badtype/Macros_Test_2.scala b/test/files/neg/macro-invalidsig-tparams-badtype/Macros_Test_2.scala deleted file mode 100644 index a82e813221..0000000000 --- a/test/files/neg/macro-invalidsig-tparams-badtype/Macros_Test_2.scala +++ /dev/null @@ -1,8 +0,0 @@ -object Macros { - def foo[U] = macro Impls.foo[U] -} - -object Test extends App { - import Macros._ - foo[Int] -} \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-tparams-bounds-a/Impls_1.scala b/test/files/neg/macro-invalidsig-tparams-bounds-a/Impls_1.scala deleted file mode 100644 index 89020de7dd..0000000000 --- a/test/files/neg/macro-invalidsig-tparams-bounds-a/Impls_1.scala +++ /dev/null @@ -1,5 +0,0 @@ -import scala.reflect.macros.{Context => Ctx} - -object Impls { - def foo[U <: String](c: Ctx) = ??? -} diff --git a/test/files/neg/macro-invalidsig-tparams-bounds-a/Macros_Test_2.scala b/test/files/neg/macro-invalidsig-tparams-bounds-a/Macros_Test_2.scala deleted file mode 100644 index a82e813221..0000000000 --- a/test/files/neg/macro-invalidsig-tparams-bounds-a/Macros_Test_2.scala +++ /dev/null @@ -1,8 +0,0 @@ -object Macros { - def foo[U] = macro Impls.foo[U] -} - -object Test extends App { - import Macros._ - foo[Int] -} \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-tparams-bounds-b/Impls_1.scala b/test/files/neg/macro-invalidsig-tparams-bounds-b/Impls_1.scala deleted file mode 100644 index 89020de7dd..0000000000 --- a/test/files/neg/macro-invalidsig-tparams-bounds-b/Impls_1.scala +++ /dev/null @@ -1,5 +0,0 @@ -import scala.reflect.macros.{Context => Ctx} - -object Impls { - def foo[U <: String](c: Ctx) = ??? -} diff --git a/test/files/neg/macro-invalidsig-tparams-bounds-b/Macros_Test_2.scala b/test/files/neg/macro-invalidsig-tparams-bounds-b/Macros_Test_2.scala deleted file mode 100644 index eed6369a16..0000000000 --- a/test/files/neg/macro-invalidsig-tparams-bounds-b/Macros_Test_2.scala +++ /dev/null @@ -1,8 +0,0 @@ -object Macros { - def foo[U <: Int] = macro Impls.foo[U] -} - -object Test extends App { - import Macros._ - foo[Int] -} \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-tparams-notparams-a/Impls_1.scala b/test/files/neg/macro-invalidsig-tparams-notparams-a/Impls_1.scala deleted file mode 100644 index f8b3c92869..0000000000 --- a/test/files/neg/macro-invalidsig-tparams-notparams-a/Impls_1.scala +++ /dev/null @@ -1,6 +0,0 @@ -import scala.reflect.runtime.universe._ -import scala.reflect.macros.{Context => Ctx} - -object Impls { - def foo[U: c.WeakTypeTag](c: Ctx) = ??? -} \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-tparams-notparams-a/Macros_Test_2.scala b/test/files/neg/macro-invalidsig-tparams-notparams-a/Macros_Test_2.scala deleted file mode 100644 index 96a8de2832..0000000000 --- a/test/files/neg/macro-invalidsig-tparams-notparams-a/Macros_Test_2.scala +++ /dev/null @@ -1,8 +0,0 @@ -object Macros { - def foo = macro Impls.foo -} - -object Test extends App { - import Macros._ - foo -} \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-tparams-notparams-b/Impls_1.scala b/test/files/neg/macro-invalidsig-tparams-notparams-b/Impls_1.scala deleted file mode 100644 index baf3aab9e3..0000000000 --- a/test/files/neg/macro-invalidsig-tparams-notparams-b/Impls_1.scala +++ /dev/null @@ -1,11 +0,0 @@ -import scala.reflect.runtime.universe._ -import scala.reflect.macros.{Context => Ctx} - -object Impls { - def foo[T: c.WeakTypeTag, U: c.WeakTypeTag, V](c: Ctx)(implicit V: c.WeakTypeTag[V]): c.Expr[Unit] = { - println(implicitly[c.WeakTypeTag[T]]) - println(implicitly[c.WeakTypeTag[U]]) - println(V) - c.literalUnit - } -} \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-tparams-notparams-b/Macros_Test_2.scala b/test/files/neg/macro-invalidsig-tparams-notparams-b/Macros_Test_2.scala deleted file mode 100644 index 7d02bf613a..0000000000 --- a/test/files/neg/macro-invalidsig-tparams-notparams-b/Macros_Test_2.scala +++ /dev/null @@ -1,11 +0,0 @@ -class D[T] { - class C[U] { - def foo[V] = macro Impls.foo - } -} - -object Test extends App { - val outer1 = new D[Int] - val outer2 = new outer1.C[String] - outer2.foo[Boolean] -} \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-tparams-notparams-c/Impls_1.scala b/test/files/neg/macro-invalidsig-tparams-notparams-c/Impls_1.scala deleted file mode 100644 index 44b4ed6ab3..0000000000 --- a/test/files/neg/macro-invalidsig-tparams-notparams-c/Impls_1.scala +++ /dev/null @@ -1,12 +0,0 @@ -import scala.reflect.runtime.universe._ -import scala.reflect.macros.{Context => Ctx} - -object Impls { - def foo[T: c.WeakTypeTag, U: c.WeakTypeTag, V](c: Ctx)(implicit V: c.WeakTypeTag[V]): c.Expr[Unit] = { - import c.universe._ - println(implicitly[c.WeakTypeTag[T]]) - println(implicitly[c.WeakTypeTag[U]]) - println(V) - c.literalUnit - } -} \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-tparams-notparams-c/Macros_Test_2.scala b/test/files/neg/macro-invalidsig-tparams-notparams-c/Macros_Test_2.scala deleted file mode 100644 index 109e142e52..0000000000 --- a/test/files/neg/macro-invalidsig-tparams-notparams-c/Macros_Test_2.scala +++ /dev/null @@ -1,11 +0,0 @@ -class D[T] { - class C[U] { - def foo[V] = macro Impls.foo[V] - } -} - -object Test extends App { - val outer1 = new D[Int] - val outer2 = new outer1.C[String] - outer2.foo[Boolean] -} \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig.check b/test/files/neg/macro-invalidsig.check new file mode 100644 index 0000000000..52074cf783 --- /dev/null +++ b/test/files/neg/macro-invalidsig.check @@ -0,0 +1,82 @@ +Macros_Test_2.scala:2: error: macro implementation has wrong shape: + required: (c: scala.reflect.macros.Context): c.Expr[Any] + found : (c: scala.reflect.macros.Context)(implicit evidence$2: Numeric[U]): c.universe.Literal +macro implementations cannot have implicit parameters other than WeakTypeTag evidences + def foo[U] = macro Impls1.foo[U] + ^ +Macros_Test_2.scala:6: error: macro implementation has wrong shape: + required: (c: scala.reflect.macros.Context): c.Expr[Any] + found : : Nothing +number of parameter sections differ + def foo = macro Impls2.foo + ^ +Macros_Test_2.scala:10: error: macro implementation has wrong shape: + required: (c: scala.reflect.macros.Context): c.Expr[Any] + found : (c: scala.reflect.api.Universe): Nothing +type mismatch for parameter c: scala.reflect.macros.Context does not conform to scala.reflect.api.Universe + def foo = macro Impls3.foo + ^ +Macros_Test_2.scala:14: error: macro implementation has wrong shape: + required: (c: scala.reflect.macros.Context): c.Expr[Any] + found : (cs: scala.reflect.macros.Context*): Nothing +types incompatible for parameter cs: corresponding is not a vararg parameter + def foo = macro Impls4.foo + ^ +Macros_Test_2.scala:18: error: macro implementation has wrong shape: + required: (c: scala.reflect.macros.Context)(x: c.Expr[Any]): c.Expr[Any] + found : (c: scala.reflect.macros.Context): Nothing +number of parameter sections differ + def foo(x: Any) = macro Impls5.foo + ^ +Macros_Test_2.scala:22: error: macro implementation has wrong shape: + required: (c: scala.reflect.macros.Context)(x: c.Expr[Int]): c.Expr[Unit] + found : (c: scala.reflect.macros.Context)(implicit x: c.Expr[Int]): c.Expr[Unit] +macro implementations cannot have implicit parameters other than WeakTypeTag evidences + def foo[U](x: Int) = macro Impls6.foo[T, U] + ^ +Macros_Test_2.scala:26: error: macro implementation has wrong shape: + required: (c: scala.reflect.macros.Context)(x: c.Expr[Int]): c.Expr[Any] + found : (c: scala.reflect.macros.Context)(x: c.Expr[Int], y: c.Expr[Int]): Nothing +parameter lists have different length, found extra parameter y: c.Expr[Int] + def foo(x: Int) = macro Impls7.foo + ^ +Macros_Test_2.scala:30: error: macro implementation has wrong shape: + required: (c: scala.reflect.macros.Context)(x: c.Expr[Int]): c.Expr[Any] + found : (c: scala.reflect.macros.Context)(x: c.universe.Symbol): Nothing +type mismatch for parameter x: c.Expr[Int] does not conform to c.universe.Symbol + def foo(x: Int) = macro Impls8.foo + ^ +Macros_Test_2.scala:34: error: macro implementation has wrong shape: + required: (c: scala.reflect.macros.Context)(x: c.Expr[Int], y: c.Expr[Int]): c.Expr[Any] + found : (c: scala.reflect.macros.Context)(xs: c.Expr[Int]*): Nothing +parameter lists have different length, required extra parameter y: c.Expr[Int] + def foo(x: Int, y: Int) = macro Impls9.foo + ^ +Macros_Test_2.scala:38: error: macro implementation has wrong shape: + required: (c: scala.reflect.macros.Context)(x: c.Expr[Int], y: c.Expr[Int]): c.Expr[Any] + found : (c: scala.reflect.macros.Context)(y: c.Expr[Int], x: c.Expr[Int]): Nothing +parameter names differ: x != y + def foo(x: Int, y: Int) = macro Impls10.foo + ^ +Macros_Test_2.scala:42: error: macro implementation has wrong shape: + required: (c: scala.reflect.macros.Context): c.Expr[Any] + found : (c: scala.reflect.macros.Context)(U: c.universe.Type): Nothing +number of parameter sections differ + def foo[U] = macro Impls11.foo[U] + ^ +Macros_Test_2.scala:46: error: type arguments [U] do not conform to method foo's type parameter bounds [U <: String] + def foo[U] = macro Impls12.foo[U] + ^ +Macros_Test_2.scala:50: error: type arguments [U] do not conform to method foo's type parameter bounds [U <: String] + def foo[U <: Int] = macro Impls13.foo[U] + ^ +Macros_Test_2.scala:54: error: wrong number of type parameters for method foo: [U](c: scala.reflect.macros.Context)(implicit evidence$4: c.WeakTypeTag[U])Nothing + def foo = macro Impls14.foo + ^ +Macros_Test_2.scala:59: error: wrong number of type parameters for method foo: [T, U, V](c: scala.reflect.macros.Context)(implicit evidence$5: c.WeakTypeTag[T], implicit evidence$6: c.WeakTypeTag[U], implicit V: c.WeakTypeTag[V])c.Expr[Unit] + def foo15[V] = macro Impls15.foo + ^ +Macros_Test_2.scala:60: error: wrong number of type parameters for method foo: [T, U, V](c: scala.reflect.macros.Context)(implicit evidence$7: c.WeakTypeTag[T], implicit evidence$8: c.WeakTypeTag[U], implicit V: c.WeakTypeTag[V])c.Expr[Unit] + def foo16[V] = macro Impls16.foo[V] + ^ +16 errors found diff --git a/test/files/neg/macro-invalidsig.flags b/test/files/neg/macro-invalidsig.flags new file mode 100644 index 0000000000..cd66464f2f --- /dev/null +++ b/test/files/neg/macro-invalidsig.flags @@ -0,0 +1 @@ +-language:experimental.macros \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig/Impls_1.scala b/test/files/neg/macro-invalidsig/Impls_1.scala new file mode 100644 index 0000000000..e7d6c18f8d --- /dev/null +++ b/test/files/neg/macro-invalidsig/Impls_1.scala @@ -0,0 +1,88 @@ +import scala.reflect.runtime.universe._ +import scala.reflect.macros.Context + +object Impls1 { + def foo[U: c.WeakTypeTag: Numeric](c: Context) = { + import c.universe._ + Literal(Constant(42)) + } +} + +object Impls2 { + def foo = ??? +} + +object Impls3 { + def foo(c: scala.reflect.api.Universe) = ??? +} + +object Impls4 { + def foo(cs: Context*) = ??? +} + +object Impls5 { + def foo(c: Context) = ??? +} + +object Impls6 { + def foo[T, U: c.WeakTypeTag](c: Context)(implicit x: c.Expr[Int]) = { + import c.{prefix => prefix} + import c.universe._ + val body = Block(List( + Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant("invoking foo_targs...")))), + Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant("type of prefix is: " + prefix.staticType)))), + Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant("U is: " + implicitly[c.WeakTypeTag[U]].tpe))))), + Literal(Constant(()))) + c.Expr[Unit](body) + } +} + +object Impls7 { + def foo(c: Context)(x: c.Expr[Int], y: c.Expr[Int]) = ??? +} + +object Impls8 { + def foo(c: Context)(x: c.universe.Symbol) = ??? +} + +object Impls9 { + def foo(c: Context)(xs: c.Expr[Int]*) = ??? +} + +object Impls10 { + def foo(c: Context)(y: c.Expr[Int], x: c.Expr[Int]) = ??? +} + +object Impls11 { + def foo[U](c: Context)(U: c.universe.Type) = ??? +} + +object Impls12 { + def foo[U <: String](c: Context) = ??? +} + +object Impls13 { + def foo[U <: String](c: Context) = ??? +} + +object Impls14 { + def foo[U: c.WeakTypeTag](c: Context) = ??? +} + +object Impls15 { + def foo[T: c.WeakTypeTag, U: c.WeakTypeTag, V](c: Context)(implicit V: c.WeakTypeTag[V]): c.Expr[Unit] = { + println(implicitly[c.WeakTypeTag[T]]) + println(implicitly[c.WeakTypeTag[U]]) + println(V) + c.literalUnit + } +} + +object Impls16 { + def foo[T: c.WeakTypeTag, U: c.WeakTypeTag, V](c: Context)(implicit V: c.WeakTypeTag[V]): c.Expr[Unit] = { + println(implicitly[c.WeakTypeTag[T]]) + println(implicitly[c.WeakTypeTag[U]]) + println(V) + c.literalUnit + } +} \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig/Macros_Test_2.scala b/test/files/neg/macro-invalidsig/Macros_Test_2.scala new file mode 100644 index 0000000000..0a6a321431 --- /dev/null +++ b/test/files/neg/macro-invalidsig/Macros_Test_2.scala @@ -0,0 +1,83 @@ +object Macros1 { + def foo[U] = macro Impls1.foo[U] +} + +object Macros2 { + def foo = macro Impls2.foo +} + +object Macros3 { + def foo = macro Impls3.foo +} + +object Macros4 { + def foo = macro Impls4.foo +} + +object Macros5 { + def foo(x: Any) = macro Impls5.foo +} + +class Macros6[T] { + def foo[U](x: Int) = macro Impls6.foo[T, U] +} + +object Macros7 { + def foo(x: Int) = macro Impls7.foo +} + +object Macros8 { + def foo(x: Int) = macro Impls8.foo +} + +object Macros9 { + def foo(x: Int, y: Int) = macro Impls9.foo +} + +object Macros10 { + def foo(x: Int, y: Int) = macro Impls10.foo +} + +object Macros11 { + def foo[U] = macro Impls11.foo[U] +} + +object Macros12 { + def foo[U] = macro Impls12.foo[U] +} + +object Macros13 { + def foo[U <: Int] = macro Impls13.foo[U] +} + +object Macros14 { + def foo = macro Impls14.foo +} + +class D[T] { + class C[U] { + def foo15[V] = macro Impls15.foo + def foo16[V] = macro Impls16.foo[V] + } +} + +object Test extends App { + println(Macros1.foo[String]) + println(Macros2.foo) + println(Macros3.foo) + println(Macros4.foo) + println(Macros5.foo(42)) + println(new Macros6[Int]().foo[String](42)) + println(Macros7.foo(42)) + println(Macros8.foo) + println(Macros9.foo(4, 2)) + println(Macros10.foo(4, 2)) + println(Macros11.foo[Int]) + println(Macros12.foo[Int]) + println(Macros13.foo[Int]) + println(Macros14.foo) + val outer1 = new D[Int] + val outer2 = new outer1.C[String] + outer2.foo15[Boolean] + outer2.foo16[Boolean] +} \ No newline at end of file diff --git a/test/files/neg/macro-invalidusage-badargs.check b/test/files/neg/macro-invalidusage-badargs.check index 294cfd0cf5..4c1115418b 100644 --- a/test/files/neg/macro-invalidusage-badargs.check +++ b/test/files/neg/macro-invalidusage-badargs.check @@ -1,6 +1,18 @@ -Macros_Test_2.scala:7: error: type mismatch; +Macros_Test_2.scala:5: error: type mismatch; found : String("42") required: Int - val s: String = foo("42") - ^ -one error found + foo("42") + ^ +Macros_Test_2.scala:6: error: too few argument lists for macro invocation + foo + ^ +Macros_Test_2.scala:7: error: Int does not take parameters + foo(4)(2) + ^ +Macros_Test_2.scala:8: error: macro applications do not support named and/or default arguments + foo() + ^ +Macros_Test_2.scala:9: error: too many arguments for macro method foo: (x: Int)Int + foo(4, 2) + ^ +5 errors found diff --git a/test/files/neg/macro-invalidusage-badargs/Macros_Test_2.scala b/test/files/neg/macro-invalidusage-badargs/Macros_Test_2.scala index a6af1bb277..0b3ca0590b 100644 --- a/test/files/neg/macro-invalidusage-badargs/Macros_Test_2.scala +++ b/test/files/neg/macro-invalidusage-badargs/Macros_Test_2.scala @@ -1,8 +1,10 @@ -object Macros { - def foo(x: Int) = macro Impls.foo -} +object Macros { def foo(x: Int) = macro Impls.foo } +import Macros._ object Test extends App { - import Macros._ - val s: String = foo("42") + foo("42") + foo + foo(4)(2) + foo() + foo(4, 2) } \ No newline at end of file diff --git a/test/files/neg/macro-invalidusage-badbounds-a.check b/test/files/neg/macro-invalidusage-badbounds-a.check deleted file mode 100644 index 277f407d38..0000000000 --- a/test/files/neg/macro-invalidusage-badbounds-a.check +++ /dev/null @@ -1,4 +0,0 @@ -Macros_Test_2.scala:7: error: type arguments [Int] do not conform to macro method foo's type parameter bounds [U <: String] - foo[Int] - ^ -one error found diff --git a/test/files/neg/macro-invalidusage-badbounds-a.flags b/test/files/neg/macro-invalidusage-badbounds-a.flags deleted file mode 100644 index cd66464f2f..0000000000 --- a/test/files/neg/macro-invalidusage-badbounds-a.flags +++ /dev/null @@ -1 +0,0 @@ --language:experimental.macros \ No newline at end of file diff --git a/test/files/neg/macro-invalidusage-badbounds-a/Impls_1.scala b/test/files/neg/macro-invalidusage-badbounds-a/Impls_1.scala deleted file mode 100644 index 6ee71a3628..0000000000 --- a/test/files/neg/macro-invalidusage-badbounds-a/Impls_1.scala +++ /dev/null @@ -1,5 +0,0 @@ -import scala.reflect.macros.{Context => Ctx} - -object Impls { - def foo[U <: String](c: Ctx) = c.literalUnit -} diff --git a/test/files/neg/macro-invalidusage-badbounds-a/Macros_Test_2.scala b/test/files/neg/macro-invalidusage-badbounds-a/Macros_Test_2.scala deleted file mode 100644 index 3139599108..0000000000 --- a/test/files/neg/macro-invalidusage-badbounds-a/Macros_Test_2.scala +++ /dev/null @@ -1,8 +0,0 @@ -object Macros { - def foo[U <: String] = macro Impls.foo[U] -} - -object Test extends App { - import Macros._ - foo[Int] -} \ No newline at end of file diff --git a/test/files/neg/macro-invalidusage-badbounds.check b/test/files/neg/macro-invalidusage-badbounds.check new file mode 100644 index 0000000000..277f407d38 --- /dev/null +++ b/test/files/neg/macro-invalidusage-badbounds.check @@ -0,0 +1,4 @@ +Macros_Test_2.scala:7: error: type arguments [Int] do not conform to macro method foo's type parameter bounds [U <: String] + foo[Int] + ^ +one error found diff --git a/test/files/neg/macro-invalidusage-badbounds.flags b/test/files/neg/macro-invalidusage-badbounds.flags new file mode 100644 index 0000000000..cd66464f2f --- /dev/null +++ b/test/files/neg/macro-invalidusage-badbounds.flags @@ -0,0 +1 @@ +-language:experimental.macros \ No newline at end of file diff --git a/test/files/neg/macro-invalidusage-badbounds/Impls_1.scala b/test/files/neg/macro-invalidusage-badbounds/Impls_1.scala new file mode 100644 index 0000000000..6ee71a3628 --- /dev/null +++ b/test/files/neg/macro-invalidusage-badbounds/Impls_1.scala @@ -0,0 +1,5 @@ +import scala.reflect.macros.{Context => Ctx} + +object Impls { + def foo[U <: String](c: Ctx) = c.literalUnit +} diff --git a/test/files/neg/macro-invalidusage-badbounds/Macros_Test_2.scala b/test/files/neg/macro-invalidusage-badbounds/Macros_Test_2.scala new file mode 100644 index 0000000000..3139599108 --- /dev/null +++ b/test/files/neg/macro-invalidusage-badbounds/Macros_Test_2.scala @@ -0,0 +1,8 @@ +object Macros { + def foo[U <: String] = macro Impls.foo[U] +} + +object Test extends App { + import Macros._ + foo[Int] +} \ No newline at end of file diff --git a/test/files/neg/macro-invalidusage-badtargs-untyped.check b/test/files/neg/macro-invalidusage-badtargs-untyped.check new file mode 100644 index 0000000000..1678180281 --- /dev/null +++ b/test/files/neg/macro-invalidusage-badtargs-untyped.check @@ -0,0 +1,18 @@ +Macros_Test_2.scala:11: error: macro method foo1: (x: _)Int does not take type parameters. + foo1[String](42) + ^ +Macros_Test_2.scala:12: error: wrong number of type parameters for macro method foo2: [T](x: _)Int + foo2[String, String](42) + ^ +Macros_Test_2.scala:13: error: wrong number of type parameters for macro method foo3: [T, U](x: _)Int + foo3[String](42) + ^ +Macros_Test_2.scala:14: error: String takes no type parameters, expected: one + foo4[String](42) + ^ +Macros_Test_2.scala:15: error: kinds of the type arguments (List) do not conform to the expected kinds of the type parameters (type T). +List's type parameters do not match type T's expected parameters: +type A has no type parameters, but type U has one + foo5[List](42) + ^ +5 errors found diff --git a/test/files/neg/macro-invalidusage-badtargs-untyped.flags b/test/files/neg/macro-invalidusage-badtargs-untyped.flags new file mode 100644 index 0000000000..cd66464f2f --- /dev/null +++ b/test/files/neg/macro-invalidusage-badtargs-untyped.flags @@ -0,0 +1 @@ +-language:experimental.macros \ No newline at end of file diff --git a/test/files/neg/macro-invalidusage-badtargs.check b/test/files/neg/macro-invalidusage-badtargs.check index 73801ab43e..6a9e1d6e6b 100644 --- a/test/files/neg/macro-invalidusage-badtargs.check +++ b/test/files/neg/macro-invalidusage-badtargs.check @@ -1,4 +1,18 @@ -Macros_Test_2.scala:7: error: macro method foo: (x: Int)Int does not take type parameters. - val s: String = foo[String](42) - ^ -one error found +Macros_Test_2.scala:11: error: macro method foo1: (x: Int)Int does not take type parameters. + foo1[String](42) + ^ +Macros_Test_2.scala:12: error: wrong number of type parameters for macro method foo2: [T](x: Int)Int + foo2[String, String](42) + ^ +Macros_Test_2.scala:13: error: wrong number of type parameters for macro method foo3: [T, U](x: Int)Int + foo3[String](42) + ^ +Macros_Test_2.scala:14: error: String takes no type parameters, expected: one + foo4[String](42) + ^ +Macros_Test_2.scala:15: error: kinds of the type arguments (List) do not conform to the expected kinds of the type parameters (type T). +List's type parameters do not match type T's expected parameters: +type A has no type parameters, but type U has one + foo5[List](42) + ^ +5 errors found diff --git a/test/files/neg/macro-invalidusage-badtargs/Macros_Test_2.scala b/test/files/neg/macro-invalidusage-badtargs/Macros_Test_2.scala index c54093b637..fd16d163c3 100644 --- a/test/files/neg/macro-invalidusage-badtargs/Macros_Test_2.scala +++ b/test/files/neg/macro-invalidusage-badtargs/Macros_Test_2.scala @@ -1,8 +1,16 @@ object Macros { - def foo(x: Int) = macro Impls.foo + def foo1(x: Int) = macro Impls.foo + def foo2[T](x: Int) = macro Impls.foo + def foo3[T, U](x: Int) = macro Impls.foo + def foo4[T[_]](x: Int) = macro Impls.foo + def foo5[T[U[_]]](x: Int) = macro Impls.foo } object Test extends App { import Macros._ - val s: String = foo[String](42) + foo1[String](42) + foo2[String, String](42) + foo3[String](42) + foo4[String](42) + foo5[List](42) } \ No newline at end of file diff --git a/test/files/neg/macro-invalidusage-nontypeable.check b/test/files/neg/macro-invalidusage-nontypeable.check new file mode 100644 index 0000000000..88e6057e5e --- /dev/null +++ b/test/files/neg/macro-invalidusage-nontypeable.check @@ -0,0 +1,4 @@ +Test_2.scala:2: error: not found: value IDoNotExist + Macros.foo + ^ +one error found diff --git a/test/files/neg/macro-invalidusage-nontypeable.flags b/test/files/neg/macro-invalidusage-nontypeable.flags new file mode 100644 index 0000000000..cd66464f2f --- /dev/null +++ b/test/files/neg/macro-invalidusage-nontypeable.flags @@ -0,0 +1 @@ +-language:experimental.macros \ No newline at end of file diff --git a/test/files/neg/macro-invalidusage-nontypeable/Impls_Macros_1.scala b/test/files/neg/macro-invalidusage-nontypeable/Impls_Macros_1.scala new file mode 100644 index 0000000000..869a5a41fa --- /dev/null +++ b/test/files/neg/macro-invalidusage-nontypeable/Impls_Macros_1.scala @@ -0,0 +1,13 @@ +import scala.reflect.macros.{Context => Ctx} + +object Impls { + def foo(c: Ctx) = { + import c.universe._ + val body = Ident(TermName("IDoNotExist")) + c.Expr[Int](body) + } +} + +object Macros { + def foo = macro Impls.foo +} \ No newline at end of file diff --git a/test/files/neg/macro-invalidusage-nontypeable/Test_2.scala b/test/files/neg/macro-invalidusage-nontypeable/Test_2.scala new file mode 100644 index 0000000000..acfddae942 --- /dev/null +++ b/test/files/neg/macro-invalidusage-nontypeable/Test_2.scala @@ -0,0 +1,3 @@ +object Test extends App { + Macros.foo +} \ No newline at end of file diff --git a/test/files/neg/macro-invalidusage-presuper.check b/test/files/neg/macro-invalidusage-presuper.check new file mode 100644 index 0000000000..f63a0eef80 --- /dev/null +++ b/test/files/neg/macro-invalidusage-presuper.check @@ -0,0 +1,4 @@ +Macros_Test_2.scala:3: error: only type definitions and concrete field definitions allowed in early object initialization section +class D extends { def x = macro impl } with AnyRef + ^ +one error found diff --git a/test/files/neg/macro-invalidusage-presuper.flags b/test/files/neg/macro-invalidusage-presuper.flags new file mode 100644 index 0000000000..cd66464f2f --- /dev/null +++ b/test/files/neg/macro-invalidusage-presuper.flags @@ -0,0 +1 @@ +-language:experimental.macros \ No newline at end of file diff --git a/test/files/neg/macro-invalidusage-presuper/Impls_1.scala b/test/files/neg/macro-invalidusage-presuper/Impls_1.scala new file mode 100644 index 0000000000..b39a037c47 --- /dev/null +++ b/test/files/neg/macro-invalidusage-presuper/Impls_1.scala @@ -0,0 +1,5 @@ +import scala.reflect.macros.Context + +object Impls { + def impl(c: Context) = c.literalUnit +} \ No newline at end of file diff --git a/test/files/neg/macro-invalidusage-presuper/Macros_Test_2.scala b/test/files/neg/macro-invalidusage-presuper/Macros_Test_2.scala new file mode 100644 index 0000000000..ff46a5915f --- /dev/null +++ b/test/files/neg/macro-invalidusage-presuper/Macros_Test_2.scala @@ -0,0 +1,3 @@ +import Impls._ + +class D extends { def x = macro impl } with AnyRef \ No newline at end of file diff --git a/test/files/run/macro-declared-in-annotation.check b/test/files/run/macro-declared-in-annotation.check deleted file mode 100644 index 7658ad2c24..0000000000 --- a/test/files/run/macro-declared-in-annotation.check +++ /dev/null @@ -1 +0,0 @@ -it works diff --git a/test/files/run/macro-declared-in-annotation.flags b/test/files/run/macro-declared-in-annotation.flags deleted file mode 100644 index cd66464f2f..0000000000 --- a/test/files/run/macro-declared-in-annotation.flags +++ /dev/null @@ -1 +0,0 @@ --language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-declared-in-annotation/Impls_1.scala b/test/files/run/macro-declared-in-annotation/Impls_1.scala deleted file mode 100644 index 1ea06de679..0000000000 --- a/test/files/run/macro-declared-in-annotation/Impls_1.scala +++ /dev/null @@ -1,11 +0,0 @@ -import scala.reflect.macros.{Context => Ctx} - -object Impls { - def foo(c: Ctx) = { - import c.{prefix => prefix} - import c.universe._ - val printPrefix = Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant("prefix = " + prefix)))) - val body = Block(List(printPrefix), Literal(Constant("this is deprecated"))) - c.Expr[String](body) - } -} \ No newline at end of file diff --git a/test/files/run/macro-declared-in-annotation/Macros_2.scala b/test/files/run/macro-declared-in-annotation/Macros_2.scala deleted file mode 100644 index 40d71c62fb..0000000000 --- a/test/files/run/macro-declared-in-annotation/Macros_2.scala +++ /dev/null @@ -1,8 +0,0 @@ -class foo(val bar: String) extends annotation.StaticAnnotation - -object Api { - // foo in ann must have a different name - // otherwise, we get bitten by https://issues.scala-lang.org/browse/SI-5544 - @foo({def fooInAnn = macro Impls.foo; fooInAnn}) - def foo = println("it works") -} \ No newline at end of file diff --git a/test/files/run/macro-declared-in-annotation/Test_3.scala b/test/files/run/macro-declared-in-annotation/Test_3.scala deleted file mode 100644 index 866487f028..0000000000 --- a/test/files/run/macro-declared-in-annotation/Test_3.scala +++ /dev/null @@ -1,3 +0,0 @@ -object Test extends App { - Api.foo -} \ No newline at end of file diff --git a/test/files/run/macro-declared-in-anonymous.check b/test/files/run/macro-declared-in-anonymous.check deleted file mode 100644 index 09b8d015a6..0000000000 --- a/test/files/run/macro-declared-in-anonymous.check +++ /dev/null @@ -1,2 +0,0 @@ -prefix = Expr[Nothing](Test.this.macros) -it works diff --git a/test/files/run/macro-declared-in-anonymous.flags b/test/files/run/macro-declared-in-anonymous.flags deleted file mode 100644 index cd66464f2f..0000000000 --- a/test/files/run/macro-declared-in-anonymous.flags +++ /dev/null @@ -1 +0,0 @@ --language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-declared-in-anonymous/Impls_1.scala b/test/files/run/macro-declared-in-anonymous/Impls_1.scala deleted file mode 100644 index 348f3420f2..0000000000 --- a/test/files/run/macro-declared-in-anonymous/Impls_1.scala +++ /dev/null @@ -1,11 +0,0 @@ -import scala.reflect.macros.{Context => Ctx} - -object Impls { - def foo(c: Ctx) = { - import c.{prefix => prefix} - import c.universe._ - val printPrefix = Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant("prefix = " + prefix)))) - val body = Block(List(printPrefix), Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant("it works"))))) - c.Expr[Unit](body) - } -} \ No newline at end of file diff --git a/test/files/run/macro-declared-in-anonymous/Macros_Test_2.scala b/test/files/run/macro-declared-in-anonymous/Macros_Test_2.scala deleted file mode 100644 index 88cd29ae4f..0000000000 --- a/test/files/run/macro-declared-in-anonymous/Macros_Test_2.scala +++ /dev/null @@ -1,6 +0,0 @@ -import scala.language.reflectiveCalls - -object Test extends App { - val macros = new { def foo = macro Impls.foo } - macros.foo -} diff --git a/test/files/run/macro-declared-in-block.check b/test/files/run/macro-declared-in-block.check deleted file mode 100644 index 5e687db8bf..0000000000 --- a/test/files/run/macro-declared-in-block.check +++ /dev/null @@ -1,2 +0,0 @@ -prefix = Expr[Nothing]() -it works diff --git a/test/files/run/macro-declared-in-block.flags b/test/files/run/macro-declared-in-block.flags deleted file mode 100644 index cd66464f2f..0000000000 --- a/test/files/run/macro-declared-in-block.flags +++ /dev/null @@ -1 +0,0 @@ --language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-declared-in-block/Impls_1.scala b/test/files/run/macro-declared-in-block/Impls_1.scala deleted file mode 100644 index 348f3420f2..0000000000 --- a/test/files/run/macro-declared-in-block/Impls_1.scala +++ /dev/null @@ -1,11 +0,0 @@ -import scala.reflect.macros.{Context => Ctx} - -object Impls { - def foo(c: Ctx) = { - import c.{prefix => prefix} - import c.universe._ - val printPrefix = Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant("prefix = " + prefix)))) - val body = Block(List(printPrefix), Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant("it works"))))) - c.Expr[Unit](body) - } -} \ No newline at end of file diff --git a/test/files/run/macro-declared-in-block/Macros_Test_2.scala b/test/files/run/macro-declared-in-block/Macros_Test_2.scala deleted file mode 100644 index 69088e24bc..0000000000 --- a/test/files/run/macro-declared-in-block/Macros_Test_2.scala +++ /dev/null @@ -1,6 +0,0 @@ -object Test extends App { - { - def foo = macro Impls.foo - foo - } -} \ No newline at end of file diff --git a/test/files/run/macro-declared-in-class-class.check b/test/files/run/macro-declared-in-class-class.check deleted file mode 100644 index 47248d7af7..0000000000 --- a/test/files/run/macro-declared-in-class-class.check +++ /dev/null @@ -1,2 +0,0 @@ -prefix = Expr[Nothing](new Test.this.outer.Macros()) -it works diff --git a/test/files/run/macro-declared-in-class-class.flags b/test/files/run/macro-declared-in-class-class.flags deleted file mode 100644 index cd66464f2f..0000000000 --- a/test/files/run/macro-declared-in-class-class.flags +++ /dev/null @@ -1 +0,0 @@ --language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-declared-in-class-class/Impls_1.scala b/test/files/run/macro-declared-in-class-class/Impls_1.scala deleted file mode 100644 index 348f3420f2..0000000000 --- a/test/files/run/macro-declared-in-class-class/Impls_1.scala +++ /dev/null @@ -1,11 +0,0 @@ -import scala.reflect.macros.{Context => Ctx} - -object Impls { - def foo(c: Ctx) = { - import c.{prefix => prefix} - import c.universe._ - val printPrefix = Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant("prefix = " + prefix)))) - val body = Block(List(printPrefix), Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant("it works"))))) - c.Expr[Unit](body) - } -} \ No newline at end of file diff --git a/test/files/run/macro-declared-in-class-class/Macros_Test_2.scala b/test/files/run/macro-declared-in-class-class/Macros_Test_2.scala deleted file mode 100644 index 871857a97f..0000000000 --- a/test/files/run/macro-declared-in-class-class/Macros_Test_2.scala +++ /dev/null @@ -1,10 +0,0 @@ -class Macros { - class Macros { - def foo = macro Impls.foo - } -} - -object Test extends App { - val outer = new Macros() - new outer.Macros().foo -} \ No newline at end of file diff --git a/test/files/run/macro-declared-in-class-object.check b/test/files/run/macro-declared-in-class-object.check deleted file mode 100644 index 35af59e40f..0000000000 --- a/test/files/run/macro-declared-in-class-object.check +++ /dev/null @@ -1,2 +0,0 @@ -prefix = Expr[Nothing](Test.this.outer.Macros) -it works diff --git a/test/files/run/macro-declared-in-class-object.flags b/test/files/run/macro-declared-in-class-object.flags deleted file mode 100644 index cd66464f2f..0000000000 --- a/test/files/run/macro-declared-in-class-object.flags +++ /dev/null @@ -1 +0,0 @@ --language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-declared-in-class-object/Impls_1.scala b/test/files/run/macro-declared-in-class-object/Impls_1.scala deleted file mode 100644 index 348f3420f2..0000000000 --- a/test/files/run/macro-declared-in-class-object/Impls_1.scala +++ /dev/null @@ -1,11 +0,0 @@ -import scala.reflect.macros.{Context => Ctx} - -object Impls { - def foo(c: Ctx) = { - import c.{prefix => prefix} - import c.universe._ - val printPrefix = Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant("prefix = " + prefix)))) - val body = Block(List(printPrefix), Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant("it works"))))) - c.Expr[Unit](body) - } -} \ No newline at end of file diff --git a/test/files/run/macro-declared-in-class-object/Macros_Test_2.scala b/test/files/run/macro-declared-in-class-object/Macros_Test_2.scala deleted file mode 100644 index 994f9fe935..0000000000 --- a/test/files/run/macro-declared-in-class-object/Macros_Test_2.scala +++ /dev/null @@ -1,10 +0,0 @@ -class Macros { - object Macros { - def foo = macro Impls.foo - } -} - -object Test extends App { - val outer = new Macros() - outer.Macros.foo -} \ No newline at end of file diff --git a/test/files/run/macro-declared-in-class.check b/test/files/run/macro-declared-in-class.check deleted file mode 100644 index a1c1d7af8b..0000000000 --- a/test/files/run/macro-declared-in-class.check +++ /dev/null @@ -1,2 +0,0 @@ -prefix = Expr[Nothing](new Macros()) -it works diff --git a/test/files/run/macro-declared-in-class.flags b/test/files/run/macro-declared-in-class.flags deleted file mode 100644 index cd66464f2f..0000000000 --- a/test/files/run/macro-declared-in-class.flags +++ /dev/null @@ -1 +0,0 @@ --language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-declared-in-class/Impls_1.scala b/test/files/run/macro-declared-in-class/Impls_1.scala deleted file mode 100644 index 348f3420f2..0000000000 --- a/test/files/run/macro-declared-in-class/Impls_1.scala +++ /dev/null @@ -1,11 +0,0 @@ -import scala.reflect.macros.{Context => Ctx} - -object Impls { - def foo(c: Ctx) = { - import c.{prefix => prefix} - import c.universe._ - val printPrefix = Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant("prefix = " + prefix)))) - val body = Block(List(printPrefix), Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant("it works"))))) - c.Expr[Unit](body) - } -} \ No newline at end of file diff --git a/test/files/run/macro-declared-in-class/Macros_Test_2.scala b/test/files/run/macro-declared-in-class/Macros_Test_2.scala deleted file mode 100644 index 1b9d13e775..0000000000 --- a/test/files/run/macro-declared-in-class/Macros_Test_2.scala +++ /dev/null @@ -1,7 +0,0 @@ -class Macros { - def foo = macro Impls.foo -} - -object Test extends App { - new Macros().foo -} \ No newline at end of file diff --git a/test/files/run/macro-declared-in-default-param.check b/test/files/run/macro-declared-in-default-param.check deleted file mode 100644 index 6decd7aa4d..0000000000 --- a/test/files/run/macro-declared-in-default-param.check +++ /dev/null @@ -1,5 +0,0 @@ -prefix = Expr[Nothing]() -it works -it works -prefix = Expr[Nothing]() -it works diff --git a/test/files/run/macro-declared-in-default-param.flags b/test/files/run/macro-declared-in-default-param.flags deleted file mode 100644 index cd66464f2f..0000000000 --- a/test/files/run/macro-declared-in-default-param.flags +++ /dev/null @@ -1 +0,0 @@ --language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-declared-in-default-param/Impls_1.scala b/test/files/run/macro-declared-in-default-param/Impls_1.scala deleted file mode 100644 index 4380f40b04..0000000000 --- a/test/files/run/macro-declared-in-default-param/Impls_1.scala +++ /dev/null @@ -1,11 +0,0 @@ -import scala.reflect.macros.{Context => Ctx} - -object Impls { - def foo(c: Ctx) = { - import c.{prefix => prefix} - import c.universe._ - val printPrefix = Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant("prefix = " + prefix)))) - val body = Block(List(printPrefix), Literal(Constant("it works"))) - c.Expr[String](body) - } -} \ No newline at end of file diff --git a/test/files/run/macro-declared-in-default-param/Macros_Test_2.scala b/test/files/run/macro-declared-in-default-param/Macros_Test_2.scala deleted file mode 100644 index 356029e63e..0000000000 --- a/test/files/run/macro-declared-in-default-param/Macros_Test_2.scala +++ /dev/null @@ -1,7 +0,0 @@ -object Test extends App { - def foo(bar: String = { def foo = macro Impls.foo; foo }) = println(bar) - - foo() - foo("it works") - foo() -} \ No newline at end of file diff --git a/test/files/run/macro-declared-in-implicit-class.check b/test/files/run/macro-declared-in-implicit-class.check deleted file mode 100644 index 5dc968c08c..0000000000 --- a/test/files/run/macro-declared-in-implicit-class.check +++ /dev/null @@ -1,2 +0,0 @@ -prefix = Expr[Nothing](Macros.foo("2")) -Some(2) diff --git a/test/files/run/macro-declared-in-implicit-class.flags b/test/files/run/macro-declared-in-implicit-class.flags deleted file mode 100644 index cd66464f2f..0000000000 --- a/test/files/run/macro-declared-in-implicit-class.flags +++ /dev/null @@ -1 +0,0 @@ --language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-declared-in-implicit-class/Impls_Macros_1.scala b/test/files/run/macro-declared-in-implicit-class/Impls_Macros_1.scala deleted file mode 100644 index 4c009cc367..0000000000 --- a/test/files/run/macro-declared-in-implicit-class/Impls_Macros_1.scala +++ /dev/null @@ -1,19 +0,0 @@ -import scala.reflect.macros.{Context => Ctx} - -object Impls { - def toOptionOfInt(c: Ctx) = { - import c.{prefix => prefix} - import c.universe._ - val printPrefix = Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant("prefix = " + prefix)))) - val body = Block(List(printPrefix), Apply(Ident(definitions.SomeModule), List(Select(Select(prefix.tree, TermName("x")), TermName("toInt"))))) - c.Expr[Option[Int]](body) - } -} - -object Macros { - implicit def foo(x: String): Foo = new Foo(x) - - class Foo(val x: String) { - def toOptionOfInt = macro Impls.toOptionOfInt - } -} \ No newline at end of file diff --git a/test/files/run/macro-declared-in-implicit-class/Test_2.scala b/test/files/run/macro-declared-in-implicit-class/Test_2.scala deleted file mode 100644 index d0bc9cc38c..0000000000 --- a/test/files/run/macro-declared-in-implicit-class/Test_2.scala +++ /dev/null @@ -1,4 +0,0 @@ -object Test extends App { - import Macros._ - println("2".toOptionOfInt) -} \ No newline at end of file diff --git a/test/files/run/macro-declared-in-method.check b/test/files/run/macro-declared-in-method.check deleted file mode 100644 index 5e687db8bf..0000000000 --- a/test/files/run/macro-declared-in-method.check +++ /dev/null @@ -1,2 +0,0 @@ -prefix = Expr[Nothing]() -it works diff --git a/test/files/run/macro-declared-in-method.flags b/test/files/run/macro-declared-in-method.flags deleted file mode 100644 index cd66464f2f..0000000000 --- a/test/files/run/macro-declared-in-method.flags +++ /dev/null @@ -1 +0,0 @@ --language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-declared-in-method/Impls_1.scala b/test/files/run/macro-declared-in-method/Impls_1.scala deleted file mode 100644 index 348f3420f2..0000000000 --- a/test/files/run/macro-declared-in-method/Impls_1.scala +++ /dev/null @@ -1,11 +0,0 @@ -import scala.reflect.macros.{Context => Ctx} - -object Impls { - def foo(c: Ctx) = { - import c.{prefix => prefix} - import c.universe._ - val printPrefix = Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant("prefix = " + prefix)))) - val body = Block(List(printPrefix), Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant("it works"))))) - c.Expr[Unit](body) - } -} \ No newline at end of file diff --git a/test/files/run/macro-declared-in-method/Macros_Test_2.scala b/test/files/run/macro-declared-in-method/Macros_Test_2.scala deleted file mode 100644 index ed5c8b7c43..0000000000 --- a/test/files/run/macro-declared-in-method/Macros_Test_2.scala +++ /dev/null @@ -1,8 +0,0 @@ -object Test extends App { - def bar() = { - def foo = macro Impls.foo - foo - } - - bar() -} \ No newline at end of file diff --git a/test/files/run/macro-declared-in-object-class.check b/test/files/run/macro-declared-in-object-class.check deleted file mode 100644 index 47248d7af7..0000000000 --- a/test/files/run/macro-declared-in-object-class.check +++ /dev/null @@ -1,2 +0,0 @@ -prefix = Expr[Nothing](new Test.this.outer.Macros()) -it works diff --git a/test/files/run/macro-declared-in-object-class.flags b/test/files/run/macro-declared-in-object-class.flags deleted file mode 100644 index cd66464f2f..0000000000 --- a/test/files/run/macro-declared-in-object-class.flags +++ /dev/null @@ -1 +0,0 @@ --language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-declared-in-object-class/Impls_1.scala b/test/files/run/macro-declared-in-object-class/Impls_1.scala deleted file mode 100644 index 348f3420f2..0000000000 --- a/test/files/run/macro-declared-in-object-class/Impls_1.scala +++ /dev/null @@ -1,11 +0,0 @@ -import scala.reflect.macros.{Context => Ctx} - -object Impls { - def foo(c: Ctx) = { - import c.{prefix => prefix} - import c.universe._ - val printPrefix = Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant("prefix = " + prefix)))) - val body = Block(List(printPrefix), Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant("it works"))))) - c.Expr[Unit](body) - } -} \ No newline at end of file diff --git a/test/files/run/macro-declared-in-object-class/Macros_Test_2.scala b/test/files/run/macro-declared-in-object-class/Macros_Test_2.scala deleted file mode 100644 index 204deed61c..0000000000 --- a/test/files/run/macro-declared-in-object-class/Macros_Test_2.scala +++ /dev/null @@ -1,10 +0,0 @@ -object Macros { - class Macros { - def foo = macro Impls.foo - } -} - -object Test extends App { - val outer = Macros - new outer.Macros().foo -} \ No newline at end of file diff --git a/test/files/run/macro-declared-in-object-object.check b/test/files/run/macro-declared-in-object-object.check deleted file mode 100644 index 35af59e40f..0000000000 --- a/test/files/run/macro-declared-in-object-object.check +++ /dev/null @@ -1,2 +0,0 @@ -prefix = Expr[Nothing](Test.this.outer.Macros) -it works diff --git a/test/files/run/macro-declared-in-object-object.flags b/test/files/run/macro-declared-in-object-object.flags deleted file mode 100644 index cd66464f2f..0000000000 --- a/test/files/run/macro-declared-in-object-object.flags +++ /dev/null @@ -1 +0,0 @@ --language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-declared-in-object-object/Impls_1.scala b/test/files/run/macro-declared-in-object-object/Impls_1.scala deleted file mode 100644 index 348f3420f2..0000000000 --- a/test/files/run/macro-declared-in-object-object/Impls_1.scala +++ /dev/null @@ -1,11 +0,0 @@ -import scala.reflect.macros.{Context => Ctx} - -object Impls { - def foo(c: Ctx) = { - import c.{prefix => prefix} - import c.universe._ - val printPrefix = Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant("prefix = " + prefix)))) - val body = Block(List(printPrefix), Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant("it works"))))) - c.Expr[Unit](body) - } -} \ No newline at end of file diff --git a/test/files/run/macro-declared-in-object-object/Macros_Test_2.scala b/test/files/run/macro-declared-in-object-object/Macros_Test_2.scala deleted file mode 100644 index e261a50f3d..0000000000 --- a/test/files/run/macro-declared-in-object-object/Macros_Test_2.scala +++ /dev/null @@ -1,10 +0,0 @@ -object Macros { - object Macros { - def foo = macro Impls.foo - } -} - -object Test extends App { - val outer = Macros - outer.Macros.foo -} \ No newline at end of file diff --git a/test/files/run/macro-declared-in-object.check b/test/files/run/macro-declared-in-object.check deleted file mode 100644 index 4d955a96b1..0000000000 --- a/test/files/run/macro-declared-in-object.check +++ /dev/null @@ -1,2 +0,0 @@ -prefix = Expr[Nothing](Macros) -it works diff --git a/test/files/run/macro-declared-in-object.flags b/test/files/run/macro-declared-in-object.flags deleted file mode 100644 index cd66464f2f..0000000000 --- a/test/files/run/macro-declared-in-object.flags +++ /dev/null @@ -1 +0,0 @@ --language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-declared-in-object/Impls_1.scala b/test/files/run/macro-declared-in-object/Impls_1.scala deleted file mode 100644 index 348f3420f2..0000000000 --- a/test/files/run/macro-declared-in-object/Impls_1.scala +++ /dev/null @@ -1,11 +0,0 @@ -import scala.reflect.macros.{Context => Ctx} - -object Impls { - def foo(c: Ctx) = { - import c.{prefix => prefix} - import c.universe._ - val printPrefix = Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant("prefix = " + prefix)))) - val body = Block(List(printPrefix), Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant("it works"))))) - c.Expr[Unit](body) - } -} \ No newline at end of file diff --git a/test/files/run/macro-declared-in-object/Macros_Test_2.scala b/test/files/run/macro-declared-in-object/Macros_Test_2.scala deleted file mode 100644 index a5a4862ba0..0000000000 --- a/test/files/run/macro-declared-in-object/Macros_Test_2.scala +++ /dev/null @@ -1,7 +0,0 @@ -object Macros { - def foo = macro Impls.foo -} - -object Test extends App { - Macros.foo -} \ No newline at end of file diff --git a/test/files/run/macro-declared-in-package-object.check b/test/files/run/macro-declared-in-package-object.check deleted file mode 100644 index bc0069178d..0000000000 --- a/test/files/run/macro-declared-in-package-object.check +++ /dev/null @@ -1,2 +0,0 @@ -prefix = Expr[Nothing](Macros.`package`) -it works diff --git a/test/files/run/macro-declared-in-package-object.flags b/test/files/run/macro-declared-in-package-object.flags deleted file mode 100644 index cd66464f2f..0000000000 --- a/test/files/run/macro-declared-in-package-object.flags +++ /dev/null @@ -1 +0,0 @@ --language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-declared-in-package-object/Impls_1.scala b/test/files/run/macro-declared-in-package-object/Impls_1.scala deleted file mode 100644 index 348f3420f2..0000000000 --- a/test/files/run/macro-declared-in-package-object/Impls_1.scala +++ /dev/null @@ -1,11 +0,0 @@ -import scala.reflect.macros.{Context => Ctx} - -object Impls { - def foo(c: Ctx) = { - import c.{prefix => prefix} - import c.universe._ - val printPrefix = Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant("prefix = " + prefix)))) - val body = Block(List(printPrefix), Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant("it works"))))) - c.Expr[Unit](body) - } -} \ No newline at end of file diff --git a/test/files/run/macro-declared-in-package-object/Macros_Test_2.scala b/test/files/run/macro-declared-in-package-object/Macros_Test_2.scala deleted file mode 100644 index 54a5962e80..0000000000 --- a/test/files/run/macro-declared-in-package-object/Macros_Test_2.scala +++ /dev/null @@ -1,8 +0,0 @@ -package object Macros { - def foo = macro Impls.foo -} - -object Test extends App { - import Macros._ - foo -} \ No newline at end of file diff --git a/test/files/run/macro-declared-in-refinement.check b/test/files/run/macro-declared-in-refinement.check deleted file mode 100644 index 09b8d015a6..0000000000 --- a/test/files/run/macro-declared-in-refinement.check +++ /dev/null @@ -1,2 +0,0 @@ -prefix = Expr[Nothing](Test.this.macros) -it works diff --git a/test/files/run/macro-declared-in-refinement.flags b/test/files/run/macro-declared-in-refinement.flags deleted file mode 100644 index cd66464f2f..0000000000 --- a/test/files/run/macro-declared-in-refinement.flags +++ /dev/null @@ -1 +0,0 @@ --language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-declared-in-refinement/Impls_1.scala b/test/files/run/macro-declared-in-refinement/Impls_1.scala deleted file mode 100644 index 348f3420f2..0000000000 --- a/test/files/run/macro-declared-in-refinement/Impls_1.scala +++ /dev/null @@ -1,11 +0,0 @@ -import scala.reflect.macros.{Context => Ctx} - -object Impls { - def foo(c: Ctx) = { - import c.{prefix => prefix} - import c.universe._ - val printPrefix = Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant("prefix = " + prefix)))) - val body = Block(List(printPrefix), Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant("it works"))))) - c.Expr[Unit](body) - } -} \ No newline at end of file diff --git a/test/files/run/macro-declared-in-refinement/Macros_Test_2.scala b/test/files/run/macro-declared-in-refinement/Macros_Test_2.scala deleted file mode 100644 index ff9a66d58a..0000000000 --- a/test/files/run/macro-declared-in-refinement/Macros_Test_2.scala +++ /dev/null @@ -1,9 +0,0 @@ - -import scala.language.reflectiveCalls - -class Base - -object Test extends App { - val macros = new Base { def foo = macro Impls.foo } - macros.foo -} diff --git a/test/files/run/macro-declared-in-trait.check b/test/files/run/macro-declared-in-trait.check deleted file mode 100644 index 0d70ac74f3..0000000000 --- a/test/files/run/macro-declared-in-trait.check +++ /dev/null @@ -1,15 +0,0 @@ -prefix = Expr[Nothing]({ - final class $anon extends AnyRef with Base { - def (): anonymous class $anon = { - $anon.super.(); - () - }; - - }; - new $anon() -}) -it works -prefix = Expr[Nothing](Macros) -it works -prefix = Expr[Nothing](new Macros()) -it works diff --git a/test/files/run/macro-declared-in-trait.flags b/test/files/run/macro-declared-in-trait.flags deleted file mode 100644 index cd66464f2f..0000000000 --- a/test/files/run/macro-declared-in-trait.flags +++ /dev/null @@ -1 +0,0 @@ --language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-declared-in-trait/Impls_1.scala b/test/files/run/macro-declared-in-trait/Impls_1.scala deleted file mode 100644 index 348f3420f2..0000000000 --- a/test/files/run/macro-declared-in-trait/Impls_1.scala +++ /dev/null @@ -1,11 +0,0 @@ -import scala.reflect.macros.{Context => Ctx} - -object Impls { - def foo(c: Ctx) = { - import c.{prefix => prefix} - import c.universe._ - val printPrefix = Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant("prefix = " + prefix)))) - val body = Block(List(printPrefix), Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant("it works"))))) - c.Expr[Unit](body) - } -} \ No newline at end of file diff --git a/test/files/run/macro-declared-in-trait/Macros_Test_2.scala b/test/files/run/macro-declared-in-trait/Macros_Test_2.scala deleted file mode 100644 index f75906b636..0000000000 --- a/test/files/run/macro-declared-in-trait/Macros_Test_2.scala +++ /dev/null @@ -1,13 +0,0 @@ -trait Base { - def foo = macro Impls.foo -} - -object Macros extends Base - -class Macros extends Base - -object Test extends App { - (new Base {}).foo - Macros.foo - new Macros().foo -} \ No newline at end of file diff --git a/test/files/run/macro-def-infer-return-type-a.check b/test/files/run/macro-def-infer-return-type-a.check deleted file mode 100644 index f70d7bba4a..0000000000 --- a/test/files/run/macro-def-infer-return-type-a.check +++ /dev/null @@ -1 +0,0 @@ -42 \ No newline at end of file diff --git a/test/files/run/macro-def-infer-return-type-a.flags b/test/files/run/macro-def-infer-return-type-a.flags deleted file mode 100644 index cd66464f2f..0000000000 --- a/test/files/run/macro-def-infer-return-type-a.flags +++ /dev/null @@ -1 +0,0 @@ --language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-def-infer-return-type-a/Impls_1.scala b/test/files/run/macro-def-infer-return-type-a/Impls_1.scala deleted file mode 100644 index 52c9f9c3e9..0000000000 --- a/test/files/run/macro-def-infer-return-type-a/Impls_1.scala +++ /dev/null @@ -1,5 +0,0 @@ -import scala.reflect.macros.{Context => Ctx} - -object Impls { - def foo(c: Ctx)(x: c.Expr[Int]) = x -} diff --git a/test/files/run/macro-def-infer-return-type-a/Macros_Test_2.scala b/test/files/run/macro-def-infer-return-type-a/Macros_Test_2.scala deleted file mode 100644 index 60fe9dc1c2..0000000000 --- a/test/files/run/macro-def-infer-return-type-a/Macros_Test_2.scala +++ /dev/null @@ -1,4 +0,0 @@ -object Test extends App { - def foo(x: Int) = macro Impls.foo - println(foo(42)) -} \ No newline at end of file diff --git a/test/files/run/macro-def-infer-return-type-b.check b/test/files/run/macro-def-infer-return-type-b.check deleted file mode 100644 index ae2dc7a06f..0000000000 --- a/test/files/run/macro-def-infer-return-type-b.check +++ /dev/null @@ -1,6 +0,0 @@ -reflective compilation has failed: - -exception during macro expansion: -java.lang.Error: an implementation is missing - at Impls$.foo(Impls_Macros_1.scala:5) - diff --git a/test/files/run/macro-def-infer-return-type-b.flags b/test/files/run/macro-def-infer-return-type-b.flags deleted file mode 100644 index cd66464f2f..0000000000 --- a/test/files/run/macro-def-infer-return-type-b.flags +++ /dev/null @@ -1 +0,0 @@ --language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-def-infer-return-type-b/Impls_Macros_1.scala b/test/files/run/macro-def-infer-return-type-b/Impls_Macros_1.scala deleted file mode 100644 index 8a0f18c01b..0000000000 --- a/test/files/run/macro-def-infer-return-type-b/Impls_Macros_1.scala +++ /dev/null @@ -1,10 +0,0 @@ -import scala.reflect.macros.{Context => Ctx} - -object Impls { - def foo[T](c: Ctx)(x: c.Expr[T]) = - throw new Error("an implementation is missing") -} - -object Macros { - def foo[T](x: T) = macro Impls.foo[T] -} \ No newline at end of file diff --git a/test/files/run/macro-def-infer-return-type-b/Test_2.scala b/test/files/run/macro-def-infer-return-type-b/Test_2.scala deleted file mode 100644 index 9e57b90b57..0000000000 --- a/test/files/run/macro-def-infer-return-type-b/Test_2.scala +++ /dev/null @@ -1,8 +0,0 @@ -object Test extends App { - import scala.reflect.runtime.universe._ - import scala.reflect.runtime.{currentMirror => cm} - import scala.tools.reflect.ToolBox - val tree = Apply(Select(Ident(TermName("Macros")), TermName("foo")), List(Literal(Constant(42)))) - try cm.mkToolBox().eval(tree) - catch { case ex: Throwable => println(ex.getMessage) } -} diff --git a/test/files/run/macro-def-infer-return-type-c.check b/test/files/run/macro-def-infer-return-type-c.check deleted file mode 100644 index f70d7bba4a..0000000000 --- a/test/files/run/macro-def-infer-return-type-c.check +++ /dev/null @@ -1 +0,0 @@ -42 \ No newline at end of file diff --git a/test/files/run/macro-def-infer-return-type-c.flags b/test/files/run/macro-def-infer-return-type-c.flags deleted file mode 100644 index cd66464f2f..0000000000 --- a/test/files/run/macro-def-infer-return-type-c.flags +++ /dev/null @@ -1 +0,0 @@ --language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-def-infer-return-type-c/Impls_1.scala b/test/files/run/macro-def-infer-return-type-c/Impls_1.scala deleted file mode 100644 index 78db67eebf..0000000000 --- a/test/files/run/macro-def-infer-return-type-c/Impls_1.scala +++ /dev/null @@ -1,5 +0,0 @@ -import scala.reflect.macros.{Context => Ctx} - -object Impls { - def foo[T](c: Ctx)(x: c.Expr[T]): c.Expr[T] = x -} diff --git a/test/files/run/macro-def-infer-return-type-c/Macros_Test_2.scala b/test/files/run/macro-def-infer-return-type-c/Macros_Test_2.scala deleted file mode 100644 index 967d16f6de..0000000000 --- a/test/files/run/macro-def-infer-return-type-c/Macros_Test_2.scala +++ /dev/null @@ -1,4 +0,0 @@ -object Test extends App { - def foo[T](x: T) = macro Impls.foo[T] - println(foo(42)) -} \ No newline at end of file diff --git a/test/files/run/macro-def-infer-return-type.check b/test/files/run/macro-def-infer-return-type.check new file mode 100644 index 0000000000..308e881960 --- /dev/null +++ b/test/files/run/macro-def-infer-return-type.check @@ -0,0 +1,8 @@ +42 +reflective compilation has failed: + +exception during macro expansion: +java.lang.Error: an implementation is missing + at Impls2$.foo(Impls_1.scala:9) + +42 diff --git a/test/files/run/macro-def-infer-return-type.flags b/test/files/run/macro-def-infer-return-type.flags new file mode 100644 index 0000000000..cd66464f2f --- /dev/null +++ b/test/files/run/macro-def-infer-return-type.flags @@ -0,0 +1 @@ +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-def-infer-return-type/Impls_1.scala b/test/files/run/macro-def-infer-return-type/Impls_1.scala new file mode 100644 index 0000000000..f8636fe725 --- /dev/null +++ b/test/files/run/macro-def-infer-return-type/Impls_1.scala @@ -0,0 +1,14 @@ +import scala.reflect.macros.Context + +object Impls1 { + def foo(c: Context)(x: c.Expr[Int]) = x +} + +object Impls2 { + def foo[T](c: Context)(x: c.Expr[T]) = + throw new Error("an implementation is missing") +} + +object Impls3 { + def foo[T](c: Context)(x: c.Expr[T]): c.Expr[T] = x +} diff --git a/test/files/run/macro-def-infer-return-type/Macros_Test_2.scala b/test/files/run/macro-def-infer-return-type/Macros_Test_2.scala new file mode 100644 index 0000000000..f579586b7f --- /dev/null +++ b/test/files/run/macro-def-infer-return-type/Macros_Test_2.scala @@ -0,0 +1,24 @@ +object Macros1 { + def foo(x: Int) = macro Impls1.foo +} + +object Macros2 { + def foo[T](x: T) = macro Impls2.foo[T] +} + +object Macros3 { + def foo[T](x: T) = macro Impls3.foo[T] +} + +object Test extends App { + println(Macros1.foo(42)) + + import scala.reflect.runtime.universe._ + import scala.reflect.runtime.{currentMirror => cm} + import scala.tools.reflect.ToolBox + val tree = Apply(Select(Ident(TermName("Macros2")), TermName("foo")), List(Literal(Constant(42)))) + try cm.mkToolBox().eval(tree) + catch { case ex: Throwable => println(ex.getMessage) } + + println(Macros3.foo(42)) +} diff --git a/test/files/run/macro-def-path-dependent-a.check b/test/files/run/macro-def-path-dependent-a.check deleted file mode 100644 index 7658ad2c24..0000000000 --- a/test/files/run/macro-def-path-dependent-a.check +++ /dev/null @@ -1 +0,0 @@ -it works diff --git a/test/files/run/macro-def-path-dependent-a.flags b/test/files/run/macro-def-path-dependent-a.flags deleted file mode 100644 index cd66464f2f..0000000000 --- a/test/files/run/macro-def-path-dependent-a.flags +++ /dev/null @@ -1 +0,0 @@ --language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-def-path-dependent-a/Impls_Macros_1.scala b/test/files/run/macro-def-path-dependent-a/Impls_Macros_1.scala deleted file mode 100644 index 3a91e41ff9..0000000000 --- a/test/files/run/macro-def-path-dependent-a/Impls_Macros_1.scala +++ /dev/null @@ -1,21 +0,0 @@ -import scala.reflect.macros.{Context => Ctx} - -trait Exprs { - self: Universe => - - class Expr[T] -} - -trait Reifiers { - self: Universe => - - type Expr[T] - - def reify[T](expr: T) = macro Impls.reify[T] -} - -trait Universe extends Exprs with Reifiers - -object Impls { - def reify[T](cc: Ctx{ type PrefixType = Reifiers })(expr: cc.Expr[T]): cc.Expr[cc.prefix.value.Expr[T]] = ??? -} diff --git a/test/files/run/macro-def-path-dependent-a/Test_2.scala b/test/files/run/macro-def-path-dependent-a/Test_2.scala deleted file mode 100644 index 7dffc5107d..0000000000 --- a/test/files/run/macro-def-path-dependent-a/Test_2.scala +++ /dev/null @@ -1,3 +0,0 @@ -object Test extends App { - println("it works") -} \ No newline at end of file diff --git a/test/files/run/macro-def-path-dependent-b.check b/test/files/run/macro-def-path-dependent-b.check deleted file mode 100644 index 7658ad2c24..0000000000 --- a/test/files/run/macro-def-path-dependent-b.check +++ /dev/null @@ -1 +0,0 @@ -it works diff --git a/test/files/run/macro-def-path-dependent-b.flags b/test/files/run/macro-def-path-dependent-b.flags deleted file mode 100644 index cd66464f2f..0000000000 --- a/test/files/run/macro-def-path-dependent-b.flags +++ /dev/null @@ -1 +0,0 @@ --language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-def-path-dependent-b/Impls_Macros_1.scala b/test/files/run/macro-def-path-dependent-b/Impls_Macros_1.scala deleted file mode 100644 index cf9f9ebd0e..0000000000 --- a/test/files/run/macro-def-path-dependent-b/Impls_Macros_1.scala +++ /dev/null @@ -1,20 +0,0 @@ -import scala.reflect.macros.{Context => Ctx} - -trait Exprs { - self: Universe => - - class Expr[T] -} - -trait Reifiers { - self: Universe => - -} - -trait Universe extends Exprs with Reifiers { - def reify[T](expr: T) = macro Impls.reify[T] -} - -object Impls { - def reify[T](cc: Ctx{ type PrefixType = Universe })(expr: cc.Expr[T]): cc.Expr[cc.prefix.value.Expr[T]] = ??? -} diff --git a/test/files/run/macro-def-path-dependent-b/Test_2.scala b/test/files/run/macro-def-path-dependent-b/Test_2.scala deleted file mode 100644 index 7dffc5107d..0000000000 --- a/test/files/run/macro-def-path-dependent-b/Test_2.scala +++ /dev/null @@ -1,3 +0,0 @@ -object Test extends App { - println("it works") -} \ No newline at end of file diff --git a/test/files/run/macro-def-path-dependent-c.check b/test/files/run/macro-def-path-dependent-c.check deleted file mode 100644 index 7658ad2c24..0000000000 --- a/test/files/run/macro-def-path-dependent-c.check +++ /dev/null @@ -1 +0,0 @@ -it works diff --git a/test/files/run/macro-def-path-dependent-c.flags b/test/files/run/macro-def-path-dependent-c.flags deleted file mode 100644 index cd66464f2f..0000000000 --- a/test/files/run/macro-def-path-dependent-c.flags +++ /dev/null @@ -1 +0,0 @@ --language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-def-path-dependent-c/Impls_Macros_1.scala b/test/files/run/macro-def-path-dependent-c/Impls_Macros_1.scala deleted file mode 100644 index 6cb374d9ba..0000000000 --- a/test/files/run/macro-def-path-dependent-c/Impls_Macros_1.scala +++ /dev/null @@ -1,20 +0,0 @@ -import scala.reflect.macros.{Context => Ctx} - -trait Exprs { - self: Universe => - - class Expr[T] -} - -trait Reifiers { - self: Universe => - -} - -trait Universe extends Exprs with Reifiers { - def reify[T](expr: T): Expr[T] = macro Impls.reify[T] -} - -object Impls { - def reify[T](cc: Ctx{ type PrefixType = Universe })(expr: cc.Expr[T]): cc.Expr[cc.prefix.value.Expr[T]] = ??? -} diff --git a/test/files/run/macro-def-path-dependent-c/Test_2.scala b/test/files/run/macro-def-path-dependent-c/Test_2.scala deleted file mode 100644 index 7dffc5107d..0000000000 --- a/test/files/run/macro-def-path-dependent-c/Test_2.scala +++ /dev/null @@ -1,3 +0,0 @@ -object Test extends App { - println("it works") -} \ No newline at end of file diff --git a/test/files/run/macro-def-path-dependent-d1.check b/test/files/run/macro-def-path-dependent-d1.check deleted file mode 100644 index 7658ad2c24..0000000000 --- a/test/files/run/macro-def-path-dependent-d1.check +++ /dev/null @@ -1 +0,0 @@ -it works diff --git a/test/files/run/macro-def-path-dependent-d1.flags b/test/files/run/macro-def-path-dependent-d1.flags deleted file mode 100644 index cd66464f2f..0000000000 --- a/test/files/run/macro-def-path-dependent-d1.flags +++ /dev/null @@ -1 +0,0 @@ --language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-def-path-dependent-d1/Impls_Macros_1.scala b/test/files/run/macro-def-path-dependent-d1/Impls_Macros_1.scala deleted file mode 100644 index 69d9708b2a..0000000000 --- a/test/files/run/macro-def-path-dependent-d1/Impls_Macros_1.scala +++ /dev/null @@ -1,9 +0,0 @@ -import scala.reflect.runtime.universe._ -import scala.reflect.macros.Context -import scala.reflect.api.Universe - -object Test { - def materializeTypeTag[T](u: Universe)(e: T) = macro materializeTypeTag_impl[T] - - def materializeTypeTag_impl[T: c.WeakTypeTag](c: Context)(u: c.Expr[Universe])(e: c.Expr[T]): c.Expr[u.value.TypeTag[T]] = ??? -} \ No newline at end of file diff --git a/test/files/run/macro-def-path-dependent-d1/Test_2.scala b/test/files/run/macro-def-path-dependent-d1/Test_2.scala deleted file mode 100644 index 7dffc5107d..0000000000 --- a/test/files/run/macro-def-path-dependent-d1/Test_2.scala +++ /dev/null @@ -1,3 +0,0 @@ -object Test extends App { - println("it works") -} \ No newline at end of file diff --git a/test/files/run/macro-def-path-dependent-d2.check b/test/files/run/macro-def-path-dependent-d2.check deleted file mode 100644 index 7658ad2c24..0000000000 --- a/test/files/run/macro-def-path-dependent-d2.check +++ /dev/null @@ -1 +0,0 @@ -it works diff --git a/test/files/run/macro-def-path-dependent-d2.flags b/test/files/run/macro-def-path-dependent-d2.flags deleted file mode 100644 index cd66464f2f..0000000000 --- a/test/files/run/macro-def-path-dependent-d2.flags +++ /dev/null @@ -1 +0,0 @@ --language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-def-path-dependent-d2/Impls_1.scala b/test/files/run/macro-def-path-dependent-d2/Impls_1.scala deleted file mode 100644 index 7fa9c3579e..0000000000 --- a/test/files/run/macro-def-path-dependent-d2/Impls_1.scala +++ /dev/null @@ -1,7 +0,0 @@ -import scala.reflect.runtime.universe._ -import scala.reflect.macros.Context -import scala.reflect.api.Universe - -object Impls { - def materializeTypeTag_impl[T: c.WeakTypeTag](c: Context)(u: c.Expr[Universe])(e: c.Expr[T]): c.Expr[u.value.TypeTag[T]] = ??? -} \ No newline at end of file diff --git a/test/files/run/macro-def-path-dependent-d2/Macros_2.scala b/test/files/run/macro-def-path-dependent-d2/Macros_2.scala deleted file mode 100644 index 65ce4d8bd2..0000000000 --- a/test/files/run/macro-def-path-dependent-d2/Macros_2.scala +++ /dev/null @@ -1,7 +0,0 @@ -import scala.reflect.runtime.universe._ -import scala.reflect.macros.Context -import scala.reflect.api.Universe - -object Macros { - def materializeTypeTag[T](u: Universe)(e: T) = macro Impls.materializeTypeTag_impl[T] -} \ No newline at end of file diff --git a/test/files/run/macro-def-path-dependent-d2/Test_3.scala b/test/files/run/macro-def-path-dependent-d2/Test_3.scala deleted file mode 100644 index 7dffc5107d..0000000000 --- a/test/files/run/macro-def-path-dependent-d2/Test_3.scala +++ /dev/null @@ -1,3 +0,0 @@ -object Test extends App { - println("it works") -} \ No newline at end of file diff --git a/test/files/run/macro-def-path-dependent.check b/test/files/run/macro-def-path-dependent.check new file mode 100644 index 0000000000..7658ad2c24 --- /dev/null +++ b/test/files/run/macro-def-path-dependent.check @@ -0,0 +1 @@ +it works diff --git a/test/files/run/macro-def-path-dependent.flags b/test/files/run/macro-def-path-dependent.flags new file mode 100644 index 0000000000..cd66464f2f --- /dev/null +++ b/test/files/run/macro-def-path-dependent.flags @@ -0,0 +1 @@ +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-def-path-dependent/Dummy.scala b/test/files/run/macro-def-path-dependent/Dummy.scala new file mode 100644 index 0000000000..7dffc5107d --- /dev/null +++ b/test/files/run/macro-def-path-dependent/Dummy.scala @@ -0,0 +1,3 @@ +object Test extends App { + println("it works") +} \ No newline at end of file diff --git a/test/files/run/macro-def-path-dependent/Test_1.scala b/test/files/run/macro-def-path-dependent/Test_1.scala new file mode 100644 index 0000000000..06c15e16c9 --- /dev/null +++ b/test/files/run/macro-def-path-dependent/Test_1.scala @@ -0,0 +1,23 @@ +package test1 + +import scala.reflect.macros.{Context => Ctx} + +trait Exprs { + self: Universe => + + class Expr[T] +} + +trait Reifiers { + self: Universe => + + type Expr[T] + + def reify[T](expr: T) = macro Impls.reify[T] +} + +trait Universe extends Exprs with Reifiers + +object Impls { + def reify[T](cc: Ctx{ type PrefixType = Reifiers })(expr: cc.Expr[T]): cc.Expr[cc.prefix.value.Expr[T]] = ??? +} diff --git a/test/files/run/macro-def-path-dependent/Test_2.scala b/test/files/run/macro-def-path-dependent/Test_2.scala new file mode 100644 index 0000000000..f1e9909981 --- /dev/null +++ b/test/files/run/macro-def-path-dependent/Test_2.scala @@ -0,0 +1,22 @@ +package test2 + +import scala.reflect.macros.{Context => Ctx} + +trait Exprs { + self: Universe => + + class Expr[T] +} + +trait Reifiers { + self: Universe => + +} + +trait Universe extends Exprs with Reifiers { + def reify[T](expr: T) = macro Impls.reify[T] +} + +object Impls { + def reify[T](cc: Ctx{ type PrefixType = Universe })(expr: cc.Expr[T]): cc.Expr[cc.prefix.value.Expr[T]] = ??? +} diff --git a/test/files/run/macro-def-path-dependent/Test_3.scala b/test/files/run/macro-def-path-dependent/Test_3.scala new file mode 100644 index 0000000000..9f5efe5e47 --- /dev/null +++ b/test/files/run/macro-def-path-dependent/Test_3.scala @@ -0,0 +1,22 @@ +package test3 + +import scala.reflect.macros.{Context => Ctx} + +trait Exprs { + self: Universe => + + class Expr[T] +} + +trait Reifiers { + self: Universe => + +} + +trait Universe extends Exprs with Reifiers { + def reify[T](expr: T): Expr[T] = macro Impls.reify[T] +} + +object Impls { + def reify[T](cc: Ctx{ type PrefixType = Universe })(expr: cc.Expr[T]): cc.Expr[cc.prefix.value.Expr[T]] = ??? +} diff --git a/test/files/run/macro-def-path-dependent/Test_4.scala b/test/files/run/macro-def-path-dependent/Test_4.scala new file mode 100644 index 0000000000..3af920d739 --- /dev/null +++ b/test/files/run/macro-def-path-dependent/Test_4.scala @@ -0,0 +1,11 @@ +package test4 + +import scala.reflect.runtime.universe._ +import scala.reflect.macros.Context +import scala.reflect.api.Universe + +object Test { + def materializeTypeTag[T](u: Universe)(e: T) = macro materializeTypeTag_impl[T] + + def materializeTypeTag_impl[T: c.WeakTypeTag](c: Context)(u: c.Expr[Universe])(e: c.Expr[T]): c.Expr[u.value.TypeTag[T]] = ??? +} \ No newline at end of file diff --git a/test/files/run/macro-def-path-dependent/Test_5.scala b/test/files/run/macro-def-path-dependent/Test_5.scala new file mode 100644 index 0000000000..bc32fb92de --- /dev/null +++ b/test/files/run/macro-def-path-dependent/Test_5.scala @@ -0,0 +1,9 @@ +package test56 + +import scala.reflect.runtime.universe._ +import scala.reflect.macros.Context +import scala.reflect.api.Universe + +object Impls { + def materializeTypeTag_impl[T: c.WeakTypeTag](c: Context)(u: c.Expr[Universe])(e: c.Expr[T]): c.Expr[u.value.TypeTag[T]] = ??? +} \ No newline at end of file diff --git a/test/files/run/macro-def-path-dependent/Test_6.scala b/test/files/run/macro-def-path-dependent/Test_6.scala new file mode 100644 index 0000000000..6267743473 --- /dev/null +++ b/test/files/run/macro-def-path-dependent/Test_6.scala @@ -0,0 +1,9 @@ +package test56 + +import scala.reflect.runtime.universe._ +import scala.reflect.macros.Context +import scala.reflect.api.Universe + +object Macros { + def materializeTypeTag[T](u: Universe)(e: T) = macro Impls.materializeTypeTag_impl[T] +} \ No newline at end of file diff --git a/test/files/run/macro-expand-nullary-generic.check b/test/files/run/macro-expand-nullary-generic.check index 42976f4baf..0470d239dc 100644 --- a/test/files/run/macro-expand-nullary-generic.check +++ b/test/files/run/macro-expand-nullary-generic.check @@ -1,6 +1,6 @@ -it works WeakTypeTag[Int] -it works WeakTypeTag[Int] -it works WeakTypeTag[Int] -it works WeakTypeTag[Int] -it works WeakTypeTag[Int] +fooNullary[Int] +fooEmpty[Int] +fooEmpty[Int] +barNullary[Int] +barEmpty[Int] kkthxbai diff --git a/test/files/run/macro-expand-nullary-generic/Impls_1.scala b/test/files/run/macro-expand-nullary-generic/Impls_1.scala index 39a9db0e14..5dfdd5c539 100644 --- a/test/files/run/macro-expand-nullary-generic/Impls_1.scala +++ b/test/files/run/macro-expand-nullary-generic/Impls_1.scala @@ -2,14 +2,14 @@ import scala.reflect.runtime.universe._ import scala.reflect.macros.{Context => Ctx} object Impls { - def impl[T: c.WeakTypeTag](c: Ctx) = { + def impl[T: c.WeakTypeTag](c: Ctx)(meth: String) = { import c.universe._ - val body = Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant("it works " + implicitly[c.WeakTypeTag[T]])))) + val body = Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant(s"$meth[${c.weakTypeOf[T]}]")))) c.Expr[Unit](body) } - def fooNullary[T: c.WeakTypeTag](c: Ctx) = impl[T](c) - def fooEmpty[T: c.WeakTypeTag](c: Ctx)() = impl[T](c) - def barNullary[T: c.WeakTypeTag](c: Ctx)(x: c.Expr[Int]) = impl[T](c) - def barEmpty[T: c.WeakTypeTag](c: Ctx)(x: c.Expr[Int])() = impl[T](c) + def fooNullary[T: c.WeakTypeTag](c: Ctx) = impl[T](c)("fooNullary") + def fooEmpty[T: c.WeakTypeTag](c: Ctx)() = impl[T](c)("fooEmpty") + def barNullary[T: c.WeakTypeTag](c: Ctx)(x: c.Expr[Int]) = impl[T](c)("barNullary") + def barEmpty[T: c.WeakTypeTag](c: Ctx)(x: c.Expr[Int])() = impl[T](c)("barEmpty") } \ No newline at end of file diff --git a/test/files/run/macro-expand-nullary-nongeneric.check b/test/files/run/macro-expand-nullary-nongeneric.check index 9ab5f3a2bc..cb7e766394 100644 --- a/test/files/run/macro-expand-nullary-nongeneric.check +++ b/test/files/run/macro-expand-nullary-nongeneric.check @@ -1,6 +1,6 @@ -it works -it works -it works -it works -it works +fooNullary +fooEmpty +fooEmpty +barNullary +barEmpty kkthxbai diff --git a/test/files/run/macro-expand-nullary-nongeneric/Impls_1.scala b/test/files/run/macro-expand-nullary-nongeneric/Impls_1.scala index 41e50acc86..d23c671c84 100644 --- a/test/files/run/macro-expand-nullary-nongeneric/Impls_1.scala +++ b/test/files/run/macro-expand-nullary-nongeneric/Impls_1.scala @@ -1,14 +1,15 @@ +import scala.reflect.runtime.universe._ import scala.reflect.macros.{Context => Ctx} object Impls { - def impl(c: Ctx) = { + def impl(c: Ctx)(meth: String) = { import c.universe._ - val body = Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant("it works")))) + val body = Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant(meth)))) c.Expr[Unit](body) } - def fooNullary(c: Ctx) = impl(c) - def fooEmpty(c: Ctx)() = impl(c) - def barNullary(c: Ctx)(x: c.Expr[Int]) = impl(c) - def barEmpty(c: Ctx)(x: c.Expr[Int])() = impl(c) + def fooNullary(c: Ctx) = impl(c)("fooNullary") + def fooEmpty(c: Ctx)() = impl(c)("fooEmpty") + def barNullary(c: Ctx)(x: c.Expr[Int]) = impl(c)("barNullary") + def barEmpty(c: Ctx)(x: c.Expr[Int])() = impl(c)("barEmpty") } \ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-bounds-a.check b/test/files/run/macro-expand-tparams-bounds-a.check deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/test/files/run/macro-expand-tparams-bounds-a.flags b/test/files/run/macro-expand-tparams-bounds-a.flags deleted file mode 100644 index cd66464f2f..0000000000 --- a/test/files/run/macro-expand-tparams-bounds-a.flags +++ /dev/null @@ -1 +0,0 @@ --language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-bounds-a/Impls_1.scala b/test/files/run/macro-expand-tparams-bounds-a/Impls_1.scala deleted file mode 100644 index 9b8dafaa97..0000000000 --- a/test/files/run/macro-expand-tparams-bounds-a/Impls_1.scala +++ /dev/null @@ -1,5 +0,0 @@ -import scala.reflect.macros.{Context => Ctx} - -object Impls { - def foo[U <: String](c: Ctx): c.Expr[Unit] = c.literalUnit -} diff --git a/test/files/run/macro-expand-tparams-bounds-a/Macros_Test_2.scala b/test/files/run/macro-expand-tparams-bounds-a/Macros_Test_2.scala deleted file mode 100644 index b498e6f65b..0000000000 --- a/test/files/run/macro-expand-tparams-bounds-a/Macros_Test_2.scala +++ /dev/null @@ -1,8 +0,0 @@ -object Macros { - def foo[U <: String] = macro Impls.foo[U] -} - -object Test extends App { - import Macros._ - foo[String] -} \ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-bounds-b.check b/test/files/run/macro-expand-tparams-bounds-b.check deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/test/files/run/macro-expand-tparams-bounds-b.flags b/test/files/run/macro-expand-tparams-bounds-b.flags deleted file mode 100644 index cd66464f2f..0000000000 --- a/test/files/run/macro-expand-tparams-bounds-b.flags +++ /dev/null @@ -1 +0,0 @@ --language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-bounds-b/Impls_1.scala b/test/files/run/macro-expand-tparams-bounds-b/Impls_1.scala deleted file mode 100644 index c11c89151c..0000000000 --- a/test/files/run/macro-expand-tparams-bounds-b/Impls_1.scala +++ /dev/null @@ -1,7 +0,0 @@ -import scala.reflect.macros.{Context => Ctx} - -class C - -object Impls { - def foo[U <: C](c: Ctx): c.Expr[Unit] = c.literalUnit -} diff --git a/test/files/run/macro-expand-tparams-bounds-b/Macros_Test_2.scala b/test/files/run/macro-expand-tparams-bounds-b/Macros_Test_2.scala deleted file mode 100644 index 1a261e9f73..0000000000 --- a/test/files/run/macro-expand-tparams-bounds-b/Macros_Test_2.scala +++ /dev/null @@ -1,10 +0,0 @@ -class D extends C - -object Macros { - def foo[T <: D] = macro Impls.foo[T] -} - -object Test extends App { - import Macros._ - foo[D] -} \ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-bounds.check b/test/files/run/macro-expand-tparams-bounds.check new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/files/run/macro-expand-tparams-bounds.flags b/test/files/run/macro-expand-tparams-bounds.flags new file mode 100644 index 0000000000..cd66464f2f --- /dev/null +++ b/test/files/run/macro-expand-tparams-bounds.flags @@ -0,0 +1 @@ +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-bounds/Impls_1.scala b/test/files/run/macro-expand-tparams-bounds/Impls_1.scala new file mode 100644 index 0000000000..f9103aaf8f --- /dev/null +++ b/test/files/run/macro-expand-tparams-bounds/Impls_1.scala @@ -0,0 +1,12 @@ +import scala.reflect.macros.Context + +object Impls1 { + def foo[U <: String](c: Context): c.Expr[Unit] = c.literalUnit +} + +class C +class D extends C + +object Impls2 { + def foo[U <: C](c: Context): c.Expr[Unit] = c.literalUnit +} diff --git a/test/files/run/macro-expand-tparams-bounds/Macros_Test_2.scala b/test/files/run/macro-expand-tparams-bounds/Macros_Test_2.scala new file mode 100644 index 0000000000..37a4bcb2b9 --- /dev/null +++ b/test/files/run/macro-expand-tparams-bounds/Macros_Test_2.scala @@ -0,0 +1,12 @@ +object Macros1 { + def foo[U <: String] = macro Impls1.foo[U] +} + +object Macros2 { + def foo[T <: D] = macro Impls2.foo[T] +} + +object Test extends App { + Macros1.foo[String] + Macros2.foo[D] +} diff --git a/test/files/run/macro-expand-tparams-only-in-impl.flags b/test/files/run/macro-expand-tparams-only-in-impl.flags deleted file mode 100644 index cd66464f2f..0000000000 --- a/test/files/run/macro-expand-tparams-only-in-impl.flags +++ /dev/null @@ -1 +0,0 @@ --language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-only-in-impl/Impls_1.scala b/test/files/run/macro-expand-tparams-only-in-impl/Impls_1.scala deleted file mode 100644 index 9b8dafaa97..0000000000 --- a/test/files/run/macro-expand-tparams-only-in-impl/Impls_1.scala +++ /dev/null @@ -1,5 +0,0 @@ -import scala.reflect.macros.{Context => Ctx} - -object Impls { - def foo[U <: String](c: Ctx): c.Expr[Unit] = c.literalUnit -} diff --git a/test/files/run/macro-expand-tparams-only-in-impl/Macros_Test_2.scala b/test/files/run/macro-expand-tparams-only-in-impl/Macros_Test_2.scala deleted file mode 100644 index 218c7aec7f..0000000000 --- a/test/files/run/macro-expand-tparams-only-in-impl/Macros_Test_2.scala +++ /dev/null @@ -1,8 +0,0 @@ -object Macros { - def foo = macro Impls.foo[String] -} - -object Test extends App { - import Macros._ - foo -} \ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-optional.check b/test/files/run/macro-expand-tparams-optional.check deleted file mode 100644 index b4a0f394c1..0000000000 --- a/test/files/run/macro-expand-tparams-optional.check +++ /dev/null @@ -1 +0,0 @@ -don't know U diff --git a/test/files/run/macro-expand-tparams-optional.flags b/test/files/run/macro-expand-tparams-optional.flags deleted file mode 100644 index cd66464f2f..0000000000 --- a/test/files/run/macro-expand-tparams-optional.flags +++ /dev/null @@ -1 +0,0 @@ --language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-optional/Impls_1.scala b/test/files/run/macro-expand-tparams-optional/Impls_1.scala deleted file mode 100644 index ace7a6cd26..0000000000 --- a/test/files/run/macro-expand-tparams-optional/Impls_1.scala +++ /dev/null @@ -1,9 +0,0 @@ -import scala.reflect.macros.{Context => Ctx} - -object Impls { - def foo[U](c: Ctx) = { - import c.universe._ - val body = Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant("don't know U")))) - c.Expr[Unit](body) - } -} \ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-optional/Macros_Test_2.scala b/test/files/run/macro-expand-tparams-optional/Macros_Test_2.scala deleted file mode 100644 index e72c27881a..0000000000 --- a/test/files/run/macro-expand-tparams-optional/Macros_Test_2.scala +++ /dev/null @@ -1,4 +0,0 @@ -object Test extends App { - def foo[U] = macro Impls.foo[U] - foo[Int] -} \ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-prefix-a.check b/test/files/run/macro-expand-tparams-prefix-a.check deleted file mode 100644 index ca44a4f652..0000000000 --- a/test/files/run/macro-expand-tparams-prefix-a.check +++ /dev/null @@ -1,4 +0,0 @@ -WeakTypeTag[Int] -WeakTypeTag[Int] -WeakTypeTag[String] -WeakTypeTag[Boolean] diff --git a/test/files/run/macro-expand-tparams-prefix-a.flags b/test/files/run/macro-expand-tparams-prefix-a.flags deleted file mode 100644 index cd66464f2f..0000000000 --- a/test/files/run/macro-expand-tparams-prefix-a.flags +++ /dev/null @@ -1 +0,0 @@ --language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-prefix-a/Impls_1.scala b/test/files/run/macro-expand-tparams-prefix-a/Impls_1.scala deleted file mode 100644 index c729aada51..0000000000 --- a/test/files/run/macro-expand-tparams-prefix-a/Impls_1.scala +++ /dev/null @@ -1,11 +0,0 @@ -import scala.reflect.runtime.universe._ -import scala.reflect.macros.{Context => Ctx} - -object Impls { - def foo[U: c.WeakTypeTag](c: Ctx)(x: c.Expr[U]) = { - import c.universe._ - val U = implicitly[c.WeakTypeTag[U]] - val body = Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant(U.toString)))) - c.Expr[Unit](body) - } -} \ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-prefix-a/Macros_Test_2.scala b/test/files/run/macro-expand-tparams-prefix-a/Macros_Test_2.scala deleted file mode 100644 index 81ccb7ff42..0000000000 --- a/test/files/run/macro-expand-tparams-prefix-a/Macros_Test_2.scala +++ /dev/null @@ -1,10 +0,0 @@ -object Test extends App { - class C[T] { - def foo[U](x: U) = macro Impls.foo[U] - } - - new C[Int]().foo(42) - new C[Boolean]().foo(42) - new C[Int]().foo("42") - new C[String]().foo(true) -} \ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-prefix-b.check b/test/files/run/macro-expand-tparams-prefix-b.check deleted file mode 100644 index 2ff2ce435d..0000000000 --- a/test/files/run/macro-expand-tparams-prefix-b.check +++ /dev/null @@ -1,2 +0,0 @@ -WeakTypeTag[Boolean] WeakTypeTag[Int] -WeakTypeTag[Boolean] WeakTypeTag[String] diff --git a/test/files/run/macro-expand-tparams-prefix-b.flags b/test/files/run/macro-expand-tparams-prefix-b.flags deleted file mode 100644 index cd66464f2f..0000000000 --- a/test/files/run/macro-expand-tparams-prefix-b.flags +++ /dev/null @@ -1 +0,0 @@ --language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-prefix-b/Impls_1.scala b/test/files/run/macro-expand-tparams-prefix-b/Impls_1.scala deleted file mode 100644 index 8880d13b04..0000000000 --- a/test/files/run/macro-expand-tparams-prefix-b/Impls_1.scala +++ /dev/null @@ -1,12 +0,0 @@ -import scala.reflect.runtime.universe._ -import scala.reflect.macros.{Context => Ctx} - -object Impls { - def foo[T: c.WeakTypeTag, U: c.WeakTypeTag](c: Ctx)(x: c.Expr[U]) = { - import c.universe._ - val T = implicitly[c.WeakTypeTag[T]] - val U = implicitly[c.WeakTypeTag[U]] - val body = Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant(T.toString + " " + U.toString)))) - c.Expr[Unit](body) - } -} \ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-prefix-b/Macros_Test_2.scala b/test/files/run/macro-expand-tparams-prefix-b/Macros_Test_2.scala deleted file mode 100644 index a4a0acfe8b..0000000000 --- a/test/files/run/macro-expand-tparams-prefix-b/Macros_Test_2.scala +++ /dev/null @@ -1,10 +0,0 @@ -object Test extends App { - class C[T] { - def foo[U](x: U) = macro Impls.foo[T, U] - } - - object D extends C[Boolean] - - D.foo(42) - D.foo("42") -} \ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-prefix-c1.check b/test/files/run/macro-expand-tparams-prefix-c1.check deleted file mode 100644 index 0f24f74db1..0000000000 --- a/test/files/run/macro-expand-tparams-prefix-c1.check +++ /dev/null @@ -1,3 +0,0 @@ -WeakTypeTag[Int] -WeakTypeTag[String] -WeakTypeTag[Boolean] diff --git a/test/files/run/macro-expand-tparams-prefix-c1.flags b/test/files/run/macro-expand-tparams-prefix-c1.flags deleted file mode 100644 index cd66464f2f..0000000000 --- a/test/files/run/macro-expand-tparams-prefix-c1.flags +++ /dev/null @@ -1 +0,0 @@ --language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-prefix-c1/Impls_1.scala b/test/files/run/macro-expand-tparams-prefix-c1/Impls_1.scala deleted file mode 100644 index 2df42e969f..0000000000 --- a/test/files/run/macro-expand-tparams-prefix-c1/Impls_1.scala +++ /dev/null @@ -1,13 +0,0 @@ -import scala.reflect.runtime.universe._ -import scala.reflect.macros.{Context => Ctx} - -object Impls { - def foo[T, U: c.WeakTypeTag, V](c: Ctx)(implicit T: c.WeakTypeTag[T], V: c.WeakTypeTag[V]): c.Expr[Unit] = { - import c.universe._ - c.Expr(Block(List( - Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant(T.toString)))), - Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant(implicitly[c.WeakTypeTag[U]].toString)))), - Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant(V.toString))))), - Literal(Constant(())))) - } -} \ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-prefix-c1/Macros_Test_2.scala b/test/files/run/macro-expand-tparams-prefix-c1/Macros_Test_2.scala deleted file mode 100644 index 4fa0c8cb33..0000000000 --- a/test/files/run/macro-expand-tparams-prefix-c1/Macros_Test_2.scala +++ /dev/null @@ -1,11 +0,0 @@ -class D[T] { - class C[U] { - def foo[V] = macro Impls.foo[T, U, V] - } -} - -object Test extends App { - val outer1 = new D[Int] - val outer2 = new outer1.C[String] - outer2.foo[Boolean] -} \ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-prefix-c2.check b/test/files/run/macro-expand-tparams-prefix-c2.check deleted file mode 100644 index 0f24f74db1..0000000000 --- a/test/files/run/macro-expand-tparams-prefix-c2.check +++ /dev/null @@ -1,3 +0,0 @@ -WeakTypeTag[Int] -WeakTypeTag[String] -WeakTypeTag[Boolean] diff --git a/test/files/run/macro-expand-tparams-prefix-c2.flags b/test/files/run/macro-expand-tparams-prefix-c2.flags deleted file mode 100644 index cd66464f2f..0000000000 --- a/test/files/run/macro-expand-tparams-prefix-c2.flags +++ /dev/null @@ -1 +0,0 @@ --language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-prefix-c2/Impls_Macros_1.scala b/test/files/run/macro-expand-tparams-prefix-c2/Impls_Macros_1.scala deleted file mode 100644 index 08817708d4..0000000000 --- a/test/files/run/macro-expand-tparams-prefix-c2/Impls_Macros_1.scala +++ /dev/null @@ -1,19 +0,0 @@ -import scala.reflect.runtime.universe._ -import scala.reflect.macros.{Context => Ctx} - -object Impls { - def foo[T, U: c.WeakTypeTag, V](c: Ctx)(implicit T: c.WeakTypeTag[T], V: c.WeakTypeTag[V]): c.Expr[Unit] = { - import c.universe._ - c.Expr(Block(List( - Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant(T.toString)))), - Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant(implicitly[c.WeakTypeTag[U]].toString)))), - Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant(V.toString))))), - Literal(Constant(())))) - } -} - -class D[T] { - class C[U] { - def foo[V] = macro Impls.foo[T, U, V] - } -} \ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-prefix-c2/Test_2.scala b/test/files/run/macro-expand-tparams-prefix-c2/Test_2.scala deleted file mode 100644 index e729d4a536..0000000000 --- a/test/files/run/macro-expand-tparams-prefix-c2/Test_2.scala +++ /dev/null @@ -1,5 +0,0 @@ -object Test extends App { - val outer1 = new D[Int] - val outer2 = new outer1.C[String] - outer2.foo[Boolean] -} \ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-prefix-d1.check b/test/files/run/macro-expand-tparams-prefix-d1.check deleted file mode 100644 index 7832503256..0000000000 --- a/test/files/run/macro-expand-tparams-prefix-d1.check +++ /dev/null @@ -1,3 +0,0 @@ -WeakTypeTag[T] -WeakTypeTag[U] -WeakTypeTag[Boolean] diff --git a/test/files/run/macro-expand-tparams-prefix-d1.flags b/test/files/run/macro-expand-tparams-prefix-d1.flags deleted file mode 100644 index cd66464f2f..0000000000 --- a/test/files/run/macro-expand-tparams-prefix-d1.flags +++ /dev/null @@ -1 +0,0 @@ --language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-prefix-d1/Impls_1.scala b/test/files/run/macro-expand-tparams-prefix-d1/Impls_1.scala deleted file mode 100644 index 2df42e969f..0000000000 --- a/test/files/run/macro-expand-tparams-prefix-d1/Impls_1.scala +++ /dev/null @@ -1,13 +0,0 @@ -import scala.reflect.runtime.universe._ -import scala.reflect.macros.{Context => Ctx} - -object Impls { - def foo[T, U: c.WeakTypeTag, V](c: Ctx)(implicit T: c.WeakTypeTag[T], V: c.WeakTypeTag[V]): c.Expr[Unit] = { - import c.universe._ - c.Expr(Block(List( - Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant(T.toString)))), - Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant(implicitly[c.WeakTypeTag[U]].toString)))), - Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant(V.toString))))), - Literal(Constant(())))) - } -} \ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-prefix-d1/Macros_Test_2.scala b/test/files/run/macro-expand-tparams-prefix-d1/Macros_Test_2.scala deleted file mode 100644 index 8222a6d1e8..0000000000 --- a/test/files/run/macro-expand-tparams-prefix-d1/Macros_Test_2.scala +++ /dev/null @@ -1,11 +0,0 @@ -object Test extends App { - class D[T] { - class C[U] { - def foo[V] = macro Impls.foo[T, U, V] - foo[Boolean] - } - } - - val outer1 = new D[Int] - new outer1.C[String] -} \ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-prefix.check b/test/files/run/macro-expand-tparams-prefix.check new file mode 100644 index 0000000000..7397958066 --- /dev/null +++ b/test/files/run/macro-expand-tparams-prefix.check @@ -0,0 +1,20 @@ +===Macros1=== +WeakTypeTag[Int] +WeakTypeTag[Int] +WeakTypeTag[String] +WeakTypeTag[Boolean] +===Macros2=== +WeakTypeTag[Boolean] WeakTypeTag[Int] +WeakTypeTag[Boolean] WeakTypeTag[String] +===Macros3=== +WeakTypeTag[Int] +WeakTypeTag[String] +WeakTypeTag[Boolean] +===Macros4=== +WeakTypeTag[Int] +WeakTypeTag[String] +WeakTypeTag[Boolean] +===Macros5=== +WeakTypeTag[T] +WeakTypeTag[U] +WeakTypeTag[Boolean] diff --git a/test/files/run/macro-expand-tparams-prefix.flags b/test/files/run/macro-expand-tparams-prefix.flags new file mode 100644 index 0000000000..cd66464f2f --- /dev/null +++ b/test/files/run/macro-expand-tparams-prefix.flags @@ -0,0 +1 @@ +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-prefix/Impls_1.scala b/test/files/run/macro-expand-tparams-prefix/Impls_1.scala new file mode 100644 index 0000000000..e92396d1b4 --- /dev/null +++ b/test/files/run/macro-expand-tparams-prefix/Impls_1.scala @@ -0,0 +1,40 @@ +import scala.reflect.runtime.universe._ +import scala.reflect.macros.Context + +object Impls1 { + def foo[U: c.WeakTypeTag](c: Context)(x: c.Expr[U]) = { + import c.universe._ + val U = implicitly[c.WeakTypeTag[U]] + val body = Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant(U.toString)))) + c.Expr[Unit](body) + } +} + +object Impls2 { + def foo[T: c.WeakTypeTag, U: c.WeakTypeTag](c: Context)(x: c.Expr[U]) = { + import c.universe._ + val T = implicitly[c.WeakTypeTag[T]] + val U = implicitly[c.WeakTypeTag[U]] + val body = Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant(T.toString + " " + U.toString)))) + c.Expr[Unit](body) + } +} + +object Impls345 { + def foo[T, U: c.WeakTypeTag, V](c: Context)(implicit T: c.WeakTypeTag[T], V: c.WeakTypeTag[V]): c.Expr[Unit] = { + import c.universe._ + c.Expr(Block(List( + Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant(T.toString)))), + Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant(implicitly[c.WeakTypeTag[U]].toString)))), + Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant(V.toString))))), + Literal(Constant(())))) + } +} + +object Macros4 { + class D[T] { + class C[U] { + def foo[V] = macro Impls345.foo[T, U, V] + } + } +} diff --git a/test/files/run/macro-expand-tparams-prefix/Macros_Test_2.scala b/test/files/run/macro-expand-tparams-prefix/Macros_Test_2.scala new file mode 100644 index 0000000000..2b1730d36e --- /dev/null +++ b/test/files/run/macro-expand-tparams-prefix/Macros_Test_2.scala @@ -0,0 +1,57 @@ +object Macros1 { + class C[T] { + def foo[U](x: U) = macro Impls1.foo[U] + } +} + +object Macros2 { + class C[T] { + def foo[U](x: U) = macro Impls2.foo[T, U] + } +} + +object Macros3 { + class D[T] { + class C[U] { + def foo[V] = macro Impls345.foo[T, U, V] + } + } +} + +// object Macros4 is declared in Impls_1.scala + +object Macros5 { + class D[T] { + class C[U] { + def foo[V] = macro Impls345.foo[T, U, V] + foo[Boolean] + } + } +} + +object Test extends App { + println("===Macros1===") + new Macros1.C[Int]().foo(42) + new Macros1.C[Boolean]().foo(42) + new Macros1.C[Int]().foo("42") + new Macros1.C[String]().foo(true) + + println("===Macros2===") + object D2 extends Macros2.C[Boolean] + D2.foo(42) + D2.foo("42") + + println("===Macros3===") + val outer31 = new Macros3.D[Int] + val outer32 = new outer31.C[String] + outer32.foo[Boolean] + + println("===Macros4===") + val outer41 = new Macros4.D[Int] + val outer42 = new outer41.C[String] + outer42.foo[Boolean] + + println("===Macros5===") + val outer1 = new Macros5.D[Int] + new outer1.C[String] +} \ No newline at end of file diff --git a/test/files/run/macro-impl-tparam-only-in-impl.flags b/test/files/run/macro-impl-tparam-only-in-impl.flags new file mode 100644 index 0000000000..cd66464f2f --- /dev/null +++ b/test/files/run/macro-impl-tparam-only-in-impl.flags @@ -0,0 +1 @@ +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-impl-tparam-only-in-impl/Impls_1.scala b/test/files/run/macro-impl-tparam-only-in-impl/Impls_1.scala new file mode 100644 index 0000000000..9b8dafaa97 --- /dev/null +++ b/test/files/run/macro-impl-tparam-only-in-impl/Impls_1.scala @@ -0,0 +1,5 @@ +import scala.reflect.macros.{Context => Ctx} + +object Impls { + def foo[U <: String](c: Ctx): c.Expr[Unit] = c.literalUnit +} diff --git a/test/files/run/macro-impl-tparam-only-in-impl/Macros_Test_2.scala b/test/files/run/macro-impl-tparam-only-in-impl/Macros_Test_2.scala new file mode 100644 index 0000000000..218c7aec7f --- /dev/null +++ b/test/files/run/macro-impl-tparam-only-in-impl/Macros_Test_2.scala @@ -0,0 +1,8 @@ +object Macros { + def foo = macro Impls.foo[String] +} + +object Test extends App { + import Macros._ + foo +} \ No newline at end of file diff --git a/test/files/run/macro-impl-tparam-typetag-is-optional.check b/test/files/run/macro-impl-tparam-typetag-is-optional.check new file mode 100644 index 0000000000..b4a0f394c1 --- /dev/null +++ b/test/files/run/macro-impl-tparam-typetag-is-optional.check @@ -0,0 +1 @@ +don't know U diff --git a/test/files/run/macro-impl-tparam-typetag-is-optional.flags b/test/files/run/macro-impl-tparam-typetag-is-optional.flags new file mode 100644 index 0000000000..cd66464f2f --- /dev/null +++ b/test/files/run/macro-impl-tparam-typetag-is-optional.flags @@ -0,0 +1 @@ +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-impl-tparam-typetag-is-optional/Impls_1.scala b/test/files/run/macro-impl-tparam-typetag-is-optional/Impls_1.scala new file mode 100644 index 0000000000..ace7a6cd26 --- /dev/null +++ b/test/files/run/macro-impl-tparam-typetag-is-optional/Impls_1.scala @@ -0,0 +1,9 @@ +import scala.reflect.macros.{Context => Ctx} + +object Impls { + def foo[U](c: Ctx) = { + import c.universe._ + val body = Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant("don't know U")))) + c.Expr[Unit](body) + } +} \ No newline at end of file diff --git a/test/files/run/macro-impl-tparam-typetag-is-optional/Macros_Test_2.scala b/test/files/run/macro-impl-tparam-typetag-is-optional/Macros_Test_2.scala new file mode 100644 index 0000000000..e72c27881a --- /dev/null +++ b/test/files/run/macro-impl-tparam-typetag-is-optional/Macros_Test_2.scala @@ -0,0 +1,4 @@ +object Test extends App { + def foo[U] = macro Impls.foo[U] + foo[Int] +} \ No newline at end of file diff --git a/test/files/run/macro-term-declared-in-annotation.check b/test/files/run/macro-term-declared-in-annotation.check new file mode 100644 index 0000000000..7658ad2c24 --- /dev/null +++ b/test/files/run/macro-term-declared-in-annotation.check @@ -0,0 +1 @@ +it works diff --git a/test/files/run/macro-term-declared-in-annotation.flags b/test/files/run/macro-term-declared-in-annotation.flags new file mode 100644 index 0000000000..cd66464f2f --- /dev/null +++ b/test/files/run/macro-term-declared-in-annotation.flags @@ -0,0 +1 @@ +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-term-declared-in-annotation/Impls_1.scala b/test/files/run/macro-term-declared-in-annotation/Impls_1.scala new file mode 100644 index 0000000000..1ea06de679 --- /dev/null +++ b/test/files/run/macro-term-declared-in-annotation/Impls_1.scala @@ -0,0 +1,11 @@ +import scala.reflect.macros.{Context => Ctx} + +object Impls { + def foo(c: Ctx) = { + import c.{prefix => prefix} + import c.universe._ + val printPrefix = Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant("prefix = " + prefix)))) + val body = Block(List(printPrefix), Literal(Constant("this is deprecated"))) + c.Expr[String](body) + } +} \ No newline at end of file diff --git a/test/files/run/macro-term-declared-in-annotation/Macros_2.scala b/test/files/run/macro-term-declared-in-annotation/Macros_2.scala new file mode 100644 index 0000000000..40d71c62fb --- /dev/null +++ b/test/files/run/macro-term-declared-in-annotation/Macros_2.scala @@ -0,0 +1,8 @@ +class foo(val bar: String) extends annotation.StaticAnnotation + +object Api { + // foo in ann must have a different name + // otherwise, we get bitten by https://issues.scala-lang.org/browse/SI-5544 + @foo({def fooInAnn = macro Impls.foo; fooInAnn}) + def foo = println("it works") +} \ No newline at end of file diff --git a/test/files/run/macro-term-declared-in-annotation/Test_3.scala b/test/files/run/macro-term-declared-in-annotation/Test_3.scala new file mode 100644 index 0000000000..866487f028 --- /dev/null +++ b/test/files/run/macro-term-declared-in-annotation/Test_3.scala @@ -0,0 +1,3 @@ +object Test extends App { + Api.foo +} \ No newline at end of file diff --git a/test/files/run/macro-term-declared-in-anonymous.check b/test/files/run/macro-term-declared-in-anonymous.check new file mode 100644 index 0000000000..09b8d015a6 --- /dev/null +++ b/test/files/run/macro-term-declared-in-anonymous.check @@ -0,0 +1,2 @@ +prefix = Expr[Nothing](Test.this.macros) +it works diff --git a/test/files/run/macro-term-declared-in-anonymous.flags b/test/files/run/macro-term-declared-in-anonymous.flags new file mode 100644 index 0000000000..cd66464f2f --- /dev/null +++ b/test/files/run/macro-term-declared-in-anonymous.flags @@ -0,0 +1 @@ +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-term-declared-in-anonymous/Impls_1.scala b/test/files/run/macro-term-declared-in-anonymous/Impls_1.scala new file mode 100644 index 0000000000..348f3420f2 --- /dev/null +++ b/test/files/run/macro-term-declared-in-anonymous/Impls_1.scala @@ -0,0 +1,11 @@ +import scala.reflect.macros.{Context => Ctx} + +object Impls { + def foo(c: Ctx) = { + import c.{prefix => prefix} + import c.universe._ + val printPrefix = Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant("prefix = " + prefix)))) + val body = Block(List(printPrefix), Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant("it works"))))) + c.Expr[Unit](body) + } +} \ No newline at end of file diff --git a/test/files/run/macro-term-declared-in-anonymous/Macros_Test_2.scala b/test/files/run/macro-term-declared-in-anonymous/Macros_Test_2.scala new file mode 100644 index 0000000000..88cd29ae4f --- /dev/null +++ b/test/files/run/macro-term-declared-in-anonymous/Macros_Test_2.scala @@ -0,0 +1,6 @@ +import scala.language.reflectiveCalls + +object Test extends App { + val macros = new { def foo = macro Impls.foo } + macros.foo +} diff --git a/test/files/run/macro-term-declared-in-block.check b/test/files/run/macro-term-declared-in-block.check new file mode 100644 index 0000000000..5e687db8bf --- /dev/null +++ b/test/files/run/macro-term-declared-in-block.check @@ -0,0 +1,2 @@ +prefix = Expr[Nothing]() +it works diff --git a/test/files/run/macro-term-declared-in-block.flags b/test/files/run/macro-term-declared-in-block.flags new file mode 100644 index 0000000000..cd66464f2f --- /dev/null +++ b/test/files/run/macro-term-declared-in-block.flags @@ -0,0 +1 @@ +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-term-declared-in-block/Impls_1.scala b/test/files/run/macro-term-declared-in-block/Impls_1.scala new file mode 100644 index 0000000000..348f3420f2 --- /dev/null +++ b/test/files/run/macro-term-declared-in-block/Impls_1.scala @@ -0,0 +1,11 @@ +import scala.reflect.macros.{Context => Ctx} + +object Impls { + def foo(c: Ctx) = { + import c.{prefix => prefix} + import c.universe._ + val printPrefix = Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant("prefix = " + prefix)))) + val body = Block(List(printPrefix), Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant("it works"))))) + c.Expr[Unit](body) + } +} \ No newline at end of file diff --git a/test/files/run/macro-term-declared-in-block/Macros_Test_2.scala b/test/files/run/macro-term-declared-in-block/Macros_Test_2.scala new file mode 100644 index 0000000000..69088e24bc --- /dev/null +++ b/test/files/run/macro-term-declared-in-block/Macros_Test_2.scala @@ -0,0 +1,6 @@ +object Test extends App { + { + def foo = macro Impls.foo + foo + } +} \ No newline at end of file diff --git a/test/files/run/macro-term-declared-in-class-class.check b/test/files/run/macro-term-declared-in-class-class.check new file mode 100644 index 0000000000..47248d7af7 --- /dev/null +++ b/test/files/run/macro-term-declared-in-class-class.check @@ -0,0 +1,2 @@ +prefix = Expr[Nothing](new Test.this.outer.Macros()) +it works diff --git a/test/files/run/macro-term-declared-in-class-class.flags b/test/files/run/macro-term-declared-in-class-class.flags new file mode 100644 index 0000000000..cd66464f2f --- /dev/null +++ b/test/files/run/macro-term-declared-in-class-class.flags @@ -0,0 +1 @@ +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-term-declared-in-class-class/Impls_1.scala b/test/files/run/macro-term-declared-in-class-class/Impls_1.scala new file mode 100644 index 0000000000..348f3420f2 --- /dev/null +++ b/test/files/run/macro-term-declared-in-class-class/Impls_1.scala @@ -0,0 +1,11 @@ +import scala.reflect.macros.{Context => Ctx} + +object Impls { + def foo(c: Ctx) = { + import c.{prefix => prefix} + import c.universe._ + val printPrefix = Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant("prefix = " + prefix)))) + val body = Block(List(printPrefix), Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant("it works"))))) + c.Expr[Unit](body) + } +} \ No newline at end of file diff --git a/test/files/run/macro-term-declared-in-class-class/Macros_Test_2.scala b/test/files/run/macro-term-declared-in-class-class/Macros_Test_2.scala new file mode 100644 index 0000000000..871857a97f --- /dev/null +++ b/test/files/run/macro-term-declared-in-class-class/Macros_Test_2.scala @@ -0,0 +1,10 @@ +class Macros { + class Macros { + def foo = macro Impls.foo + } +} + +object Test extends App { + val outer = new Macros() + new outer.Macros().foo +} \ No newline at end of file diff --git a/test/files/run/macro-term-declared-in-class-object.check b/test/files/run/macro-term-declared-in-class-object.check new file mode 100644 index 0000000000..35af59e40f --- /dev/null +++ b/test/files/run/macro-term-declared-in-class-object.check @@ -0,0 +1,2 @@ +prefix = Expr[Nothing](Test.this.outer.Macros) +it works diff --git a/test/files/run/macro-term-declared-in-class-object.flags b/test/files/run/macro-term-declared-in-class-object.flags new file mode 100644 index 0000000000..cd66464f2f --- /dev/null +++ b/test/files/run/macro-term-declared-in-class-object.flags @@ -0,0 +1 @@ +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-term-declared-in-class-object/Impls_1.scala b/test/files/run/macro-term-declared-in-class-object/Impls_1.scala new file mode 100644 index 0000000000..348f3420f2 --- /dev/null +++ b/test/files/run/macro-term-declared-in-class-object/Impls_1.scala @@ -0,0 +1,11 @@ +import scala.reflect.macros.{Context => Ctx} + +object Impls { + def foo(c: Ctx) = { + import c.{prefix => prefix} + import c.universe._ + val printPrefix = Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant("prefix = " + prefix)))) + val body = Block(List(printPrefix), Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant("it works"))))) + c.Expr[Unit](body) + } +} \ No newline at end of file diff --git a/test/files/run/macro-term-declared-in-class-object/Macros_Test_2.scala b/test/files/run/macro-term-declared-in-class-object/Macros_Test_2.scala new file mode 100644 index 0000000000..994f9fe935 --- /dev/null +++ b/test/files/run/macro-term-declared-in-class-object/Macros_Test_2.scala @@ -0,0 +1,10 @@ +class Macros { + object Macros { + def foo = macro Impls.foo + } +} + +object Test extends App { + val outer = new Macros() + outer.Macros.foo +} \ No newline at end of file diff --git a/test/files/run/macro-term-declared-in-class.check b/test/files/run/macro-term-declared-in-class.check new file mode 100644 index 0000000000..a1c1d7af8b --- /dev/null +++ b/test/files/run/macro-term-declared-in-class.check @@ -0,0 +1,2 @@ +prefix = Expr[Nothing](new Macros()) +it works diff --git a/test/files/run/macro-term-declared-in-class.flags b/test/files/run/macro-term-declared-in-class.flags new file mode 100644 index 0000000000..cd66464f2f --- /dev/null +++ b/test/files/run/macro-term-declared-in-class.flags @@ -0,0 +1 @@ +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-term-declared-in-class/Impls_1.scala b/test/files/run/macro-term-declared-in-class/Impls_1.scala new file mode 100644 index 0000000000..348f3420f2 --- /dev/null +++ b/test/files/run/macro-term-declared-in-class/Impls_1.scala @@ -0,0 +1,11 @@ +import scala.reflect.macros.{Context => Ctx} + +object Impls { + def foo(c: Ctx) = { + import c.{prefix => prefix} + import c.universe._ + val printPrefix = Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant("prefix = " + prefix)))) + val body = Block(List(printPrefix), Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant("it works"))))) + c.Expr[Unit](body) + } +} \ No newline at end of file diff --git a/test/files/run/macro-term-declared-in-class/Macros_Test_2.scala b/test/files/run/macro-term-declared-in-class/Macros_Test_2.scala new file mode 100644 index 0000000000..1b9d13e775 --- /dev/null +++ b/test/files/run/macro-term-declared-in-class/Macros_Test_2.scala @@ -0,0 +1,7 @@ +class Macros { + def foo = macro Impls.foo +} + +object Test extends App { + new Macros().foo +} \ No newline at end of file diff --git a/test/files/run/macro-term-declared-in-default-param.check b/test/files/run/macro-term-declared-in-default-param.check new file mode 100644 index 0000000000..6decd7aa4d --- /dev/null +++ b/test/files/run/macro-term-declared-in-default-param.check @@ -0,0 +1,5 @@ +prefix = Expr[Nothing]() +it works +it works +prefix = Expr[Nothing]() +it works diff --git a/test/files/run/macro-term-declared-in-default-param.flags b/test/files/run/macro-term-declared-in-default-param.flags new file mode 100644 index 0000000000..cd66464f2f --- /dev/null +++ b/test/files/run/macro-term-declared-in-default-param.flags @@ -0,0 +1 @@ +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-term-declared-in-default-param/Impls_1.scala b/test/files/run/macro-term-declared-in-default-param/Impls_1.scala new file mode 100644 index 0000000000..4380f40b04 --- /dev/null +++ b/test/files/run/macro-term-declared-in-default-param/Impls_1.scala @@ -0,0 +1,11 @@ +import scala.reflect.macros.{Context => Ctx} + +object Impls { + def foo(c: Ctx) = { + import c.{prefix => prefix} + import c.universe._ + val printPrefix = Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant("prefix = " + prefix)))) + val body = Block(List(printPrefix), Literal(Constant("it works"))) + c.Expr[String](body) + } +} \ No newline at end of file diff --git a/test/files/run/macro-term-declared-in-default-param/Macros_Test_2.scala b/test/files/run/macro-term-declared-in-default-param/Macros_Test_2.scala new file mode 100644 index 0000000000..356029e63e --- /dev/null +++ b/test/files/run/macro-term-declared-in-default-param/Macros_Test_2.scala @@ -0,0 +1,7 @@ +object Test extends App { + def foo(bar: String = { def foo = macro Impls.foo; foo }) = println(bar) + + foo() + foo("it works") + foo() +} \ No newline at end of file diff --git a/test/files/run/macro-term-declared-in-implicit-class.check b/test/files/run/macro-term-declared-in-implicit-class.check new file mode 100644 index 0000000000..5dc968c08c --- /dev/null +++ b/test/files/run/macro-term-declared-in-implicit-class.check @@ -0,0 +1,2 @@ +prefix = Expr[Nothing](Macros.foo("2")) +Some(2) diff --git a/test/files/run/macro-term-declared-in-implicit-class.flags b/test/files/run/macro-term-declared-in-implicit-class.flags new file mode 100644 index 0000000000..cd66464f2f --- /dev/null +++ b/test/files/run/macro-term-declared-in-implicit-class.flags @@ -0,0 +1 @@ +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-term-declared-in-implicit-class/Impls_Macros_1.scala b/test/files/run/macro-term-declared-in-implicit-class/Impls_Macros_1.scala new file mode 100644 index 0000000000..4c009cc367 --- /dev/null +++ b/test/files/run/macro-term-declared-in-implicit-class/Impls_Macros_1.scala @@ -0,0 +1,19 @@ +import scala.reflect.macros.{Context => Ctx} + +object Impls { + def toOptionOfInt(c: Ctx) = { + import c.{prefix => prefix} + import c.universe._ + val printPrefix = Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant("prefix = " + prefix)))) + val body = Block(List(printPrefix), Apply(Ident(definitions.SomeModule), List(Select(Select(prefix.tree, TermName("x")), TermName("toInt"))))) + c.Expr[Option[Int]](body) + } +} + +object Macros { + implicit def foo(x: String): Foo = new Foo(x) + + class Foo(val x: String) { + def toOptionOfInt = macro Impls.toOptionOfInt + } +} \ No newline at end of file diff --git a/test/files/run/macro-term-declared-in-implicit-class/Test_2.scala b/test/files/run/macro-term-declared-in-implicit-class/Test_2.scala new file mode 100644 index 0000000000..d0bc9cc38c --- /dev/null +++ b/test/files/run/macro-term-declared-in-implicit-class/Test_2.scala @@ -0,0 +1,4 @@ +object Test extends App { + import Macros._ + println("2".toOptionOfInt) +} \ No newline at end of file diff --git a/test/files/run/macro-term-declared-in-method.check b/test/files/run/macro-term-declared-in-method.check new file mode 100644 index 0000000000..5e687db8bf --- /dev/null +++ b/test/files/run/macro-term-declared-in-method.check @@ -0,0 +1,2 @@ +prefix = Expr[Nothing]() +it works diff --git a/test/files/run/macro-term-declared-in-method.flags b/test/files/run/macro-term-declared-in-method.flags new file mode 100644 index 0000000000..cd66464f2f --- /dev/null +++ b/test/files/run/macro-term-declared-in-method.flags @@ -0,0 +1 @@ +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-term-declared-in-method/Impls_1.scala b/test/files/run/macro-term-declared-in-method/Impls_1.scala new file mode 100644 index 0000000000..348f3420f2 --- /dev/null +++ b/test/files/run/macro-term-declared-in-method/Impls_1.scala @@ -0,0 +1,11 @@ +import scala.reflect.macros.{Context => Ctx} + +object Impls { + def foo(c: Ctx) = { + import c.{prefix => prefix} + import c.universe._ + val printPrefix = Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant("prefix = " + prefix)))) + val body = Block(List(printPrefix), Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant("it works"))))) + c.Expr[Unit](body) + } +} \ No newline at end of file diff --git a/test/files/run/macro-term-declared-in-method/Macros_Test_2.scala b/test/files/run/macro-term-declared-in-method/Macros_Test_2.scala new file mode 100644 index 0000000000..ed5c8b7c43 --- /dev/null +++ b/test/files/run/macro-term-declared-in-method/Macros_Test_2.scala @@ -0,0 +1,8 @@ +object Test extends App { + def bar() = { + def foo = macro Impls.foo + foo + } + + bar() +} \ No newline at end of file diff --git a/test/files/run/macro-term-declared-in-object-class.check b/test/files/run/macro-term-declared-in-object-class.check new file mode 100644 index 0000000000..47248d7af7 --- /dev/null +++ b/test/files/run/macro-term-declared-in-object-class.check @@ -0,0 +1,2 @@ +prefix = Expr[Nothing](new Test.this.outer.Macros()) +it works diff --git a/test/files/run/macro-term-declared-in-object-class.flags b/test/files/run/macro-term-declared-in-object-class.flags new file mode 100644 index 0000000000..cd66464f2f --- /dev/null +++ b/test/files/run/macro-term-declared-in-object-class.flags @@ -0,0 +1 @@ +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-term-declared-in-object-class/Impls_1.scala b/test/files/run/macro-term-declared-in-object-class/Impls_1.scala new file mode 100644 index 0000000000..348f3420f2 --- /dev/null +++ b/test/files/run/macro-term-declared-in-object-class/Impls_1.scala @@ -0,0 +1,11 @@ +import scala.reflect.macros.{Context => Ctx} + +object Impls { + def foo(c: Ctx) = { + import c.{prefix => prefix} + import c.universe._ + val printPrefix = Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant("prefix = " + prefix)))) + val body = Block(List(printPrefix), Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant("it works"))))) + c.Expr[Unit](body) + } +} \ No newline at end of file diff --git a/test/files/run/macro-term-declared-in-object-class/Macros_Test_2.scala b/test/files/run/macro-term-declared-in-object-class/Macros_Test_2.scala new file mode 100644 index 0000000000..204deed61c --- /dev/null +++ b/test/files/run/macro-term-declared-in-object-class/Macros_Test_2.scala @@ -0,0 +1,10 @@ +object Macros { + class Macros { + def foo = macro Impls.foo + } +} + +object Test extends App { + val outer = Macros + new outer.Macros().foo +} \ No newline at end of file diff --git a/test/files/run/macro-term-declared-in-object-object.check b/test/files/run/macro-term-declared-in-object-object.check new file mode 100644 index 0000000000..35af59e40f --- /dev/null +++ b/test/files/run/macro-term-declared-in-object-object.check @@ -0,0 +1,2 @@ +prefix = Expr[Nothing](Test.this.outer.Macros) +it works diff --git a/test/files/run/macro-term-declared-in-object-object.flags b/test/files/run/macro-term-declared-in-object-object.flags new file mode 100644 index 0000000000..cd66464f2f --- /dev/null +++ b/test/files/run/macro-term-declared-in-object-object.flags @@ -0,0 +1 @@ +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-term-declared-in-object-object/Impls_1.scala b/test/files/run/macro-term-declared-in-object-object/Impls_1.scala new file mode 100644 index 0000000000..348f3420f2 --- /dev/null +++ b/test/files/run/macro-term-declared-in-object-object/Impls_1.scala @@ -0,0 +1,11 @@ +import scala.reflect.macros.{Context => Ctx} + +object Impls { + def foo(c: Ctx) = { + import c.{prefix => prefix} + import c.universe._ + val printPrefix = Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant("prefix = " + prefix)))) + val body = Block(List(printPrefix), Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant("it works"))))) + c.Expr[Unit](body) + } +} \ No newline at end of file diff --git a/test/files/run/macro-term-declared-in-object-object/Macros_Test_2.scala b/test/files/run/macro-term-declared-in-object-object/Macros_Test_2.scala new file mode 100644 index 0000000000..e261a50f3d --- /dev/null +++ b/test/files/run/macro-term-declared-in-object-object/Macros_Test_2.scala @@ -0,0 +1,10 @@ +object Macros { + object Macros { + def foo = macro Impls.foo + } +} + +object Test extends App { + val outer = Macros + outer.Macros.foo +} \ No newline at end of file diff --git a/test/files/run/macro-term-declared-in-object.check b/test/files/run/macro-term-declared-in-object.check new file mode 100644 index 0000000000..4d955a96b1 --- /dev/null +++ b/test/files/run/macro-term-declared-in-object.check @@ -0,0 +1,2 @@ +prefix = Expr[Nothing](Macros) +it works diff --git a/test/files/run/macro-term-declared-in-object.flags b/test/files/run/macro-term-declared-in-object.flags new file mode 100644 index 0000000000..cd66464f2f --- /dev/null +++ b/test/files/run/macro-term-declared-in-object.flags @@ -0,0 +1 @@ +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-term-declared-in-object/Impls_1.scala b/test/files/run/macro-term-declared-in-object/Impls_1.scala new file mode 100644 index 0000000000..348f3420f2 --- /dev/null +++ b/test/files/run/macro-term-declared-in-object/Impls_1.scala @@ -0,0 +1,11 @@ +import scala.reflect.macros.{Context => Ctx} + +object Impls { + def foo(c: Ctx) = { + import c.{prefix => prefix} + import c.universe._ + val printPrefix = Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant("prefix = " + prefix)))) + val body = Block(List(printPrefix), Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant("it works"))))) + c.Expr[Unit](body) + } +} \ No newline at end of file diff --git a/test/files/run/macro-term-declared-in-object/Macros_Test_2.scala b/test/files/run/macro-term-declared-in-object/Macros_Test_2.scala new file mode 100644 index 0000000000..a5a4862ba0 --- /dev/null +++ b/test/files/run/macro-term-declared-in-object/Macros_Test_2.scala @@ -0,0 +1,7 @@ +object Macros { + def foo = macro Impls.foo +} + +object Test extends App { + Macros.foo +} \ No newline at end of file diff --git a/test/files/run/macro-term-declared-in-package-object.check b/test/files/run/macro-term-declared-in-package-object.check new file mode 100644 index 0000000000..bc0069178d --- /dev/null +++ b/test/files/run/macro-term-declared-in-package-object.check @@ -0,0 +1,2 @@ +prefix = Expr[Nothing](Macros.`package`) +it works diff --git a/test/files/run/macro-term-declared-in-package-object.flags b/test/files/run/macro-term-declared-in-package-object.flags new file mode 100644 index 0000000000..cd66464f2f --- /dev/null +++ b/test/files/run/macro-term-declared-in-package-object.flags @@ -0,0 +1 @@ +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-term-declared-in-package-object/Impls_1.scala b/test/files/run/macro-term-declared-in-package-object/Impls_1.scala new file mode 100644 index 0000000000..348f3420f2 --- /dev/null +++ b/test/files/run/macro-term-declared-in-package-object/Impls_1.scala @@ -0,0 +1,11 @@ +import scala.reflect.macros.{Context => Ctx} + +object Impls { + def foo(c: Ctx) = { + import c.{prefix => prefix} + import c.universe._ + val printPrefix = Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant("prefix = " + prefix)))) + val body = Block(List(printPrefix), Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant("it works"))))) + c.Expr[Unit](body) + } +} \ No newline at end of file diff --git a/test/files/run/macro-term-declared-in-package-object/Macros_Test_2.scala b/test/files/run/macro-term-declared-in-package-object/Macros_Test_2.scala new file mode 100644 index 0000000000..54a5962e80 --- /dev/null +++ b/test/files/run/macro-term-declared-in-package-object/Macros_Test_2.scala @@ -0,0 +1,8 @@ +package object Macros { + def foo = macro Impls.foo +} + +object Test extends App { + import Macros._ + foo +} \ No newline at end of file diff --git a/test/files/run/macro-term-declared-in-refinement.check b/test/files/run/macro-term-declared-in-refinement.check new file mode 100644 index 0000000000..09b8d015a6 --- /dev/null +++ b/test/files/run/macro-term-declared-in-refinement.check @@ -0,0 +1,2 @@ +prefix = Expr[Nothing](Test.this.macros) +it works diff --git a/test/files/run/macro-term-declared-in-refinement.flags b/test/files/run/macro-term-declared-in-refinement.flags new file mode 100644 index 0000000000..cd66464f2f --- /dev/null +++ b/test/files/run/macro-term-declared-in-refinement.flags @@ -0,0 +1 @@ +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-term-declared-in-refinement/Impls_1.scala b/test/files/run/macro-term-declared-in-refinement/Impls_1.scala new file mode 100644 index 0000000000..348f3420f2 --- /dev/null +++ b/test/files/run/macro-term-declared-in-refinement/Impls_1.scala @@ -0,0 +1,11 @@ +import scala.reflect.macros.{Context => Ctx} + +object Impls { + def foo(c: Ctx) = { + import c.{prefix => prefix} + import c.universe._ + val printPrefix = Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant("prefix = " + prefix)))) + val body = Block(List(printPrefix), Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant("it works"))))) + c.Expr[Unit](body) + } +} \ No newline at end of file diff --git a/test/files/run/macro-term-declared-in-refinement/Macros_Test_2.scala b/test/files/run/macro-term-declared-in-refinement/Macros_Test_2.scala new file mode 100644 index 0000000000..ff9a66d58a --- /dev/null +++ b/test/files/run/macro-term-declared-in-refinement/Macros_Test_2.scala @@ -0,0 +1,9 @@ + +import scala.language.reflectiveCalls + +class Base + +object Test extends App { + val macros = new Base { def foo = macro Impls.foo } + macros.foo +} diff --git a/test/files/run/macro-term-declared-in-trait.check b/test/files/run/macro-term-declared-in-trait.check new file mode 100644 index 0000000000..0d70ac74f3 --- /dev/null +++ b/test/files/run/macro-term-declared-in-trait.check @@ -0,0 +1,15 @@ +prefix = Expr[Nothing]({ + final class $anon extends AnyRef with Base { + def (): anonymous class $anon = { + $anon.super.(); + () + }; + + }; + new $anon() +}) +it works +prefix = Expr[Nothing](Macros) +it works +prefix = Expr[Nothing](new Macros()) +it works diff --git a/test/files/run/macro-term-declared-in-trait.flags b/test/files/run/macro-term-declared-in-trait.flags new file mode 100644 index 0000000000..cd66464f2f --- /dev/null +++ b/test/files/run/macro-term-declared-in-trait.flags @@ -0,0 +1 @@ +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-term-declared-in-trait/Impls_1.scala b/test/files/run/macro-term-declared-in-trait/Impls_1.scala new file mode 100644 index 0000000000..348f3420f2 --- /dev/null +++ b/test/files/run/macro-term-declared-in-trait/Impls_1.scala @@ -0,0 +1,11 @@ +import scala.reflect.macros.{Context => Ctx} + +object Impls { + def foo(c: Ctx) = { + import c.{prefix => prefix} + import c.universe._ + val printPrefix = Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant("prefix = " + prefix)))) + val body = Block(List(printPrefix), Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant("it works"))))) + c.Expr[Unit](body) + } +} \ No newline at end of file diff --git a/test/files/run/macro-term-declared-in-trait/Macros_Test_2.scala b/test/files/run/macro-term-declared-in-trait/Macros_Test_2.scala new file mode 100644 index 0000000000..f75906b636 --- /dev/null +++ b/test/files/run/macro-term-declared-in-trait/Macros_Test_2.scala @@ -0,0 +1,13 @@ +trait Base { + def foo = macro Impls.foo +} + +object Macros extends Base + +class Macros extends Base + +object Test extends App { + (new Base {}).foo + Macros.foo + new Macros().foo +} \ No newline at end of file diff --git a/test/files/run/repl-term-macros.check b/test/files/run/repl-term-macros.check new file mode 100644 index 0000000000..eae489c294 --- /dev/null +++ b/test/files/run/repl-term-macros.check @@ -0,0 +1,44 @@ +Type in expressions to have them evaluated. +Type :help for more information. + +scala> + +scala> import scala.reflect.macros.Context +import scala.reflect.macros.Context + +scala> import language.experimental.macros +import language.experimental.macros + +scala> + +scala> def impl1(c: Context) = c.literalUnit +impl1: (c: scala.reflect.macros.Context)c.Expr[Unit] + +scala> def foo1 = macro impl1 +defined term macro foo1: Unit + +scala> foo1 + +scala> + +scala> def impl2(c: Context)() = c.literalUnit +impl2: (c: scala.reflect.macros.Context)()c.Expr[Unit] + +scala> def foo2() = macro impl2 +defined term macro foo2: ()Unit + +scala> foo2() + +scala> + +scala> def impl3(c: Context)(x: c.Expr[Int])(y: c.Expr[Int]) = c.literalUnit +impl3: (c: scala.reflect.macros.Context)(x: c.Expr[Int])(y: c.Expr[Int])c.Expr[Unit] + +scala> def foo3(x: Int)(y: Int) = macro impl3 +defined term macro foo3: (x: Int)(y: Int)Unit + +scala> foo3(2)(3) + +scala> + +scala> diff --git a/test/files/run/repl-term-macros.scala b/test/files/run/repl-term-macros.scala new file mode 100644 index 0000000000..f826259be9 --- /dev/null +++ b/test/files/run/repl-term-macros.scala @@ -0,0 +1,20 @@ +import scala.tools.partest.ReplTest + +object Test extends ReplTest { + def code = """ + import scala.reflect.macros.Context +import language.experimental.macros + +def impl1(c: Context) = c.literalUnit +def foo1 = macro impl1 +foo1 + +def impl2(c: Context)() = c.literalUnit +def foo2() = macro impl2 +foo2() + +def impl3(c: Context)(x: c.Expr[Int])(y: c.Expr[Int]) = c.literalUnit +def foo3(x: Int)(y: Int) = macro impl3 +foo3(2)(3) + """ +} \ No newline at end of file diff --git a/test/pending/run/macro-term-declared-in-anonymous-explicit-import.check b/test/pending/run/macro-term-declared-in-anonymous-explicit-import.check new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/pending/run/macro-term-declared-in-anonymous-explicit-import/Impls_1.scala b/test/pending/run/macro-term-declared-in-anonymous-explicit-import/Impls_1.scala new file mode 100644 index 0000000000..348f3420f2 --- /dev/null +++ b/test/pending/run/macro-term-declared-in-anonymous-explicit-import/Impls_1.scala @@ -0,0 +1,11 @@ +import scala.reflect.macros.{Context => Ctx} + +object Impls { + def foo(c: Ctx) = { + import c.{prefix => prefix} + import c.universe._ + val printPrefix = Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant("prefix = " + prefix)))) + val body = Block(List(printPrefix), Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant("it works"))))) + c.Expr[Unit](body) + } +} \ No newline at end of file diff --git a/test/pending/run/macro-term-declared-in-anonymous-explicit-import/Macros_Test_2.scala b/test/pending/run/macro-term-declared-in-anonymous-explicit-import/Macros_Test_2.scala new file mode 100644 index 0000000000..dd2317b1b7 --- /dev/null +++ b/test/pending/run/macro-term-declared-in-anonymous-explicit-import/Macros_Test_2.scala @@ -0,0 +1,6 @@ +import language.experimental.macros + +object Test extends App { + val macros = new { def foo = macro Impls.foo } + macros.foo +} \ No newline at end of file -- cgit v1.2.3 From e0bbe0af094b9055942c24fcaaa290a31415fa0a Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Wed, 27 Feb 2013 15:02:03 +0100 Subject: refactors importers Introduces better names, factors out recreation of symbols, trees, types and completes into separate methods, so that they can be overridden in specialized importers. The original motivation for this refactoring was to support JIT compilation of macros, but I think that most of the introduced improvements to code quality will be useful in trunk. --- src/reflect/scala/reflect/internal/Importers.scala | 636 ++++++++++----------- 1 file changed, 318 insertions(+), 318 deletions(-) diff --git a/src/reflect/scala/reflect/internal/Importers.scala b/src/reflect/scala/reflect/internal/Importers.scala index b0d3cda629..ae1c2a9a77 100644 --- a/src/reflect/scala/reflect/internal/Importers.scala +++ b/src/reflect/scala/reflect/internal/Importers.scala @@ -6,17 +6,17 @@ import scala.collection.mutable.WeakHashMap import scala.ref.WeakReference // SI-6241: move importers to a mirror -trait Importers extends api.Importers { self: SymbolTable => +trait Importers extends api.Importers { to: SymbolTable => def mkImporter(from0: api.Universe): Importer { val from: from0.type } = ( - if (self eq from0) { + if (to eq from0) { new Importer { val from = from0 - val reverse = this.asInstanceOf[from.Importer{ val from: self.type }] - def importSymbol(sym: from.Symbol) = sym.asInstanceOf[self.Symbol] - def importType(tpe: from.Type) = tpe.asInstanceOf[self.Type] - def importTree(tree: from.Tree) = tree.asInstanceOf[self.Tree] - def importPosition(pos: from.Position) = pos.asInstanceOf[self.Position] + val reverse = this.asInstanceOf[from.Importer{ val from: to.type }] + def importSymbol(their: from.Symbol) = their.asInstanceOf[to.Symbol] + def importType(their: from.Type) = their.asInstanceOf[to.Type] + def importTree(their: from.Tree) = their.asInstanceOf[to.Tree] + def importPosition(their: from.Position) = their.asInstanceOf[to.Position] } } else { // todo. fix this loophole @@ -29,8 +29,8 @@ trait Importers extends api.Importers { self: SymbolTable => val from: SymbolTable - protected lazy val symMap = new Cache[from.Symbol, Symbol]() - protected lazy val tpeMap = new Cache[from.Type, Type]() + protected lazy val symMap = new Cache[from.Symbol, to.Symbol]() + protected lazy val tpeMap = new Cache[from.Type, to.Type]() protected class Cache[K <: AnyRef, V <: AnyRef] extends WeakHashMap[K, WeakReference[V]] { def weakGet(key: K): Option[V] = this get key flatMap WeakReference.unapply def weakUpdate(key: K, value: V) = this.update(key, WeakReference(value)) @@ -50,158 +50,156 @@ trait Importers extends api.Importers { self: SymbolTable => } object reverse extends from.StandardImporter { - val from: self.type = self + val from: to.type = to // FIXME this and reverse should be constantly kept in sync // not just synced once upon the first usage of reverse - for ((fromsym, WeakReference(mysym)) <- StandardImporter.this.symMap) symMap += ((mysym, WeakReference(fromsym))) - for ((fromtpe, WeakReference(mytpe)) <- StandardImporter.this.tpeMap) tpeMap += ((mytpe, WeakReference(fromtpe))) + for ((theirsym, WeakReference(mysym)) <- StandardImporter.this.symMap) symMap += ((mysym, WeakReference(theirsym))) + for ((theirtpe, WeakReference(mytpe)) <- StandardImporter.this.tpeMap) tpeMap += ((mytpe, WeakReference(theirtpe))) } - // todo. careful import of positions - def importPosition(pos: from.Position): Position = - pos.asInstanceOf[Position] + // ============== SYMBOLS ============== - def importSymbol(sym0: from.Symbol): Symbol = { - def doImport(sym: from.Symbol): Symbol = - symMap weakGet sym match { + protected def recreatedSymbolCompleter(their: from.Symbol) = { + val mytypeParams = their.typeParams map importSymbol + new LazyPolyType(mytypeParams) with FlagAgnosticCompleter { + override def complete(my: to.Symbol): Unit = { + val theirCore = their.info match { + case from.PolyType(_, core) => core + case core => core + } + my setInfo GenPolyType(mytypeParams, importType(theirCore)) + my setAnnotations (their.annotations map importAnnotationInfo) + } + } + } + + protected def recreateSymbol(their: from.Symbol): to.Symbol = { + val myowner = importSymbol(their.owner) + val mypos = importPosition(their.pos) + val myname = importName(their.name) + val myflags = their.flags + def linkReferenced(my: TermSymbol, their: from.TermSymbol, op: from.Symbol => Symbol): Symbol = { + symMap.weakUpdate(their, my) + my.referenced = op(their.referenced) + my + } + val my = their match { + case their: from.MethodSymbol => + linkReferenced(myowner.newMethod(myname.toTermName, mypos, myflags), their, importSymbol) + case their: from.ModuleSymbol => + val ret = linkReferenced(myowner.newModuleSymbol(myname.toTermName, mypos, myflags), their, importSymbol) + ret.associatedFile = their.associatedFile + ret + case their: from.FreeTermSymbol => + newFreeTermSymbol(myname.toTermName, their.value, their.flags, their.origin) setInfo importType(their.info) + case their: from.FreeTypeSymbol => + newFreeTypeSymbol(myname.toTypeName, their.flags, their.origin) + case their: from.TermSymbol => + linkReferenced(myowner.newValue(myname.toTermName, mypos, myflags), their, importSymbol) + case their: from.TypeSkolem => + val origin = their.unpackLocation match { + case null => null + case theirloc: from.Tree => importTree(theirloc) + case theirloc: from.Symbol => importSymbol(theirloc) + } + myowner.newTypeSkolemSymbol(myname.toTypeName, origin, mypos, myflags) + case their: from.ModuleClassSymbol => + val my = myowner.newModuleClass(myname.toTypeName, mypos, myflags) + symMap.weakUpdate(their, my) + my.sourceModule = importSymbol(their.sourceModule) + my + case their: from.ClassSymbol => + val my = myowner.newClassSymbol(myname.toTypeName, mypos, myflags) + symMap.weakUpdate(their, my) + if (their.thisSym != their) { + my.typeOfThis = importType(their.typeOfThis) + my.thisSym setName importName(their.thisSym.name) + } + my.associatedFile = their.associatedFile + my + case their: from.TypeSymbol => + myowner.newTypeSymbol(myname.toTypeName, mypos, myflags) + } + symMap.weakUpdate(their, my) + my setFlag Flags.LOCKED + my setInfo recreatedSymbolCompleter(their) + my resetFlag Flags.LOCKED + } + + def importSymbol(their0: from.Symbol): Symbol = { + def cachedRecreateSymbol(their: from.Symbol): Symbol = + symMap weakGet their match { case Some(result) => result - case _ => - val myowner = importSymbol(sym.owner) - val mypos = importPosition(sym.pos) - val myname = importName(sym.name).toTermName - val myflags = sym.flags - def linkReferenced(mysym: TermSymbol, x: from.TermSymbol, op: from.Symbol => Symbol): Symbol = { - symMap.weakUpdate(x, mysym) - mysym.referenced = op(x.referenced) - mysym - } - val mysym = sym match { - case x: from.MethodSymbol => - linkReferenced(myowner.newMethod(myname, mypos, myflags), x, importSymbol) - case x: from.ModuleSymbol => - linkReferenced(myowner.newModuleSymbol(myname, mypos, myflags), x, importSymbol) - case x: from.FreeTermSymbol => - newFreeTermSymbol(importName(x.name).toTermName, x.value, x.flags, x.origin) setInfo importType(x.info) - case x: from.FreeTypeSymbol => - newFreeTypeSymbol(importName(x.name).toTypeName, x.flags, x.origin) - case x: from.TermSymbol => - linkReferenced(myowner.newValue(myname, mypos, myflags), x, importSymbol) - case x: from.TypeSkolem => - val origin = x.unpackLocation match { - case null => null - case y: from.Tree => importTree(y) - case y: from.Symbol => importSymbol(y) - } - myowner.newTypeSkolemSymbol(myname.toTypeName, origin, mypos, myflags) - case x: from.ModuleClassSymbol => - val mysym = myowner.newModuleClass(myname.toTypeName, mypos, myflags) - symMap.weakUpdate(x, mysym) - mysym.sourceModule = importSymbol(x.sourceModule) - mysym - case x: from.ClassSymbol => - val mysym = myowner.newClassSymbol(myname.toTypeName, mypos, myflags) - symMap.weakUpdate(x, mysym) - if (sym.thisSym != sym) { - mysym.typeOfThis = importType(sym.typeOfThis) - mysym.thisSym setName importName(sym.thisSym.name) - } - mysym - case x: from.TypeSymbol => - myowner.newTypeSymbol(myname.toTypeName, mypos, myflags) - } - symMap.weakUpdate(sym, mysym) - mysym setFlag Flags.LOCKED - mysym setInfo { - val mytypeParams = sym.typeParams map importSymbol - new LazyPolyType(mytypeParams) with FlagAgnosticCompleter { - override def complete(s: Symbol) { - val result = sym.info match { - case from.PolyType(_, res) => res - case result => result - } - s setInfo GenPolyType(mytypeParams, importType(result)) - s setAnnotations (sym.annotations map importAnnotationInfo) - } - } - } - mysym resetFlag Flags.LOCKED - } // end doImport + case _ => recreateSymbol(their) + } - def importOrRelink: Symbol = { - val sym = sym0 // makes sym visible in the debugger - if (sym == null) + def recreateOrRelink: Symbol = { + val their = their0 // makes their visible in the debugger + if (their == null) null - else if (sym == from.NoSymbol) + else if (their == from.NoSymbol) NoSymbol - else if (sym.isRoot) + else if (their.isRoot) rootMirror.RootClass // !!! replace with actual mirror when we move importers to the mirror else { - val name = sym.name - val owner = sym.owner - var scope = if (owner.isClass && !owner.isRefinementClass) owner.info else from.NoType - var existing = scope.decl(name) - if (sym.isModuleClass) - existing = existing.moduleClass - - if (!existing.exists) scope = from.NoType - - val myname = importName(name) - val myowner = importSymbol(owner) - val myscope = if (scope != from.NoType && !(myowner hasFlag Flags.LOCKED)) myowner.info else NoType - var myexisting = if (myscope != NoType) myowner.info.decl(myname) else NoSymbol // cannot load myexisting in general case, because it creates cycles for methods - if (sym.isModuleClass) - myexisting = importSymbol(sym.sourceModule).moduleClass - - if (!sym.isOverloaded && myexisting.isOverloaded) { + var theirscope = if (their.owner.isClass && !their.owner.isRefinementClass) their.owner.info else from.NoType + var theirexisting = theirscope.decl(their.name) + if (their.isModuleClass) theirexisting = theirexisting.moduleClass + if (!theirexisting.exists) theirscope = from.NoType + + val myname = importName(their.name) + val myowner = importSymbol(their.owner) + val myscope = if (theirscope != from.NoType && !(myowner hasFlag Flags.LOCKED)) myowner.info else NoType + var myexisting = if (myscope != NoType) myscope.decl(myname) else NoSymbol // cannot load myexisting in general case, because it creates cycles for methods + + if (their.isModuleClass) + myexisting = importSymbol(their.sourceModule).moduleClass + + if (!their.isOverloaded && myexisting.isOverloaded) { myexisting = - if (sym.isMethod) { - val localCopy = doImport(sym) + if (their.isMethod) { + val localCopy = cachedRecreateSymbol(their) myexisting filter (_.tpe matches localCopy.tpe) } else { myexisting filter (!_.isMethod) } assert(!myexisting.isOverloaded, "import failure: cannot determine unique overloaded method alternative from\n "+ - (myexisting.alternatives map (_.defString) mkString "\n")+"\n that matches "+sym+":"+sym.tpe) + (myexisting.alternatives map (_.defString) mkString "\n")+"\n that matches "+their+":"+their.tpe) } - val mysym = { - if (sym.isOverloaded) { - myowner.newOverloaded(myowner.thisType, sym.alternatives map importSymbol) - } else if (sym.isTypeParameter && sym.paramPos >= 0 && !(myowner hasFlag Flags.LOCKED)) { - assert(myowner.typeParams.length > sym.paramPos, - "import failure: cannot determine parameter "+sym+" (#"+sym.paramPos+") in "+ + val my = { + if (their.isOverloaded) { + myowner.newOverloaded(myowner.thisType, their.alternatives map importSymbol) + } else if (their.isTypeParameter && their.paramPos >= 0 && !(myowner hasFlag Flags.LOCKED)) { + assert(myowner.typeParams.length > their.paramPos, + "import failure: cannot determine parameter "+their+" (#"+their.paramPos+") in "+ myowner+typeParamsString(myowner.rawInfo)+"\n original symbol was: "+ - sym.owner+from.typeParamsString(sym.owner.info)) - myowner.typeParams(sym.paramPos) + their.owner+from.typeParamsString(their.owner.info)) + myowner.typeParams(their.paramPos) } else { - if (myexisting != NoSymbol) { - myexisting - } else { - val mysym = doImport(sym) - + myexisting.orElse { + val my = cachedRecreateSymbol(their) if (myscope != NoType) { - assert(myowner.info.decls.lookup(myname) == NoSymbol, myname+" "+myowner.info.decl(myname)+" "+myexisting) - myowner.info.decls enter mysym + assert(myscope.decls.lookup(myname) == NoSymbol, myname+" "+myscope.decl(myname)+" "+myexisting) + myscope.decls enter my } - - mysym + my } } } - - mysym + my } - } // end importOrRelink + } // end recreateOrRelink - val sym = sym0 - symMap.weakGet(sym) match { + val their = their0 + symMap.weakGet(their) match { case Some(result) => result case None => pendingSyms += 1 try { - val result = importOrRelink - symMap.weakUpdate(sym, result) + val result = recreateOrRelink + symMap.weakUpdate(their, result) result } finally { pendingSyms -= 1 @@ -210,69 +208,70 @@ trait Importers extends api.Importers { self: SymbolTable => } } - def importType(tpe: from.Type): Type = { - def doImport(tpe: from.Type): Type = tpe match { - case from.TypeRef(pre, sym, args) => - TypeRef(importType(pre), importSymbol(sym), args map importType) - case from.ThisType(clazz) => - ThisType(importSymbol(clazz)) - case from.SingleType(pre, sym) => - SingleType(importType(pre), importSymbol(sym)) - case from.MethodType(params, restpe) => - MethodType(params map importSymbol, importType(restpe)) - case from.PolyType(tparams, restpe) => - PolyType(tparams map importSymbol, importType(restpe)) - case from.NullaryMethodType(restpe) => - NullaryMethodType(importType(restpe)) - case from.ConstantType(constant @ from.Constant(_)) => - ConstantType(importConstant(constant)) - case from.SuperType(thistpe, supertpe) => - SuperType(importType(thistpe), importType(supertpe)) - case from.TypeBounds(lo, hi) => - TypeBounds(importType(lo), importType(hi)) - case from.BoundedWildcardType(bounds) => - BoundedWildcardType(importTypeBounds(bounds)) - case from.ClassInfoType(parents, decls, clazz) => - val myclazz = importSymbol(clazz) - val myscope = if (myclazz.isPackageClass) newPackageScope(myclazz) else newScope - val myclazzTpe = ClassInfoType(parents map importType, myscope, myclazz) - myclazz setInfo GenPolyType(myclazz.typeParams, myclazzTpe) // needed so that newly created symbols find their scope - decls foreach importSymbol // will enter itself into myclazz - myclazzTpe - case from.RefinedType(parents, decls) => - RefinedType(parents map importType, importScope(decls), importSymbol(tpe.typeSymbol)) - case from.ExistentialType(tparams, restpe) => - newExistentialType(tparams map importSymbol, importType(restpe)) - case from.OverloadedType(pre, alts) => - OverloadedType(importType(pre), alts map importSymbol) - case from.AntiPolyType(pre, targs) => - AntiPolyType(importType(pre), targs map importType) - case x: from.TypeVar => - TypeVar(importType(x.origin), importTypeConstraint(x.constr), x.typeArgs map importType, x.params map importSymbol) - case from.AnnotatedType(annots, tpe, selfsym) => - AnnotatedType(annots map importAnnotationInfo, importType(tpe), importSymbol(selfsym)) - case from.ErrorType => - ErrorType - case from.WildcardType => - WildcardType - case from.NoType => - NoType - case from.NoPrefix => - NoPrefix - case null => - null - } // end doImport - - def importOrRelink: Type = - doImport(tpe) + // ============== TYPES ============== + + def recreateType(their: from.Type): Type = their match { + case from.TypeRef(pre, sym, args) => + TypeRef(importType(pre), importSymbol(sym), args map importType) + case from.ThisType(clazz) => + ThisType(importSymbol(clazz)) + case from.SingleType(pre, sym) => + SingleType(importType(pre), importSymbol(sym)) + case from.MethodType(params, result) => + MethodType(params map importSymbol, importType(result)) + case from.PolyType(tparams, result) => + PolyType(tparams map importSymbol, importType(result)) + case from.NullaryMethodType(result) => + NullaryMethodType(importType(result)) + case from.ConstantType(constant @ from.Constant(_)) => + ConstantType(importConstant(constant)) + case from.SuperType(thistpe, supertpe) => + SuperType(importType(thistpe), importType(supertpe)) + case from.TypeBounds(lo, hi) => + TypeBounds(importType(lo), importType(hi)) + case from.BoundedWildcardType(bounds) => + BoundedWildcardType(importType(bounds).asInstanceOf[TypeBounds]) + case from.ClassInfoType(parents, decls, clazz) => + val myclazz = importSymbol(clazz) + val myscope = if (myclazz.isPackageClass) newPackageScope(myclazz) else newScope + val myclazzTpe = ClassInfoType(parents map importType, myscope, myclazz) + myclazz setInfo GenPolyType(myclazz.typeParams, myclazzTpe) // needed so that newly created symbols find their scope + decls foreach importSymbol // will enter itself into myclazz + myclazzTpe + case from.RefinedType(parents, decls) => + RefinedType(parents map importType, importScope(decls), importSymbol(their.typeSymbol)) + case from.ExistentialType(tparams, result) => + newExistentialType(tparams map importSymbol, importType(result)) + case from.OverloadedType(pre, alts) => + OverloadedType(importType(pre), alts map importSymbol) + case from.AntiPolyType(pre, targs) => + AntiPolyType(importType(pre), targs map importType) + case their: from.TypeVar => + val myconstr = new TypeConstraint(their.constr.loBounds map importType, their.constr.hiBounds map importType) + myconstr.inst = importType(their.constr.inst) + TypeVar(importType(their.origin), myconstr, their.typeArgs map importType, their.params map importSymbol) + case from.AnnotatedType(annots, result, selfsym) => + AnnotatedType(annots map importAnnotationInfo, importType(result), importSymbol(selfsym)) + case from.ErrorType => + ErrorType + case from.WildcardType => + WildcardType + case from.NoType => + NoType + case from.NoPrefix => + NoPrefix + case null => + null + } - tpeMap.weakGet(tpe) match { + def importType(their: from.Type): Type = { + tpeMap.weakGet(their) match { case Some(result) => result case None => pendingTpes += 1 try { - val result = importOrRelink - tpeMap.weakUpdate(tpe, result) + val result = recreateType(their) + tpeMap.weakUpdate(their, result) result } finally { pendingTpes -= 1 @@ -281,7 +280,136 @@ trait Importers extends api.Importers { self: SymbolTable => } } - def importTypeBounds(bounds: from.TypeBounds) = importType(bounds).asInstanceOf[TypeBounds] + // ============== TREES ============== + + def recreatedTreeCompleter(their: from.Tree, my: to.Tree): Unit = { + if (their.canHaveAttrs) { + if (my.hasSymbolField) my.symbol = importSymbol(their.symbol) + my.pos = importPosition(their.pos) + (their, my) match { + case (their: from.TypeTree, my: to.TypeTree) => + if (their.wasEmpty) my.defineType(importType(their.tpe)) else my.setType(importType(their.tpe)) + case (_, _) => + my.tpe = importType(their.tpe) + } + } + } + + def recreateTree(their: from.Tree): to.Tree = their match { + case from.ClassDef(mods, name, tparams, impl) => + new ClassDef(importModifiers(mods), importName(name).toTypeName, tparams map importTypeDef, importTemplate(impl)) + case from.PackageDef(pid, stats) => + new PackageDef(importRefTree(pid), stats map importTree) + case from.ModuleDef(mods, name, impl) => + new ModuleDef(importModifiers(mods), importName(name).toTermName, importTemplate(impl)) + case from.emptyValDef => + emptyValDef + case from.pendingSuperCall => + pendingSuperCall + case from.ValDef(mods, name, tpt, rhs) => + new ValDef(importModifiers(mods), importName(name).toTermName, importTree(tpt), importTree(rhs)) + case from.DefDef(mods, name, tparams, vparamss, tpt, rhs) => + new DefDef(importModifiers(mods), importName(name).toTermName, tparams map importTypeDef, mmap(vparamss)(importValDef), importTree(tpt), importTree(rhs)) + case from.TypeDef(mods, name, tparams, rhs) => + new TypeDef(importModifiers(mods), importName(name).toTypeName, tparams map importTypeDef, importTree(rhs)) + case from.LabelDef(name, params, rhs) => + new LabelDef(importName(name).toTermName, params map importIdent, importTree(rhs)) + case from.Import(expr, selectors) => + new Import(importTree(expr), selectors map importImportSelector) + case from.Template(parents, self, body) => + new Template(parents map importTree, importValDef(self), body map importTree) + case from.Block(stats, expr) => + new Block(stats map importTree, importTree(expr)) + case from.CaseDef(pat, guard, body) => + new CaseDef(importTree(pat), importTree(guard), importTree(body)) + case from.Alternative(trees) => + new Alternative(trees map importTree) + case from.Star(elem) => + new Star(importTree(elem)) + case from.Bind(name, body) => + new Bind(importName(name), importTree(body)) + case from.UnApply(fun, args) => + new UnApply(importTree(fun), args map importTree) + case from.ArrayValue(elemtpt ,elems) => + new ArrayValue(importTree(elemtpt), elems map importTree) + case from.Function(vparams, body) => + new Function(vparams map importValDef, importTree(body)) + case from.Assign(lhs, rhs) => + new Assign(importTree(lhs), importTree(rhs)) + case from.AssignOrNamedArg(lhs, rhs) => + new AssignOrNamedArg(importTree(lhs), importTree(rhs)) + case from.If(cond, thenp, elsep) => + new If(importTree(cond), importTree(thenp), importTree(elsep)) + case from.Match(selector, cases) => + new Match(importTree(selector), cases map importCaseDef) + case from.Return(expr) => + new Return(importTree(expr)) + case from.Try(block, catches, finalizer) => + new Try(importTree(block), catches map importCaseDef, importTree(finalizer)) + case from.Throw(expr) => + new Throw(importTree(expr)) + case from.New(tpt) => + new New(importTree(tpt)) + case from.Typed(expr, tpt) => + new Typed(importTree(expr), importTree(tpt)) + case from.TypeApply(fun, args) => + new TypeApply(importTree(fun), args map importTree) + case from.Apply(fun, args) => their match { + case _: from.ApplyToImplicitArgs => + new ApplyToImplicitArgs(importTree(fun), args map importTree) + case _: from.ApplyImplicitView => + new ApplyImplicitView(importTree(fun), args map importTree) + case _ => + new Apply(importTree(fun), args map importTree) + } + case from.ApplyDynamic(qual, args) => + new ApplyDynamic(importTree(qual), args map importTree) + case from.Super(qual, mix) => + new Super(importTree(qual), importName(mix).toTypeName) + case from.This(qual) => + new This(importName(qual).toTypeName) + case from.Select(qual, name) => + new Select(importTree(qual), importName(name)) + case from.Ident(name) => + new Ident(importName(name)) + case from.ReferenceToBoxed(ident) => + new ReferenceToBoxed(importTree(ident) match { case ident: Ident => ident }) + case from.Literal(constant @ from.Constant(_)) => + new Literal(importConstant(constant)) + case theirtt @ from.TypeTree() => + val mytt = TypeTree() + if (theirtt.original != null) mytt.setOriginal(importTree(theirtt.original)) + mytt + case from.Annotated(annot, arg) => + new Annotated(importTree(annot), importTree(arg)) + case from.SingletonTypeTree(ref) => + new SingletonTypeTree(importTree(ref)) + case from.SelectFromTypeTree(qual, name) => + new SelectFromTypeTree(importTree(qual), importName(name).toTypeName) + case from.CompoundTypeTree(templ) => + new CompoundTypeTree(importTemplate(templ)) + case from.AppliedTypeTree(tpt, args) => + new AppliedTypeTree(importTree(tpt), args map importTree) + case from.TypeBoundsTree(lo, hi) => + new TypeBoundsTree(importTree(lo), importTree(hi)) + case from.ExistentialTypeTree(tpt, whereClauses) => + new ExistentialTypeTree(importTree(tpt), whereClauses map importTree) + case from.EmptyTree => + EmptyTree + case null => + null + } + + def importTree(their: from.Tree): Tree = { + val my = recreateTree(their) + if (my != null) { + addFixup(recreatedTreeCompleter(their, my)) + tryFixup() + } + my + } + + // ============== MISCELLANEOUS ============== def importAnnotationInfo(ann: from.AnnotationInfo): AnnotationInfo = { val atp1 = importType(ann.atp) @@ -302,11 +430,9 @@ trait Importers extends api.Importers { self: SymbolTable => NestedAnnotArg(importAnnotationInfo(annInfo)) } - def importTypeConstraint(constr: from.TypeConstraint): TypeConstraint = { - val result = new TypeConstraint(constr.loBounds map importType, constr.hiBounds map importType) - result.inst = importType(constr.inst) - result - } + // todo. careful import of positions + def importPosition(their: from.Position): to.Position = + their.asInstanceOf[Position] // !!! todo: override to cater for PackageScopes def importScope(decls: from.Scope): Scope = @@ -314,138 +440,12 @@ trait Importers extends api.Importers { self: SymbolTable => def importName(name: from.Name): Name = if (name.isTypeName) newTypeName(name.toString) else newTermName(name.toString) - def importTypeName(name: from.TypeName): TypeName = importName(name).toTypeName def importModifiers(mods: from.Modifiers): Modifiers = new Modifiers(mods.flags, importName(mods.privateWithin), mods.annotations map importTree) def importImportSelector(sel: from.ImportSelector): ImportSelector = new ImportSelector(importName(sel.name), sel.namePos, if (sel.rename != null) importName(sel.rename) else null, sel.renamePos) - - def importTree(tree: from.Tree): Tree = { - val mytree = tree match { - case from.ClassDef(mods, name, tparams, impl) => - new ClassDef(importModifiers(mods), importName(name).toTypeName, tparams map importTypeDef, importTemplate(impl)) - case from.PackageDef(pid, stats) => - new PackageDef(importRefTree(pid), stats map importTree) - case from.ModuleDef(mods, name, impl) => - new ModuleDef(importModifiers(mods), importName(name).toTermName, importTemplate(impl)) - case from.emptyValDef => - emptyValDef - case from.pendingSuperCall => - pendingSuperCall - case from.ValDef(mods, name, tpt, rhs) => - new ValDef(importModifiers(mods), importName(name).toTermName, importTree(tpt), importTree(rhs)) - case from.DefDef(mods, name, tparams, vparamss, tpt, rhs) => - new DefDef(importModifiers(mods), importName(name).toTermName, tparams map importTypeDef, mmap(vparamss)(importValDef), importTree(tpt), importTree(rhs)) - case from.TypeDef(mods, name, tparams, rhs) => - new TypeDef(importModifiers(mods), importName(name).toTypeName, tparams map importTypeDef, importTree(rhs)) - case from.LabelDef(name, params, rhs) => - new LabelDef(importName(name).toTermName, params map importIdent, importTree(rhs)) - case from.Import(expr, selectors) => - new Import(importTree(expr), selectors map importImportSelector) - case from.Template(parents, self, body) => - new Template(parents map importTree, importValDef(self), body map importTree) - case from.Block(stats, expr) => - new Block(stats map importTree, importTree(expr)) - case from.CaseDef(pat, guard, body) => - new CaseDef(importTree(pat), importTree(guard), importTree(body)) - case from.Alternative(trees) => - new Alternative(trees map importTree) - case from.Star(elem) => - new Star(importTree(elem)) - case from.Bind(name, body) => - new Bind(importName(name), importTree(body)) - case from.UnApply(fun, args) => - new UnApply(importTree(fun), args map importTree) - case from.ArrayValue(elemtpt ,elems) => - new ArrayValue(importTree(elemtpt), elems map importTree) - case from.Function(vparams, body) => - new Function(vparams map importValDef, importTree(body)) - case from.Assign(lhs, rhs) => - new Assign(importTree(lhs), importTree(rhs)) - case from.AssignOrNamedArg(lhs, rhs) => - new AssignOrNamedArg(importTree(lhs), importTree(rhs)) - case from.If(cond, thenp, elsep) => - new If(importTree(cond), importTree(thenp), importTree(elsep)) - case from.Match(selector, cases) => - new Match(importTree(selector), cases map importCaseDef) - case from.Return(expr) => - new Return(importTree(expr)) - case from.Try(block, catches, finalizer) => - new Try(importTree(block), catches map importCaseDef, importTree(finalizer)) - case from.Throw(expr) => - new Throw(importTree(expr)) - case from.New(tpt) => - new New(importTree(tpt)) - case from.Typed(expr, tpt) => - new Typed(importTree(expr), importTree(tpt)) - case from.TypeApply(fun, args) => - new TypeApply(importTree(fun), args map importTree) - case from.Apply(fun, args) => tree match { - case _: from.ApplyToImplicitArgs => - new ApplyToImplicitArgs(importTree(fun), args map importTree) - case _: from.ApplyImplicitView => - new ApplyImplicitView(importTree(fun), args map importTree) - case _ => - new Apply(importTree(fun), args map importTree) - } - case from.ApplyDynamic(qual, args) => - new ApplyDynamic(importTree(qual), args map importTree) - case from.Super(qual, mix) => - new Super(importTree(qual), importTypeName(mix)) - case from.This(qual) => - new This(importName(qual).toTypeName) - case from.Select(qual, name) => - new Select(importTree(qual), importName(name)) - case from.Ident(name) => - new Ident(importName(name)) - case from.ReferenceToBoxed(ident) => - new ReferenceToBoxed(importTree(ident) match { case ident: Ident => ident }) - case from.Literal(constant @ from.Constant(_)) => - new Literal(importConstant(constant)) - case from.TypeTree() => - new TypeTree() - case from.Annotated(annot, arg) => - new Annotated(importTree(annot), importTree(arg)) - case from.SingletonTypeTree(ref) => - new SingletonTypeTree(importTree(ref)) - case from.SelectFromTypeTree(qual, name) => - new SelectFromTypeTree(importTree(qual), importName(name).toTypeName) - case from.CompoundTypeTree(templ) => - new CompoundTypeTree(importTemplate(templ)) - case from.AppliedTypeTree(tpt, args) => - new AppliedTypeTree(importTree(tpt), args map importTree) - case from.TypeBoundsTree(lo, hi) => - new TypeBoundsTree(importTree(lo), importTree(hi)) - case from.ExistentialTypeTree(tpt, whereClauses) => - new ExistentialTypeTree(importTree(tpt), whereClauses map importTree) - case from.EmptyTree => - EmptyTree - case null => - null - } - addFixup({ - if (mytree != null) { - val mysym = if (tree.hasSymbolField) importSymbol(tree.symbol) else NoSymbol - val mytpe = importType(tree.tpe) - - mytree match { - case mytt: TypeTree => - val tt = tree.asInstanceOf[from.TypeTree] - if (mytree.hasSymbolField) mytt.symbol = mysym - if (tt.wasEmpty) mytt.defineType(mytpe) else mytt.setType(mytpe) - if (tt.original != null) mytt.setOriginal(importTree(tt.original)) - case _ => - if (mytree.hasSymbolField) mytree.symbol = importSymbol(tree.symbol) - mytree setType importType(tree.tpe) - } - } - }) - tryFixup() - mytree - } - def importValDef(tree: from.ValDef): ValDef = importTree(tree).asInstanceOf[ValDef] def importTypeDef(tree: from.TypeDef): TypeDef = importTree(tree).asInstanceOf[TypeDef] def importTemplate(tree: from.Template): Template = importTree(tree).asInstanceOf[Template] -- cgit v1.2.3 From 10229316dbf7afa7545d8e279b5960da6ee3db7d Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Sat, 19 Jan 2013 12:28:19 +0100 Subject: refactors macro compilation Upgrades the way that macro defs are compiled by factoring out most of the logic in typedMacroBody and related errors in ContextErrors into an standalone cake. This leads to tighter cohesion and better code reuse as the cake is isolated from the rest of the compiler and is much easier to evolve than just a method body. Increased convenience of coding macro compilation allowed me to further clarify the implementation of the macro engine (e.g. take a look at Validators.scala) and to easily implement additional features, namely: 1) Parameters and return type of macro implementations can now be plain c.Tree's instead of previously mandatory c.Expr's. This makes macros more lightweight as there are a lot of situations when one doesn't need to splice macro params (the only motivation to use exprs over trees). Also as we're on the verge of having quasiquotes in trunk, there soon will be no reason to use exprs at all, since quasiquotes can splice everything. 2) Macro implementations can now be defined in bundles, standalone cakes built around a macro context: http://docs.scala-lang.org/overviews/macros/bundles.html. This further reduces boilerplate by simplifying implementations complex macros due to the fact that macro programmers no longer need to play path-dependent games to use helpers. --- .../macros/compiler/DefaultMacroCompiler.scala | 33 ++ .../scala/reflect/macros/compiler/Errors.scala | 113 ++++++ .../scala/reflect/macros/compiler/Resolvers.scala | 91 +++++ .../scala/reflect/macros/compiler/Validators.scala | 193 +++++++++ .../scala/reflect/macros/runtime/Synthetics.scala | 19 +- .../scala/reflect/macros/util/Helpers.scala | 71 ++++ src/compiler/scala/tools/nsc/Global.scala | 21 + .../tools/nsc/typechecker/ContextErrors.scala | 158 +------- .../scala/tools/nsc/typechecker/Macros.scala | 443 +++++---------------- .../tools/nsc/typechecker/StdAttachments.scala | 27 ++ .../scala/tools/nsc/typechecker/Typers.scala | 7 +- src/compiler/scala/tools/reflect/FastTrack.scala | 1 + src/reflect/scala/reflect/api/Trees.scala | 14 + .../scala/reflect/internal/Definitions.scala | 14 + src/reflect/scala/reflect/internal/StdNames.scala | 5 + src/reflect/scala/reflect/internal/TreeInfo.scala | 13 +- src/reflect/scala/reflect/internal/Trees.scala | 13 + src/reflect/scala/reflect/macros/Macro.scala | 39 ++ .../scala/reflect/runtime/JavaMirrors.scala | 4 +- test/files/neg/macro-invalidimpl.check | 30 +- test/files/neg/macro-invalidret.check | 4 +- test/files/neg/macro-invalidshape.check | 14 +- .../neg/macro-invalidsig-params-badtype.check | 6 +- .../Impls_Macros_1.scala | 2 +- test/files/neg/macro-invalidsig.check | 26 +- test/files/neg/t5689.check | 2 +- .../run/macro-bodyexpandstoimpl/Impls_1.scala | 2 + test/files/run/macro-bundle.check | 3 + test/files/run/macro-bundle.flags | 1 + test/files/run/macro-bundle/Impls_Macros_1.scala | 13 + test/files/run/macro-bundle/Test_2.scala | 5 + .../run/macro-toplevel-companion-b/Test_2.scala | 2 +- test/files/run/macro-toplevel-companion-c.scala | 2 +- 33 files changed, 837 insertions(+), 554 deletions(-) create mode 100644 src/compiler/scala/reflect/macros/compiler/DefaultMacroCompiler.scala create mode 100644 src/compiler/scala/reflect/macros/compiler/Errors.scala create mode 100644 src/compiler/scala/reflect/macros/compiler/Resolvers.scala create mode 100644 src/compiler/scala/reflect/macros/compiler/Validators.scala create mode 100644 src/compiler/scala/reflect/macros/util/Helpers.scala create mode 100644 src/reflect/scala/reflect/macros/Macro.scala create mode 100644 test/files/run/macro-bundle.check create mode 100644 test/files/run/macro-bundle.flags create mode 100644 test/files/run/macro-bundle/Impls_Macros_1.scala create mode 100644 test/files/run/macro-bundle/Test_2.scala diff --git a/src/compiler/scala/reflect/macros/compiler/DefaultMacroCompiler.scala b/src/compiler/scala/reflect/macros/compiler/DefaultMacroCompiler.scala new file mode 100644 index 0000000000..749e730c0e --- /dev/null +++ b/src/compiler/scala/reflect/macros/compiler/DefaultMacroCompiler.scala @@ -0,0 +1,33 @@ +package scala.reflect.macros +package compiler + +import scala.tools.nsc.Global +import scala.reflect.macros.runtime.Context + +abstract class DefaultMacroCompiler extends Resolvers + with Validators + with Errors { + val global: Global + import global._ + + val typer: global.analyzer.Typer + private implicit val context0 = typer.context + val context = typer.context + + val macroDdef: DefDef + lazy val macroDef = macroDdef.symbol + + private case class MacroImplResolutionException(pos: Position, msg: String) extends Exception + def abort(pos: Position, msg: String) = throw MacroImplResolutionException(pos, msg) + + def resolveMacroImpl: Tree = { + try { + validateMacroImplRef() + macroImplRef + } catch { + case MacroImplResolutionException(pos, msg) => + context.error(pos, msg) + EmptyTree + } + } +} \ No newline at end of file diff --git a/src/compiler/scala/reflect/macros/compiler/Errors.scala b/src/compiler/scala/reflect/macros/compiler/Errors.scala new file mode 100644 index 0000000000..dd3142127e --- /dev/null +++ b/src/compiler/scala/reflect/macros/compiler/Errors.scala @@ -0,0 +1,113 @@ +package scala.reflect.macros +package compiler + +import scala.compat.Platform.EOL +import scala.reflect.macros.util.Traces + +trait Errors extends Traces { + self: DefaultMacroCompiler => + + import global._ + import analyzer._ + import definitions._ + import typer.TyperErrorGen._ + import typer.infer.InferErrorGen._ + def globalSettings = global.settings + + // sanity check errors + + private def implRefError(message: String) = abort(macroDdef.pos, message) + + def MacroImplReferenceWrongShapeError() = implRefError( + "macro implementation reference has wrong shape. required:\n"+ + "macro [].[[]] or\n" + + "macro [].[[]]") + + def MacroImplNotPublicError() = implRefError("macro implementation must be public") + + def MacroImplOverloadedError() = implRefError("macro implementation cannot be overloaded") + + def MacroImplWrongNumberOfTypeArgumentsError() = implRefError(TypedApplyWrongNumberOfTpeParametersErrorMessage(macroImplRef)) + + // compatibility errors + + // helpers + + private def lengthMsg(flavor: String, violation: String, extra: Symbol) = { + val noun = if (flavor == "value") "parameter" else "type parameter" + val message = noun + " lists have different length, " + violation + " extra " + noun + val suffix = if (extra ne NoSymbol) " " + extra.defString else "" + message + suffix + } + + private def abbreviateCoreAliases(s: String): String = List("WeakTypeTag", "Expr").foldLeft(s)((res, x) => res.replace("c.universe." + x, "c." + x)) + + private def showMeth(pss: List[List[Symbol]], restpe: Type, abbreviate: Boolean) = { + var argsPart = (pss map (ps => ps map (_.defString) mkString ("(", ", ", ")"))).mkString + if (abbreviate) argsPart = abbreviateCoreAliases(argsPart) + var retPart = restpe.toString + if (abbreviate || macroDdef.tpt.tpe == null) retPart = abbreviateCoreAliases(retPart) + argsPart + ": " + retPart + } + + // not exactly an error generator, but very related + // and I dearly wanted to push it away from Macros.scala + private def checkConforms(slot: String, rtpe: Type, atpe: Type) = { + val verbose = macroDebugVerbose || settings.explaintypes.value + + def check(rtpe: Type, atpe: Type): Boolean = { + def success() = { if (verbose) println(rtpe + " <: " + atpe + "?" + EOL + "true"); true } + (rtpe, atpe) match { + case _ if rtpe eq atpe => success() + case (TypeRef(_, RepeatedParamClass, rtpe :: Nil), TypeRef(_, RepeatedParamClass, atpe :: Nil)) => check(rtpe, atpe) + case (ExprClassOf(_), TreeType()) => success() + case (TreeType(), ExprClassOf(_)) => success() + case _ => rtpe <:< atpe + } + } + + val ok = + if (verbose) withTypesExplained(check(rtpe, atpe)) + else check(rtpe, atpe) + if (!ok) { + if (!macroDebugVerbose) + explainTypes(rtpe, atpe) + compatibilityError("type mismatch for %s: %s does not conform to %s".format(slot, abbreviateCoreAliases(rtpe.toString), abbreviateCoreAliases(atpe.toString))) + } + } + + private def compatibilityError(message: String) = + implRefError( + "macro implementation has wrong shape:"+ + "\n required: " + showMeth(rparamss, rret, abbreviate = true) + + "\n found : " + showMeth(aparamss, aret, abbreviate = false) + + "\n" + message) + + def MacroImplNonTagImplicitParameters(params: List[Symbol]) = compatibilityError("macro implementations cannot have implicit parameters other than WeakTypeTag evidences") + + def MacroImplParamssMismatchError() = compatibilityError("number of parameter sections differ") + + def MacroImplExtraParamsError(aparams: List[Symbol], rparams: List[Symbol]) = compatibilityError(lengthMsg("value", "found", aparams(rparams.length))) + + def MacroImplMissingParamsError(aparams: List[Symbol], rparams: List[Symbol]) = compatibilityError(abbreviateCoreAliases(lengthMsg("value", "required", rparams(aparams.length)))) + + def checkMacroImplParamTypeMismatch(atpe: Type, rparam: Symbol) = checkConforms("parameter " + rparam.name, rparam.tpe, atpe) + + def checkMacroImplResultTypeMismatch(atpe: Type, rret: Type) = checkConforms("return type", atpe, rret) + + def MacroImplParamNameMismatchError(aparam: Symbol, rparam: Symbol) = compatibilityError("parameter names differ: " + rparam.name + " != " + aparam.name) + + def MacroImplVarargMismatchError(aparam: Symbol, rparam: Symbol) = { + def fail(paramName: Name) = compatibilityError("types incompatible for parameter " + paramName + ": corresponding is not a vararg parameter") + if (isRepeated(rparam) && !isRepeated(aparam)) fail(rparam.name) + if (!isRepeated(rparam) && isRepeated(aparam)) fail(aparam.name) + } + + def MacroImplTargMismatchError(atargs: List[Type], atparams: List[Symbol]) = + compatibilityError(NotWithinBoundsErrorMessage("", atargs, atparams, macroDebugVerbose || settings.explaintypes.value)) + + def MacroImplTparamInstantiationError(atparams: List[Symbol], ex: NoInstance) = + compatibilityError( + "type parameters "+(atparams map (_.defString) mkString ", ")+" cannot be instantiated\n"+ + ex.getMessage) +} \ No newline at end of file diff --git a/src/compiler/scala/reflect/macros/compiler/Resolvers.scala b/src/compiler/scala/reflect/macros/compiler/Resolvers.scala new file mode 100644 index 0000000000..3025eb52a1 --- /dev/null +++ b/src/compiler/scala/reflect/macros/compiler/Resolvers.scala @@ -0,0 +1,91 @@ +package scala.reflect.macros +package compiler + +import scala.reflect.internal.Flags._ +import scala.reflect.macros.TypecheckException + +trait Resolvers { + self: DefaultMacroCompiler => + + import global._ + import analyzer._ + import definitions._ + import treeInfo._ + import gen._ + + /** Determines the type of context implied by the macro def. + */ + val ctxTpe = MacroContextClass.tpe + + /** Resolves a macro impl reference provided in the right-hand side of the given macro definition. + * + * Acceptable shapes of the right-hand side: + * 1) [].[[]] // vanilla macro def + * 2) [].[[]] // shiny new macro bundle + * + * Produces a tree, which represents a reference to a macro implementation if everything goes well, + * otherwise reports found errors and returns EmptyTree. The resulting tree should have the following format: + * + * qualifier.method[targs] + * + * Qualifier here might be omitted (local macro defs), be a static object (vanilla macro defs) + * or be a dummy instance of a macro bundle (e.g. new MyMacro(???).expand). + */ + lazy val macroImplRef: Tree = { + val (maybeBundleRef, methName, targs) = macroDdef.rhs match { + case Applied(methRef @ Select(bundleRef @ RefTree(qual, bundleName), methName), targs, Nil) => + (RefTree(qual, bundleName.toTypeName), methName, targs) + case Applied(Ident(methName), targs, Nil) => + (Ident(context.owner.enclClass), methName, targs) + case _ => + (EmptyTree, TermName(""), Nil) + } + + val untypedImplRef = typer.silent(_.typedType(maybeBundleRef)) match { + case SilentResultValue(result) if isMacroBundleType(result.tpe) => + val bundleClass = result.tpe.typeSymbol + if (!bundleClass.owner.isPackageClass) abort(macroDef.pos, "macro bundles can only be defined as top-level classes or traits") + + // synthesize the invoker, i.e. given a top-level `trait Foo extends Macro { def expand = ... } ` + // create a top-level definition `class FooInvoker(val c: Context) extends Foo` in MACRO_INVOKER_PACKAGE + val invokerPid = gen.mkUnattributedRef(nme.MACRO_INVOKER_PACKAGE) + val invokerName = TypeName(bundleClass.fullName.split('.').map(_.capitalize).mkString("") + nme.MACRO_INVOKER_SUFFIX) + val invokerFullName = TypeName(s"$invokerPid.$invokerName") + val existingInvoker = rootMirror.getClassIfDefined(invokerFullName) + if (!currentRun.compiles(existingInvoker)) { + def mkContextValDef(flags: Long) = ValDef(Modifiers(flags), nme.c, TypeTree(ctxTpe), EmptyTree) + val contextField = mkContextValDef(PARAMACCESSOR) + val contextParam = mkContextValDef(PARAM | PARAMACCESSOR) + val invokerCtor = DefDef(Modifiers(), nme.CONSTRUCTOR, Nil, List(List(contextParam)), TypeTree(), Block(List(pendingSuperCall), Literal(Constant(())))) + val invoker = atPos(bundleClass.pos)(ClassDef(NoMods, invokerName, Nil, Template(List(Ident(bundleClass)), emptyValDef, List(contextField, invokerCtor)))) + currentRun.compileLate(PackageDef(invokerPid, List(invoker))) + } + + // synthesize the macro impl reference, which is going to look like: + // `new Foo$invoker(???).expand` plus the optional type arguments + val instanceOfInvoker = New(Select(invokerPid, invokerName), List(List(Select(scalaDot(nme.Predef), nme.???)))) + gen.mkTypeApply(Select(instanceOfInvoker, methName), targs) + case _ => + macroDdef.rhs + } + + val typedImplRef = typer.silent(_.typed(markMacroImplRef(untypedImplRef)), reportAmbiguousErrors = false) + typedImplRef match { + case SilentResultValue(success) => success + case SilentTypeError(err) => abort(err.errPos, err.errMsg) + } + } + + // FIXME: cannot write this concisely because of SI-7507 + // lazy val (isImplBundle, macroImplOwner, macroImpl, macroImplTargs) = + private lazy val dissectedMacroImplRef = + macroImplRef match { + case MacroImplReference(isBundle, owner, meth, targs) => (isBundle, owner, meth, targs) + case _ => MacroImplReferenceWrongShapeError() + } + lazy val isImplBundle = dissectedMacroImplRef._1 + lazy val isImplMethod = !isImplBundle + lazy val macroImplOwner = dissectedMacroImplRef._2 + lazy val macroImpl = dissectedMacroImplRef._3 + lazy val targs = dissectedMacroImplRef._4 +} diff --git a/src/compiler/scala/reflect/macros/compiler/Validators.scala b/src/compiler/scala/reflect/macros/compiler/Validators.scala new file mode 100644 index 0000000000..60cfc94a23 --- /dev/null +++ b/src/compiler/scala/reflect/macros/compiler/Validators.scala @@ -0,0 +1,193 @@ +package scala.reflect.macros +package compiler + +import java.util.UUID.randomUUID +import scala.reflect.internal.Flags._ +import scala.reflect.macros.TypecheckException + +trait Validators { + self: DefaultMacroCompiler => + + import global._ + import analyzer._ + import definitions._ + import treeInfo._ + import typer.infer._ + + def validateMacroImplRef() = { + sanityCheck() + if (macroImpl != Predef_???) checkMacroDefMacroImplCorrespondence() + } + + private def sanityCheck() = { + if (!macroImpl.isMethod) MacroImplReferenceWrongShapeError() + if (!macroImpl.isPublic) MacroImplNotPublicError() + if (macroImpl.isOverloaded) MacroImplOverloadedError() + if (macroImpl.typeParams.length != targs.length) MacroImplWrongNumberOfTypeArgumentsError() + val declaredInStaticObject = isImplMethod && (macroImplOwner.isStaticOwner || macroImplOwner.moduleClass.isStaticOwner) + val declaredInTopLevelClass = isImplBundle && macroImplOwner.owner.isPackageClass + if (!declaredInStaticObject && !declaredInTopLevelClass) MacroImplReferenceWrongShapeError() + } + + private def checkMacroDefMacroImplCorrespondence() = { + val atvars = atparams map freshVar + def atpeToRtpe(atpe: Type) = atpe.substSym(aparamss.flatten, rparamss.flatten).instantiateTypeParams(atparams, atvars) + + // we only check strict correspondence between value parameterss + // type parameters of macro defs and macro impls don't have to coincide with each other + val implicitParams = aparamss.flatten filter (_.isImplicit) + if (implicitParams.nonEmpty) MacroImplNonTagImplicitParameters(implicitParams) + if (aparamss.length != rparamss.length) MacroImplParamssMismatchError() + map2(aparamss, rparamss)((aparams, rparams) => { + if (aparams.length < rparams.length) MacroImplMissingParamsError(aparams, rparams) + if (rparams.length < aparams.length) MacroImplExtraParamsError(aparams, rparams) + }) + + try { + // cannot fuse this map2 and the map2 above because if aparamss.flatten != rparamss.flatten + // then `atpeToRtpe` is going to fail with an unsound substitution + map2(aparamss.flatten, rparamss.flatten)((aparam, rparam) => { + if (aparam.name != rparam.name && !rparam.isSynthetic) MacroImplParamNameMismatchError(aparam, rparam) + if (isRepeated(aparam) ^ isRepeated(rparam)) MacroImplVarargMismatchError(aparam, rparam) + val aparamtpe = aparam.tpe.dealias match { + case RefinedType(List(tpe), Scope(sym)) if tpe =:= ctxTpe && sym.allOverriddenSymbols.contains(MacroContextPrefixType) => tpe + case tpe => tpe + } + checkMacroImplParamTypeMismatch(atpeToRtpe(aparamtpe), rparam) + }) + + checkMacroImplResultTypeMismatch(atpeToRtpe(aret), rret) + + val maxLubDepth = lubDepth(aparamss.flatten map (_.tpe)) max lubDepth(rparamss.flatten map (_.tpe)) + val atargs = solvedTypes(atvars, atparams, atparams map varianceInType(aret), upper = false, depth = maxLubDepth) + val boundsOk = typer.silent(_.infer.checkBounds(macroDdef, NoPrefix, NoSymbol, atparams, atargs, "")) + boundsOk match { + case SilentResultValue(true) => // do nothing, success + case SilentResultValue(false) | SilentTypeError(_) => MacroImplTargMismatchError(atargs, atparams) + } + } catch { + case ex: NoInstance => MacroImplTparamInstantiationError(atparams, ex) + } + } + + // aXXX (e.g. aparamss) => characteristics of the actual macro impl signature extracted from the macro impl ("a" stands for "actual") + // rXXX (e.g. rparamss) => characteristics of the reference macro impl signature synthesized from the macro def ("r" stands for "reference") + // FIXME: cannot write this concisely because of SI-7507 + //lazy val MacroImplSig(atparams, aparamss, aret) = macroImplSig + //lazy val MacroImplSig(_, rparamss, rret) = referenceMacroImplSig + lazy val atparams = macroImplSig.tparams + lazy val aparamss = macroImplSig.paramss + lazy val aret = macroImplSig.ret + lazy val rparamss = referenceMacroImplSig.paramss + lazy val rret = referenceMacroImplSig.ret + + // Technically this can be just an alias to MethodType, but promoting it to a first-class entity + // provides better encapsulation and convenient syntax for pattern matching. + private case class MacroImplSig(tparams: List[Symbol], paramss: List[List[Symbol]], ret: Type) + + /** An actual macro implementation signature extracted from a macro implementation method. + * + * For the following macro impl: + * def fooBar[T: c.WeakTypeTag] + * (c: scala.reflect.macros.Context) + * (xs: c.Expr[List[T]]) + * : c.Expr[T] = ... + * + * This function will return: + * (c: scala.reflect.macros.Context)(xs: c.Expr[List[T]])c.Expr[T] + * + * Note that type tag evidence parameters are not included into the result. + * Type tag context bounds for macro impl tparams are optional. + * Therefore compatibility checks ignore such parameters, and we don't need to bother about them here. + * + * This method cannot be reduced to just macroImpl.info, because macro implementations might + * come in different shapes. If the implementation is an apply method of a Macro-compatible object, + * then it won't have (c: Context) in its parameters, but will rather refer to Macro.c. + * + * @param macroImpl The macro implementation symbol + */ + private lazy val macroImplSig: MacroImplSig = { + val tparams = macroImpl.typeParams + val paramss = transformTypeTagEvidenceParams(macroImplRef, (param, tparam) => NoSymbol) + val ret = macroImpl.info.finalResultType + MacroImplSig(tparams, paramss, ret) + } + + /** A reference macro implementation signature extracted from a given macro definition. + * + * For the following macro def: + * def foo[T](xs: List[T]): T = macro fooBar + * + * This function will return: + * (c: scala.reflect.macros.Context)(xs: c.Expr[List[T]])c.Expr[T] + * + * Note that type tag evidence parameters are not included into the result. + * Type tag context bounds for macro impl tparams are optional. + * Therefore compatibility checks ignore such parameters, and we don't need to bother about them here. + * + * Also note that we need a DefDef, not the corresponding MethodSymbol, because that symbol would be of no use for us. + * Macro signatures are verified when typechecking macro defs, which means that at that moment inspecting macroDef.info + * means asking for cyclic reference errors. + * + * We need macro implementation symbol as well, because the return type of the macro definition might be omitted, + * and in that case we'd need to infer it from the return type of the macro implementation. Luckily for us, we can + * use that symbol without a risk of running into cycles. + * + * @param typer Typechecker of `macroDdef` + * @param macroDdef The macro definition tree + * @param macroImpl The macro implementation symbol + */ + private lazy val referenceMacroImplSig: MacroImplSig = { + // had to move method's body to an object because of the recursive dependencies between sigma and param + object SigGenerator { + val cache = scala.collection.mutable.Map[Symbol, Symbol]() + val ctxPrefix = + if (isImplMethod) singleType(NoPrefix, makeParam(nme.macroContext, macroDdef.pos, ctxTpe, SYNTHETIC)) + else singleType(ThisType(macroImpl.owner), macroImpl.owner.tpe.member(nme.c)) + var paramss = + if (isImplMethod) List(ctxPrefix.termSymbol) :: mmap(macroDdef.vparamss)(param) + else mmap(macroDdef.vparamss)(param) + val macroDefRet = + if (!macroDdef.tpt.isEmpty) typer.typedType(macroDdef.tpt).tpe + else computeMacroDefTypeFromMacroImplRef(macroDdef, macroImplRef) + val implReturnType = sigma(increaseMetalevel(ctxPrefix, macroDefRet)) + + object SigmaTypeMap extends TypeMap { + def mapPrefix(pre: Type) = pre match { + case ThisType(sym) if sym == macroDef.owner => + singleType(singleType(ctxPrefix, MacroContextPrefix), ExprValue) + case SingleType(NoPrefix, sym) => + mfind(macroDdef.vparamss)(_.symbol == sym).fold(pre)(p => singleType(singleType(NoPrefix, param(p)), ExprValue)) + case _ => + mapOver(pre) + } + def apply(tp: Type): Type = tp match { + case TypeRef(pre, sym, args) => + val pre1 = mapPrefix(pre) + val args1 = mapOverArgs(args, sym.typeParams) + if ((pre eq pre1) && (args eq args1)) tp + else typeRef(pre1, sym, args1) + case _ => + mapOver(tp) + } + } + def sigma(tpe: Type): Type = SigmaTypeMap(tpe) + + def makeParam(name: Name, pos: Position, tpe: Type, flags: Long) = + macroDef.newValueParameter(name.toTermName, pos, flags) setInfo tpe + def param(tree: Tree): Symbol = ( + cache.getOrElseUpdate(tree.symbol, { + val sym = tree.symbol + assert(sym.isTerm, s"sym = $sym, tree = $tree") + makeParam(sym.name, sym.pos, sigma(increaseMetalevel(ctxPrefix, sym.tpe)), sym.flags) + }) + ) + } + + import SigGenerator._ + macroLogVerbose(s"generating macroImplSigs for: $macroDdef") + val result = MacroImplSig(macroDdef.tparams map (_.symbol), paramss, implReturnType) + macroLogVerbose(s"result is: $result") + result + } +} diff --git a/src/compiler/scala/reflect/macros/runtime/Synthetics.scala b/src/compiler/scala/reflect/macros/runtime/Synthetics.scala index 73f3ab8d20..1156769a80 100644 --- a/src/compiler/scala/reflect/macros/runtime/Synthetics.scala +++ b/src/compiler/scala/reflect/macros/runtime/Synthetics.scala @@ -5,7 +5,6 @@ package scala.reflect.macros package runtime -import java.util.UUID._ import scala.reflect.internal.Flags._ import scala.reflect.internal.util.BatchSourceFile import scala.reflect.io.VirtualFile @@ -42,11 +41,6 @@ trait Synthetics { else EmptyTree } - // TODO: provide a way to specify a pretty name for debugging purposes - private def randomFileName() = ( - "macroSynthetic-" + randomUUID().toString.replace("-", "") + ".scala" - ) - def introduceTopLevel[T: PackageSpec](packagePrototype: T, definition: universe.ImplDef): RefTree = introduceTopLevel(packagePrototype, List(definition)).head @@ -55,18 +49,7 @@ trait Synthetics { private def introduceTopLevel[T: PackageSpec](packagePrototype: T, definitions: List[universe.ImplDef]): List[RefTree] = { val code @ PackageDef(pid, _) = implicitly[PackageSpec[T]].mkPackageDef(packagePrototype, definitions) - val syntheticFileName = randomFileName() - // compatibility with SBT - // on the one hand, we need to specify some jfile here, otherwise sbt crashes with an NPE (SI-6870) - // on the other hand, we can't specify the obvious enclosingUnit, because then sbt somehow fails to run tests using type macros - // okay, now let's specify a guaranteedly non-existent file in an existing directory (so that we don't run into permission problems) - val relatedJfile = enclosingUnit.source.file.file - val fakeJfile = if (relatedJfile != null) new java.io.File(relatedJfile.getParent, syntheticFileName) else null - val virtualFile = new VirtualFile(syntheticFileName) { override def file = fakeJfile } - val sourceFile = new BatchSourceFile(virtualFile, code.toString) - val unit = new CompilationUnit(sourceFile) - unit.body = code - universe.currentRun.compileLate(unit) + universe.currentRun.compileLate(code) definitions map (definition => Select(pid, definition.name)) } diff --git a/src/compiler/scala/reflect/macros/util/Helpers.scala b/src/compiler/scala/reflect/macros/util/Helpers.scala new file mode 100644 index 0000000000..ada8efa833 --- /dev/null +++ b/src/compiler/scala/reflect/macros/util/Helpers.scala @@ -0,0 +1,71 @@ +package scala.reflect.macros +package util + +import scala.tools.nsc.typechecker.Analyzer + +trait Helpers { + self: Analyzer => + + import global._ + import definitions._ + + /** Transforms parameters lists of a macro impl. + * The `transform` function is invoked only for WeakTypeTag evidence parameters. + * + * The transformer takes two arguments: a value parameter from the parameter list + * and a type parameter that is witnesses by the value parameter. + * + * If the transformer returns a NoSymbol, the value parameter is not included from the result. + * If the transformer returns something else, this something else is included in the result instead of the value parameter. + * + * Despite of being highly esoteric, this function significantly simplifies signature analysis. + * For example, it can be used to strip macroImpl.paramss from the evidences (necessary when checking def <-> impl correspondence) + * or to streamline creation of the list of macro arguments. + */ + def transformTypeTagEvidenceParams(macroImplRef: Tree, transform: (Symbol, Symbol) => Symbol): List[List[Symbol]] = { + val treeInfo.MacroImplReference(isBundle, owner, macroImpl, _) = macroImplRef + val paramss = macroImpl.paramss + if (paramss.isEmpty || paramss.last.isEmpty) return paramss // no implicit parameters in the signature => nothing to do + val rc = + if (isBundle) macroImpl.owner.tpe.member(nme.c) + else { + def cparam = paramss.head.head + if (paramss.head.isEmpty || !(cparam.tpe <:< MacroContextClass.tpe)) return paramss // no context parameter in the signature => nothing to do + cparam + } + def transformTag(param: Symbol): Symbol = param.tpe.dealias match { + case TypeRef(SingleType(SingleType(_, ac), universe), WeakTypeTagClass, targ :: Nil) + if ac == rc && universe == MacroContextUniverse => + transform(param, targ.typeSymbol) + case _ => + param + } + val transformed = paramss.last map transformTag filter (_ ne NoSymbol) + if (transformed.isEmpty) paramss.init else paramss.init :+ transformed + } + + private def dealiasAndRewrap(tp: Type)(fn: Type => Type): Type = { + if (isRepeatedParamType(tp)) scalaRepeatedType(fn(tp.typeArgs.head.dealias)) + else fn(tp.dealias) + } + + /** Increases metalevel of the type, i.e. transforms: + * * T to c.Expr[T] + * + * @see Metalevels.scala for more information and examples about metalevels + */ + def increaseMetalevel(pre: Type, tp: Type): Type = dealiasAndRewrap(tp) { + case tp => typeRef(pre, MacroContextExprClass, List(tp)) + } + + /** Decreases metalevel of the type, i.e. transforms: + * * c.Expr[T] to T + * * Anything else to Any + * + * @see Metalevels.scala for more information and examples about metalevels + */ + def decreaseMetalevel(tp: Type): Type = dealiasAndRewrap(tp) { + case ExprClassOf(runtimeType) => runtimeType + case _ => AnyClass.tpe // so that macro impls with rhs = ??? don't screw up our inference + } +} \ No newline at end of file diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala index f1fccd6069..a08633ffc8 100644 --- a/src/compiler/scala/tools/nsc/Global.scala +++ b/src/compiler/scala/tools/nsc/Global.scala @@ -9,6 +9,7 @@ package nsc import java.io.{ File, FileOutputStream, PrintWriter, IOException, FileNotFoundException } import java.nio.charset.{ Charset, CharsetDecoder, IllegalCharsetNameException, UnsupportedCharsetException } +import java.util.UUID._ import scala.compat.Platform.currentTime import scala.collection.{ mutable, immutable } import io.{ SourceReader, AbstractFile, Path } @@ -16,6 +17,7 @@ import reporters.{ Reporter, ConsoleReporter } import util.{ ClassPath, MergedClassPath, StatisticsInfo, returning, stackTraceString, stackTraceHeadString } import scala.reflect.internal.util.{ OffsetPosition, SourceFile, NoSourceFile, BatchSourceFile, ScriptSourceFile } import scala.reflect.internal.pickling.{ PickleBuffer, PickleFormat } +import scala.reflect.io.VirtualFile import symtab.{ Flags, SymbolTable, SymbolLoaders, SymbolTrackers } import symtab.classfile.Pickler import plugins.Plugins @@ -1621,6 +1623,25 @@ class Global(var currentSettings: Settings, var reporter: Reporter) } } + // TODO: provide a way to specify a pretty name for debugging purposes + private def randomFileName() = ( + "compileLateSynthetic-" + randomUUID().toString.replace("-", "") + ".scala" + ) + + def compileLate(code: PackageDef) { + // compatibility with SBT + // on the one hand, we need to specify some jfile here, otherwise sbt crashes with an NPE (SI-6870) + // on the other hand, we can't specify the obvious enclosingUnit, because then sbt somehow fails to run tests using type macros + // okay, now let's specify a guaranteedly non-existent file in an existing directory (so that we don't run into permission problems) + val syntheticFileName = randomFileName() + val fakeJfile = new java.io.File(syntheticFileName) + val virtualFile = new VirtualFile(syntheticFileName) { override def file = fakeJfile } + val sourceFile = new BatchSourceFile(virtualFile, code.toString) + val unit = new CompilationUnit(sourceFile) + unit.body = code + compileLate(unit) + } + /** Reset package class to state at typer (not sure what this * is needed for?) */ diff --git a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala index 054f96c7b7..09ac13982d 100644 --- a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala +++ b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala @@ -460,7 +460,7 @@ trait ContextErrors { def AbstractionFromVolatileTypeError(vd: ValDef) = issueNormalTypeError(vd, "illegal abstraction from value with volatile type "+vd.symbol.tpe) - private[ContextErrors] def TypedApplyWrongNumberOfTpeParametersErrorMessage(fun: Tree) = + private[scala] def TypedApplyWrongNumberOfTpeParametersErrorMessage(fun: Tree) = "wrong number of type parameters for "+treeSymTypeMsg(fun) def TypedApplyWrongNumberOfTpeParametersError(tree: Tree, fun: Tree) = { @@ -692,7 +692,6 @@ trait ContextErrors { issueNormalTypeError(expandee, s"macro in $role role can only expand into $allowedExpansions") } - // same reason as for MacroBodyTypecheckException case object MacroExpansionException extends Exception with scala.util.control.ControlThrowable protected def macroExpansionError(expandee: Tree, msg: String, pos: Position = NoPosition) = { @@ -712,14 +711,14 @@ trait ContextErrors { } private def MacroTooFewArgumentListsMessage = "too few argument lists for macro invocation" - def MacroTooFewArgumentLists(expandee: Tree) = macroExpansionError2(expandee, MacroTooFewArgumentListsMessage) + def MacroTooFewArgumentListsError(expandee: Tree) = macroExpansionError2(expandee, MacroTooFewArgumentListsMessage) private def MacroTooManyArgumentListsMessage = "too many argument lists for macro invocation" - def MacroTooManyArgumentLists(expandee: Tree) = macroExpansionError2(expandee, MacroTooManyArgumentListsMessage) + def MacroTooManyArgumentListsError(expandee: Tree) = macroExpansionError2(expandee, MacroTooManyArgumentListsMessage) - def MacroTooFewArguments(expandee: Tree) = macroExpansionError2(expandee, "too few arguments for macro invocation") + def MacroTooFewArgumentsError(expandee: Tree) = macroExpansionError2(expandee, "too few arguments for macro invocation") - def MacroTooManyArguments(expandee: Tree) = macroExpansionError2(expandee, "too many arguments for macro invocation") + def MacroTooManyArgumentsError(expandee: Tree) = macroExpansionError2(expandee, "too many arguments for macro invocation") def MacroGeneratedAbort(expandee: Tree, ex: AbortMacroException) = { // errors have been reported by the macro itself, so we do nothing here @@ -926,7 +925,7 @@ trait ContextErrors { kindErrors.toList.mkString("\n", ", ", "")) } - private[ContextErrors] def NotWithinBoundsErrorMessage(prefix: String, targs: List[Type], tparams: List[Symbol], explaintypes: Boolean) = { + private[scala] def NotWithinBoundsErrorMessage(prefix: String, targs: List[Type], tparams: List[Symbol], explaintypes: Boolean) = { if (explaintypes) { val bounds = tparams map (tp => tp.info.instantiateTypeParams(tparams, targs).bounds) (targs, bounds).zipped foreach ((targ, bound) => explainTypes(bound.lo, targ)) @@ -1233,149 +1232,4 @@ trait ContextErrors { setError(arg) } } - - // using an exception here is actually a good idea - // because the lifespan of this exception is extremely small and controlled - // moreover exceptions let us avoid an avalanche of "if (!hasError) do stuff" checks - case object MacroBodyTypecheckException extends Exception with scala.util.control.ControlThrowable - - trait MacroErrors { - self: MacroTyper => - - private implicit val context0 = typer.context - val context = typer.context - - // helpers - - private def lengthMsg(flavor: String, violation: String, extra: Symbol) = { - val noun = if (flavor == "value") "parameter" else "type parameter" - val message = noun + " lists have different length, " + violation + " extra " + noun - val suffix = if (extra ne NoSymbol) " " + extra.defString else "" - message + suffix - } - - private def abbreviateCoreAliases(s: String): String = List("WeakTypeTag", "Expr").foldLeft(s)((res, x) => res.replace("c.universe." + x, "c." + x)) - - private def showMeth(pss: List[List[Symbol]], restpe: Type, abbreviate: Boolean) = { - var argsPart = (pss map (ps => ps map (_.defString) mkString ("(", ", ", ")"))).mkString - if (abbreviate) argsPart = abbreviateCoreAliases(argsPart) - var retPart = restpe.toString - if (abbreviate || macroDdef.tpt.tpe == null) retPart = abbreviateCoreAliases(retPart) - argsPart + ": " + retPart - } - - // not exactly an error generator, but very related - // and I dearly wanted to push it away from Macros.scala - private def checkConforms(slot: String, rtpe: Type, atpe: Type) = { - val verbose = macroDebugVerbose || settings.explaintypes.value - - def check(rtpe: Type, atpe: Type): Boolean = { - if (rtpe eq atpe) { if (verbose) println(rtpe + " <: " + atpe + "?" + EOL + "true"); true } - else rtpe <:< atpe - } - - val ok = - if (verbose) withTypesExplained(check(rtpe, atpe)) - else check(rtpe, atpe) - if (!ok) { - if (!macroDebugVerbose) - explainTypes(rtpe, atpe) - compatibilityError("type mismatch for %s: %s does not conform to %s".format(slot, abbreviateCoreAliases(rtpe.toString), abbreviateCoreAliases(atpe.toString))) - } - } - - // errors - - private def fail() = { - // need to set the IS_ERROR flag to prohibit spurious expansions - if (macroDef != null) macroDef setFlag IS_ERROR - // not setting ErrorSymbol as in `infer.setError`, because we still need to know that it's a macro - // otherwise assignTypeToTree in Namers might fail if macroDdef.tpt == EmptyTree - macroDdef setType ErrorType - throw MacroBodyTypecheckException - } - - private def genericError(tree: Tree, message: String) = { - issueNormalTypeError(tree, message) - fail() - } - - private def implRefError(message: String) = { - val treeInfo.Applied(implRef, _, _) = macroDdef.rhs - genericError(implRef, message) - } - - private def compatibilityError(message: String) = - implRefError( - "macro implementation has wrong shape:"+ - "\n required: " + showMeth(rparamss, rret, abbreviate = true) + - "\n found : " + showMeth(aparamss, aret, abbreviate = false) + - "\n" + message) - - // Phase I: sanity checks - - def MacroDefIsFastTrack() = { - macroLogVerbose("typecheck terminated unexpectedly: macro is fast track") - assert(!macroDdef.tpt.isEmpty, "fast track macros must provide result type") - throw MacroBodyTypecheckException // don't call fail, because we don't need IS_ERROR - } - - def MacroDefIsQmarkQmarkQmark() = { - macroLogVerbose("typecheck terminated unexpectedly: macro is ???") - throw MacroBodyTypecheckException - } - - def MacroFeatureNotEnabled() = { - macroLogVerbose("typecheck terminated unexpectedly: language.experimental.macros feature is not enabled") - fail() - } - - // Phase II: typecheck the right-hand side of the macro def - - // do nothing, just fail. relevant typecheck errors have already been reported - def MacroDefUntypeableBodyError() = fail() - - def MacroDefInvalidBodyError() = genericError(macroDdef, "macro body has wrong shape:\n required: macro [].[[]]") - - def MacroImplNotPublicError() = implRefError("macro implementation must be public") - - def MacroImplOverloadedError() = implRefError("macro implementation cannot be overloaded") - - def MacroImplWrongNumberOfTypeArgumentsError(macroImplRef: Tree) = implRefError(typer.TyperErrorGen.TypedApplyWrongNumberOfTpeParametersErrorMessage(macroImplRef)) - - def MacroImplNotStaticError() = implRefError("macro implementation must be in statically accessible object") - - // Phase III: check compatibility between the macro def and its macro impl - // aXXX (e.g. aparams) => characteristics of the macro impl ("a" stands for "actual") - // rXXX (e.g. rparams) => characteristics of a reference macro impl signature synthesized from the macro def ("r" stands for "reference") - - def MacroImplNonTagImplicitParameters(params: List[Symbol]) = compatibilityError("macro implementations cannot have implicit parameters other than WeakTypeTag evidences") - - def MacroImplParamssMismatchError() = compatibilityError("number of parameter sections differ") - - def MacroImplExtraParamsError(aparams: List[Symbol], rparams: List[Symbol]) = compatibilityError(lengthMsg("value", "found", aparams(rparams.length))) - - def MacroImplMissingParamsError(aparams: List[Symbol], rparams: List[Symbol]) = compatibilityError(abbreviateCoreAliases(lengthMsg("value", "required", rparams(aparams.length)))) - - def checkMacroImplParamTypeMismatch(atpe: Type, rparam: Symbol) = checkConforms("parameter " + rparam.name, rparam.tpe, atpe) - - def checkMacroImplResultTypeMismatch(atpe: Type, rret: Type) = checkConforms("return type", atpe, rret) - - def MacroImplParamNameMismatchError(aparam: Symbol, rparam: Symbol) = compatibilityError("parameter names differ: " + rparam.name + " != " + aparam.name) - - def MacroImplVarargMismatchError(aparam: Symbol, rparam: Symbol) = { - if (isRepeated(rparam) && !isRepeated(aparam)) - compatibilityError("types incompatible for parameter " + rparam.name + ": corresponding is not a vararg parameter") - if (!isRepeated(rparam) && isRepeated(aparam)) - compatibilityError("types incompatible for parameter " + aparam.name + ": corresponding is not a vararg parameter") - } - - def MacroImplTargMismatchError(atargs: List[Type], atparams: List[Symbol]) = - compatibilityError(typer.infer.InferErrorGen.NotWithinBoundsErrorMessage("", atargs, atparams, macroDebugVerbose || settings.explaintypes)) - - def MacroImplTparamInstantiationError(atparams: List[Symbol], ex: NoInstance) = - compatibilityError( - "type parameters "+(atparams map (_.defString) mkString ", ")+" cannot be instantiated\n"+ - ex.getMessage) - } } diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala index 93f73f1bbe..40f284c94c 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala @@ -11,6 +11,8 @@ import scala.reflect.internal.util.Statistics import scala.reflect.macros.util._ import scala.util.control.ControlThrowable import scala.reflect.macros.runtime.AbortMacroException +import scala.reflect.runtime.{universe => ru} +import scala.reflect.macros.compiler.DefaultMacroCompiler /** * Code to deal with macros, namely with: @@ -37,7 +39,7 @@ import scala.reflect.macros.runtime.AbortMacroException * (Expr(elems)) * (TypeTag(Int)) */ -trait Macros extends scala.tools.reflect.FastTrack with Traces { +trait Macros extends scala.tools.reflect.FastTrack with Traces with Helpers { self: Analyzer => import global._ @@ -76,6 +78,8 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces { * and various accounting information necessary when composing an argument list for the reflective invocation. */ private case class MacroImplBinding( + // Is this macro impl a bundle (a trait extending Macro) or a vanilla def? + val isBundle: Boolean, // Java class name of the class that contains the macro implementation // is used to load the corresponding object with Java reflection className: String, @@ -110,19 +114,21 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces { * * @scala.reflect.macros.internal.macroImpl( * `macro`( + * "isBundle" = false, * "signature" = List(-1), * "methodName" = "impl", * "versionFormat" = , * "className" = "Macros$")) */ private object MacroImplBinding { - val versionFormat = 2 + val versionFormat = 3 def pickleAtom(obj: Any): Tree = obj match { case list: List[_] => Apply(Ident(ListModule), list map pickleAtom) case s: String => Literal(Constant(s)) case i: Int => Literal(Constant(i)) + case b: Boolean => Literal(Constant(b)) } def unpickleAtom(tree: Tree): Any = @@ -130,11 +136,11 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces { case Apply(list @ Ident(_), args) if list.symbol == ListModule => args map unpickleAtom case Literal(Constant(s: String)) => s case Literal(Constant(i: Int)) => i + case Literal(Constant(b: Boolean)) => b } def pickle(macroImplRef: Tree): Tree = { - val MacroImplReference(owner, macroImpl, targs) = macroImplRef - val paramss = macroImpl.paramss + val MacroImplReference(isBundle, owner, macroImpl, targs) = macroImplRef // todo. refactor when fixing SI-5498 def className: String = { @@ -157,12 +163,13 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces { case _ => IMPLPARAM_OTHER } - val transformed = transformTypeTagEvidenceParams(paramss, (param, tparam) => tparam) + val transformed = transformTypeTagEvidenceParams(macroImplRef, (param, tparam) => tparam) mmap(transformed)(p => if (p.isTerm) fingerprint(p.info) else p.paramPos) } val payload = List[(String, Any)]( "versionFormat" -> versionFormat, + "isBundle" -> isBundle, "className" -> className, "methodName" -> macroImpl.name.toString, "signature" -> signature @@ -205,10 +212,11 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces { val pickleVersionFormat = payload("versionFormat").asInstanceOf[Int] if (versionFormat != pickleVersionFormat) throw new Error(s"macro impl binding format mismatch: expected $versionFormat, actual $pickleVersionFormat") + val isBundle = payload("isBundle").asInstanceOf[Boolean] val className = payload("className").asInstanceOf[String] val methodName = payload("methodName").asInstanceOf[String] val signature = payload("signature").asInstanceOf[List[List[Int]]] - MacroImplBinding(className, methodName, signature, targs) + MacroImplBinding(isBundle, className, methodName, signature, targs) } } @@ -222,330 +230,82 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces { MacroImplBinding.unpickle(pickle) } - /** Transforms parameters lists of a macro impl. - * The `transform` function is invoked only for WeakTypeTag evidence parameters. - * - * The transformer takes two arguments: a value parameter from the parameter list - * and a type parameter that is witnesses by the value parameter. - * - * If the transformer returns a NoSymbol, the value parameter is not included from the result. - * If the transformer returns something else, this something else is included in the result instead of the value parameter. - * - * Despite of being highly esoteric, this function significantly simplifies signature analysis. - * For example, it can be used to strip macroImpl.paramss from the evidences (necessary when checking def <-> impl correspondence) - * or to streamline creation of the list of macro arguments. - */ - private def transformTypeTagEvidenceParams(paramss: List[List[Symbol]], transform: (Symbol, Symbol) => Symbol): List[List[Symbol]] = { - if (paramss.isEmpty || paramss.last.isEmpty) return paramss // no implicit parameters in the signature => nothing to do - if (paramss.head.isEmpty || !(paramss.head.head.tpe <:< MacroContextClass.tpe)) return paramss // no context parameter in the signature => nothing to do - def transformTag(param: Symbol): Symbol = param.tpe.dealias match { - case TypeRef(SingleType(SingleType(NoPrefix, c), universe), WeakTypeTagClass, targ :: Nil) - if c == paramss.head.head && universe == MacroContextUniverse => - transform(param, targ.typeSymbol) - case _ => - param - } - val transformed = paramss.last map transformTag filter (_ ne NoSymbol) - if (transformed.isEmpty) paramss.init else paramss.init :+ transformed - } - - private def dealiasAndRewrap(tp: Type)(fn: Type => Type): Type = { - if (isRepeatedParamType(tp)) scalaRepeatedType(fn(tp.typeArgs.head.dealias)) - else fn(tp.dealias) - } - - /** Increases metalevel of the type, i.e. transforms: - * * T to c.Expr[T] - * - * @see Metalevels.scala for more information and examples about metalevels - */ - private def increaseMetalevel(c: Symbol, tp: Type): Type = dealiasAndRewrap(tp) { - case tp => typeRef(SingleType(NoPrefix, c), MacroContextExprClass, List(tp)) - } - - /** Decreases metalevel of the type, i.e. transforms: - * * c.Expr[T] to T - * - * @see Metalevels.scala for more information and examples about metalevels - */ - private def decreaseMetalevel(tp: Type): Type = dealiasAndRewrap(tp) { - case ExprClassOf(runtimeType) => runtimeType - case _ => AnyClass.tpe // so that macro impls with rhs = ??? don't screw up our inference - } - - def computeMacroDefTypeFromMacroImpl(macroDdef: DefDef, macroImplSig: MacroImplSig): Type = { - // Step I. Transform c.Expr[T] to T and c.Tree to - var runtimeType = decreaseMetalevel(macroImplSig.ret) - - // Step II. Transform type parameters of a macro implementation into type arguments in a macro definition's body - runtimeType = runtimeType.substituteTypes(macroImplSig.tparams, loadMacroImplBinding(macroDdef.symbol).targs.map(_.tpe)) - - // Step III. Transform c.prefix.value.XXX to this.XXX and implParam.value.YYY to defParam.YYY - def unsigma(tpe: Type): Type = - transformTypeTagEvidenceParams(macroImplSig.paramss, (param, tparam) => NoSymbol) match { - case (implCtxParam :: Nil) :: implParamss => - val implToDef = flatMap2(implParamss, macroDdef.vparamss)(map2(_, _)((_, _))).toMap - object UnsigmaTypeMap extends TypeMap { - def apply(tp: Type): Type = tp match { - case TypeRef(pre, sym, args) => - val pre1 = pre match { - case SingleType(SingleType(SingleType(NoPrefix, c), prefix), value) if c == implCtxParam && prefix == MacroContextPrefix && value == ExprValue => - ThisType(macroDdef.symbol.owner) - case SingleType(SingleType(NoPrefix, implParam), value) if value == ExprValue => - implToDef get implParam map (defParam => SingleType(NoPrefix, defParam.symbol)) getOrElse pre + def computeMacroDefTypeFromMacroImplRef(macroDdef: DefDef, macroImplRef: Tree): Type = { + macroImplRef match { + case MacroImplReference(_, _, macroImpl, targs) => + // Step I. Transform c.Expr[T] to T and everything else to Any + var runtimeType = decreaseMetalevel(macroImpl.info.finalResultType) + + // Step II. Transform type parameters of a macro implementation into type arguments in a macro definition's body + runtimeType = runtimeType.substituteTypes(macroImpl.typeParams, targs map (_.tpe)) + + // Step III. Transform c.prefix.value.XXX to this.XXX and implParam.value.YYY to defParam.YYY + def unsigma(tpe: Type): Type = + transformTypeTagEvidenceParams(macroImplRef, (param, tparam) => NoSymbol) match { + case (implCtxParam :: Nil) :: implParamss => + val implToDef = flatMap2(implParamss, macroDdef.vparamss)(map2(_, _)((_, _))).toMap + object UnsigmaTypeMap extends TypeMap { + def apply(tp: Type): Type = tp match { + case TypeRef(pre, sym, args) => + val pre1 = pre match { + case SingleType(SingleType(SingleType(NoPrefix, c), prefix), value) if c == implCtxParam && prefix == MacroContextPrefix && value == ExprValue => + ThisType(macroDdef.symbol.owner) + case SingleType(SingleType(NoPrefix, implParam), value) if value == ExprValue => + implToDef get implParam map (defParam => SingleType(NoPrefix, defParam.symbol)) getOrElse pre + case _ => + pre + } + val args1 = args map mapOver + TypeRef(pre1, sym, args1) case _ => - pre + mapOver(tp) } - val args1 = args map mapOver - TypeRef(pre1, sym, args1) - case _ => - mapOver(tp) - } - } - - UnsigmaTypeMap(tpe) - case _ => - tpe - } - - unsigma(runtimeType) - } - - /** Signature of a macro implementation, used to check def <-> impl correspondence. - * - * Technically it can be just an alias to MethodType, but promoting it to a first-class entity - * provides better encapsulation and convenient syntax for pattern matching. - */ - case class MacroImplSig(tparams: List[Symbol], paramss: List[List[Symbol]], ret: Type) + } - /** An actual macro implementation signature extracted from a macro implementation method. - * - * In the example above for the following macro impl: - * def fooBar[T: c.WeakTypeTag] - * (c: scala.reflect.macros.Context) - * (xs: c.Expr[List[T]]) - * : c.Expr[T] = ... - * - * This function will return: - * (c: scala.reflect.macros.Context)(xs: c.Expr[List[T]])c.Expr[T] - * - * Note that type tag evidence parameters are not included into the result. - * Type tag context bounds for macro impl tparams are optional. - * Therefore compatibility checks ignore such parameters, and we don't need to bother about them here. - * - * This method cannot be reduced to just macroImpl.info, because macro implementations might - * come in different shapes. If the implementation is an apply method of a Macro-compatible object, - * then it won't have (c: Context) in its parameters, but will rather refer to Macro.c. - * - * @param macroImpl The macro implementation symbol - */ - def macroImplSig(macroImpl: Symbol): MacroImplSig = { - val tparams = macroImpl.typeParams - val paramss = transformTypeTagEvidenceParams(macroImpl.paramss, (param, tparam) => NoSymbol) - val ret = macroImpl.info.finalResultType - MacroImplSig(tparams, paramss, ret) - } + UnsigmaTypeMap(tpe) + case _ => + tpe + } - /** A reference macro implementation signature extracted from a given macro definition. - * - * In the example above for the following macro def: - * def foo[T](xs: List[T]): T = macro fooBar - * - * This function will return: - * (c: scala.reflect.macros.Context)(xs: c.Expr[List[T]])c.Expr[T] - * - * Note that type tag evidence parameters are not included into the result. - * Type tag context bounds for macro impl tparams are optional. - * Therefore compatibility checks ignore such parameters, and we don't need to bother about them here. - * - * Also note that we need a DefDef, not the corresponding MethodSymbol, because that symbol would be of no use for us. - * Macro signatures are verified when typechecking macro defs, which means that at that moment inspecting macroDef.info - * means asking for cyclic reference errors. - * - * We need macro implementation symbol as well, because the return type of the macro definition might be omitted, - * and in that case we'd need to infer it from the return type of the macro implementation. Luckily for us, we can - * use that symbol without a risk of running into cycles. - * - * @param typer Typechecker of `macroDdef` - * @param macroDdef The macro definition tree - * @param macroImpl The macro implementation symbol - */ - def referenceMacroImplSig(typer: Typer, macroDdef: DefDef, macroImpl: Symbol): MacroImplSig = { - // had to move method's body to an object because of the recursive dependencies between sigma and param - object SigGenerator { - val cache = scala.collection.mutable.Map[Symbol, Symbol]() - val macroDef = macroDdef.symbol - val ctxParam = makeParam(nme.macroContext, macroDdef.pos, MacroContextClass.tpe, SYNTHETIC) - val paramss = List(ctxParam) :: mmap(macroDdef.vparamss)(param) - val macroDefRet = - if (!macroDdef.tpt.isEmpty) typer.typedType(macroDdef.tpt).tpe - else computeMacroDefTypeFromMacroImpl(macroDdef, macroImplSig(macroImpl)) - val implReturnType = sigma(increaseMetalevel(ctxParam, macroDefRet)) - - object SigmaTypeMap extends TypeMap { - def mapPrefix(pre: Type) = pre match { - case ThisType(sym) if sym == macroDef.owner => - singleType(singleType(singleType(NoPrefix, ctxParam), MacroContextPrefix), ExprValue) - case SingleType(NoPrefix, sym) => - mfind(macroDdef.vparamss)(_.symbol == sym).fold(pre)(p => singleType(singleType(NoPrefix, param(p)), ExprValue)) - case _ => - mapOver(pre) - } - def apply(tp: Type): Type = tp match { - case TypeRef(pre, sym, args) => - val pre1 = mapPrefix(pre) - val args1 = mapOverArgs(args, sym.typeParams) - if ((pre eq pre1) && (args eq args1)) tp - else typeRef(pre1, sym, args1) - case _ => - mapOver(tp) - } - } - def sigma(tpe: Type): Type = SigmaTypeMap(tpe) - - def makeParam(name: Name, pos: Position, tpe: Type, flags: Long) = - macroDef.newValueParameter(name.toTermName, pos, flags) setInfo tpe - def param(tree: Tree): Symbol = ( - cache.getOrElseUpdate(tree.symbol, { - val sym = tree.symbol - assert(sym.isTerm, s"sym = $sym, tree = $tree") - makeParam(sym.name, sym.pos, sigma(increaseMetalevel(ctxParam, sym.tpe)), sym.flags) - }) - ) + unsigma(runtimeType) + case _ => + ErrorType } - - import SigGenerator._ - val result = MacroImplSig(macroDdef.tparams map (_.symbol), paramss, implReturnType) - macroLogVerbose(sm""" - |generating macroImplSig for: $macroDdef - |result is: $result - """.trim) - result } - /** Verifies that the body of a macro def typechecks to a reference to a static public non-overloaded method, + /** Verifies that the body of a macro def typechecks to a reference to a static public non-overloaded method or a top-level macro bundle, * and that that method is signature-wise compatible with the given macro definition. * - * @return Typechecked rhs of the given macro definition if everything is okay. + * @return Macro impl reference for the given macro definition if everything is okay. * EmptyTree if an error occurs. */ - def typedMacroBody(typer: Typer, macroDdef: DefDef): Tree = - try new MacroTyper(typer, macroDdef).typed - catch { case MacroBodyTypecheckException => EmptyTree } - - class MacroTyper(val typer: Typer, val macroDdef: DefDef) extends MacroErrors { - private def typed1Expr(tree: Tree) = typer.typed1(tree, EXPRmode, WildcardType) - - // Phase I: sanity checks + def typedMacroBody(typer: Typer, macroDdef: DefDef): Tree = { val macroDef = macroDdef.symbol - macroLogVerbose("typechecking macro def %s at %s".format(macroDef, macroDdef.pos)) assert(macroDef.isMacro, macroDdef) - if (fastTrack contains macroDef) MacroDefIsFastTrack() - if (!typer.checkFeature(macroDdef.pos, MacrosFeature, immediate = true)) MacroFeatureNotEnabled() - - // we use typed1 instead of typed, because otherwise adapt is going to mess us up - // if adapt sees ., it will want to perform eta-expansion and will fail - // unfortunately, this means that we have to manually trigger macro expansion - // because it's adapt which is responsible for automatic expansion during typechecking - def typecheckRhs(rhs: Tree): Tree = { - try { - // interestingly enough, just checking isErroneous doesn't cut it - // e.g. a "type arguments [U] do not conform to method foo's type parameter bounds" error - // doesn't manifest itself as an error in the resulting tree - val prevNumErrors = reporter.ERROR.count - var rhs1 = typed1Expr(rhs) - def rhsNeedsMacroExpansion = rhs1.symbol != null && rhs1.symbol.isTermMacro && !rhs1.symbol.isErroneous - while (rhsNeedsMacroExpansion) { - rhs1 = macroExpand1(typer, rhs1) match { - case Success(expanded) => - try { - val typechecked = typed1Expr(expanded) - macroLogVerbose("typechecked1:%n%s%n%s".format(typechecked, showRaw(typechecked))) - typechecked - } finally { - popMacroContext() - } - case Fallback(fallback) => - typed1Expr(fallback) - case Delayed(delayed) => - typer.instantiate(delayed, EXPRmode, WildcardType) - case Skipped(skipped) => - skipped - case Failure(failure) => - failure - } - } - val typecheckedWithErrors = (rhs1 exists (_.isErroneous)) || reporter.ERROR.count != prevNumErrors - if (typecheckedWithErrors) MacroDefUntypeableBodyError() - rhs1 - } catch { - case ex: TypeError => - typer.reportTypeError(context, rhs.pos, ex) - MacroDefUntypeableBodyError() - } - } - // Phase II: typecheck the right-hand side of the macro def - val typed = typecheckRhs(macroDdef.rhs) - typed match { - case MacroImplReference(_, meth, _) if meth == Predef_??? => - bindMacroImpl(macroDef, typed) - MacroDefIsQmarkQmarkQmark() - case MacroImplReference(owner, meth, targs) => - if (!meth.isMethod) MacroDefInvalidBodyError() - if (!meth.isPublic) MacroImplNotPublicError() - if (meth.isOverloaded) MacroImplOverloadedError() - if (!owner.isStaticOwner && !owner.moduleClass.isStaticOwner) MacroImplNotStaticError() - if (meth.typeParams.length != targs.length) MacroImplWrongNumberOfTypeArgumentsError(typed) - bindMacroImpl(macroDef, typed) - case _ => - MacroDefInvalidBodyError() - } - - // Phase III: check compatibility between the macro def and its macro impl - // this check ignores type tag evidence parameters, because type tag context bounds are optional - // aXXX (e.g. aparamss) => characteristics of the actual macro impl signature extracted from the macro impl ("a" stands for "actual") - // rXXX (e.g. rparamss) => characteristics of the reference macro impl signature synthesized from the macro def ("r" stands for "reference") - val macroImpl = typed.symbol - val MacroImplSig(atparams, aparamss, aret) = macroImplSig(macroImpl) - val MacroImplSig(_, rparamss, rret) = referenceMacroImplSig(typer, macroDdef, macroImpl) - val atvars = atparams map freshVar - def atpeToRtpe(atpe: Type) = atpe.substSym(aparamss.flatten, rparamss.flatten).instantiateTypeParams(atparams, atvars) - - // we only check correspondence between value parameterss - // type parameters of macro defs and macro impls don't have to coincide with each other - val implicitParams = aparamss.flatten filter (_.isImplicit) - if (implicitParams.nonEmpty) MacroImplNonTagImplicitParameters(implicitParams) - if (aparamss.length != rparamss.length) MacroImplParamssMismatchError() - map2(aparamss, rparamss)((aparams, rparams) => { - if (aparams.length < rparams.length) MacroImplMissingParamsError(aparams, rparams) - if (rparams.length < aparams.length) MacroImplExtraParamsError(aparams, rparams) - }) - - try { - // cannot fuse this map2 and the map2 above because if aparamss.flatten != rparamss.flatten - // then `atpeToRtpe` is going to fail with an unsound substitution - map2(aparamss.flatten, rparamss.flatten)((aparam, rparam) => { - if (aparam.name != rparam.name && !rparam.isSynthetic) MacroImplParamNameMismatchError(aparam, rparam) - if (isRepeated(aparam) ^ isRepeated(rparam)) MacroImplVarargMismatchError(aparam, rparam) - val aparamtpe = aparam.tpe.dealias match { - case RefinedType(List(tpe), Scope(sym)) if tpe =:= MacroContextClass.tpe && sym.allOverriddenSymbols.contains(MacroContextPrefixType) => tpe - case tpe => tpe - } - checkMacroImplParamTypeMismatch(atpeToRtpe(aparamtpe), rparam) - }) - - checkMacroImplResultTypeMismatch(atpeToRtpe(aret), rret) - - val maxLubDepth = lubDepth(aparamss.flatten map (_.tpe)) max lubDepth(rparamss.flatten map (_.tpe)) - val atargs = solvedTypes(atvars, atparams, atparams map varianceInType(aret), upper = false, depth = maxLubDepth) - val boundsOk = typer.silent(_.infer.checkBounds(macroDdef, NoPrefix, NoSymbol, atparams, atargs, "")) - boundsOk match { - case SilentResultValue(true) => // do nothing, success - case SilentResultValue(false) | SilentTypeError(_) => MacroImplTargMismatchError(atargs, atparams) + macroLogVerbose("typechecking macro def %s at %s".format(macroDef, macroDdef.pos)) + if (fastTrack contains macroDef) { + macroLogVerbose("typecheck terminated unexpectedly: macro is fast track") + assert(!macroDdef.tpt.isEmpty, "fast track macros must provide result type") + EmptyTree + } else { + def fail() = { if (macroDef != null) macroDef setFlag IS_ERROR; macroDdef setType ErrorType; EmptyTree } + def success(macroImplRef: Tree) = { bindMacroImpl(macroDef, macroImplRef); macroImplRef } + + if (!typer.checkFeature(macroDdef.pos, MacrosFeature, immediate = true)) { + macroLogVerbose("typecheck terminated unexpectedly: language.experimental.macros feature is not enabled") + fail() + } else { + val macroDdef1: macroDdef.type = macroDdef + val typer1: typer.type = typer + val macroCompiler = new { + val global: self.global.type = self.global + val typer: self.global.analyzer.Typer = typer1.asInstanceOf[self.global.analyzer.Typer] + val macroDdef: self.global.DefDef = macroDdef1 + } with DefaultMacroCompiler + val macroImplRef = macroCompiler.resolveMacroImpl + if (macroImplRef.isEmpty) fail() else success(macroImplRef) } - } catch { - case ex: NoInstance => MacroImplTparamInstantiationError(atparams, ex) } } @@ -555,6 +315,10 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces { */ lazy val macroClassloader: ClassLoader = findMacroClassLoader() + /** Reflective mirror built from `macroClassloader`. + */ + private lazy val macroMirror: ru.JavaMirror = ru.runtimeMirror(macroClassloader) + /** Produces a function that can be used to invoke macro implementation for a given macro definition: * 1) Looks up macro implementation symbol in this universe. * 2) Loads its enclosing class from the macro classloader. @@ -574,28 +338,32 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces { } else { macroRuntimesCache.getOrElseUpdate(macroDef, { val binding = loadMacroImplBinding(macroDef) + val isBundle = binding.isBundle val className = binding.className val methName = binding.methName macroLogVerbose(s"resolved implementation as $className.$methName") - if (binding.className == Predef_???.owner.fullName.toString && binding.methName == Predef_???.name.encoded) { + if (binding.className == Predef_???.owner.javaClassName && binding.methName == Predef_???.name.encoded) { args => throw new AbortMacroException(args.c.enclosingPosition, "macro implementation is missing") } else { - // I don't use Scala reflection here, because it seems to interfere with JIT magic - // whenever you instantiate a mirror (and not do anything with in, just instantiate), performance drops by 15-20% - // I'm not sure what's the reason - for me it's pure voodoo - // upd. my latest experiments show that everything's okay - // it seems that in 2.10.1 we can easily switch to Scala reflection try { macroLogVerbose(s"loading implementation class: $className") macroLogVerbose(s"classloader is: ${ReflectionUtils.show(macroClassloader)}") - val implObj = ReflectionUtils.staticSingletonInstance(macroClassloader, className) - // relies on the fact that macro impls cannot be overloaded - // so every methName can resolve to at maximum one method - val implMeths = implObj.getClass.getDeclaredMethods.find(_.getName == methName) - val implMeth = implMeths getOrElse { throw new NoSuchMethodException(s"$className.$methName") } - macroLogVerbose(s"successfully loaded macro impl as ($implObj, $implMeth)") - args => implMeth.invoke(implObj, ((args.c +: args.others) map (_.asInstanceOf[AnyRef])): _*) + val implContainerSym = macroMirror.classSymbol(Class.forName(className, true, macroClassloader)) + val implMethSym = implContainerSym.typeSignature.member(ru.TermName(methName)).asMethod + macroLogVerbose(s"successfully loaded macro impl as ($implContainerSym, $implMethSym)") + args => { + val implContainer = + if (isBundle) { + val implCtorSym = implContainerSym.typeSignature.member(ru.nme.CONSTRUCTOR).asMethod + macroMirror.reflectClass(implContainerSym).reflectConstructor(implCtorSym)(args.c) + } else { + macroMirror.reflectModule(implContainerSym.module.asModule).instance + } + val implMeth = macroMirror.reflect(implContainer).reflectMethod(implMethSym) + val implArgs = if (isBundle) args.others else args.c +: args.others + implMeth(implArgs: _*) + } } catch { case ex: Exception => macroLogVerbose(s"macro runtime failed to load: ${ex.toString}") @@ -640,31 +408,32 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces { import typer.TyperErrorGen._ val isNullaryArgsEmptyParams = argss.isEmpty && paramss == ListOfNil - if (paramss.length < argss.length) MacroTooManyArgumentLists(expandee) - if (paramss.length > argss.length && !isNullaryArgsEmptyParams) MacroTooFewArgumentLists(expandee) + if (paramss.length < argss.length) MacroTooManyArgumentListsError(expandee) + if (paramss.length > argss.length && !isNullaryArgsEmptyParams) MacroTooFewArgumentListsError(expandee) val macroImplArgs: List[Any] = if (fastTrack contains macroDef) { // Take a dry run of the fast track implementation if (fastTrack(macroDef) validate expandee) argss.flatten - else typer.TyperErrorGen.MacroTooFewArgumentLists(expandee) + else MacroTooFewArgumentListsError(expandee) } else { val binding = loadMacroImplBinding(macroDef) - if (binding.className == Predef_???.owner.fullName.toString && binding.methName == Predef_???.name.encoded) Nil + if (binding.className == Predef_???.owner.javaClassName && binding.methName == Predef_???.name.encoded) Nil else { + val signature = if (binding.isBundle) binding.signature else binding.signature.tail macroLogVerbose(s"binding: $binding") // STEP I: prepare value arguments of the macro expansion // wrap argss in c.Expr if necessary (i.e. if corresponding macro impl param is of type c.Expr[T]) // expand varargs (nb! varargs can apply to any parameter section, not necessarily to the last one) - val trees = map3(argss, paramss, binding.signature.tail)((args, defParams, implParams) => { + val trees = map3(argss, paramss, signature)((args, defParams, implParams) => { val isVarargs = isVarArgsList(defParams) if (isVarargs) { - if (defParams.length > args.length + 1) MacroTooFewArguments(expandee) + if (defParams.length > args.length + 1) MacroTooFewArgumentsError(expandee) } else { - if (defParams.length < args.length) MacroTooManyArguments(expandee) - if (defParams.length > args.length) MacroTooFewArguments(expandee) + if (defParams.length < args.length) MacroTooManyArgumentsError(expandee) + if (defParams.length > args.length) MacroTooFewArgumentsError(expandee) } val wrappedArgs = mapWithIndex(args)((arg, j) => { @@ -700,7 +469,7 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces { // then T and U need to be inferred from the lexical scope of the call using `asSeenFrom` // whereas V won't be resolved by asSeenFrom and need to be loaded directly from `expandee` which needs to contain a TypeApply node // also, macro implementation reference may contain a regular type as a type argument, then we pass it verbatim - val tags = binding.signature.flatten filter (_ >= IMPLPARAM_TAG) map (paramPos => { + val tags = signature.flatten filter (_ >= IMPLPARAM_TAG) map (paramPos => { val targ = binding.targs(paramPos).tpe.typeSymbol val tpe = if (targ.isTypeParameterOrSkolem) { if (targ.owner == macroDef) { diff --git a/src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala b/src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala index 64fcda3b80..a208924acb 100644 --- a/src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala +++ b/src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala @@ -127,4 +127,31 @@ trait StdAttachments { /** Determines whether the given tree has an associated SuperArgsAttachment. */ def hasSuperArgs(tree: Tree): Boolean = superArgs(tree).nonEmpty + + /** @see markMacroImplRef + */ + case object MacroImplRefAttachment + + /** Marks the tree as a macro impl reference, which is a naked reference to a method. + * + * This is necessary for typechecking macro impl references (see `DefaultMacroCompiler.defaultResolveMacroImpl`), + * because otherwise typing a naked reference will result in the "follow this method with `_' if you want to + * treat it as a partially applied function" errors. + * + * This mark suppresses adapt except for when the annottee is a macro application. + */ + def markMacroImplRef(tree: Tree): Tree = tree.updateAttachment(MacroImplRefAttachment) + + /** Unmarks the tree as a macro impl reference (see `markMacroImplRef` for more information). + * + * This is necessary when a tree that was previously deemed to be a macro impl reference, + * typechecks to be a macro application. Then we need to unmark it, expand it and try to treat + * its expansion as a macro impl reference. + */ + def unmarkMacroImplRef(tree: Tree): Tree = tree.removeAttachment[MacroImplRefAttachment.type] + + /** Determines whether a tree should or should not be adapted, + * because someone has put MacroImplRefAttachment on it. + */ + def isMacroImplRef(tree: Tree): Boolean = tree.attachments.get[MacroImplRefAttachment.type].isDefined } \ No newline at end of file diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 5916116ef3..c9aa27cf49 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -1234,7 +1234,10 @@ trait Typers extends Adaptations with Tags { } // begin adapt - tree.tpe match { + if (isMacroImplRef(tree)) { + if (treeInfo.isMacroApplication(tree)) adapt(unmarkMacroImplRef(tree), mode, pt, original) + else tree + } else tree.tpe match { case atp @ AnnotatedType(_, _, _) if canAdaptAnnotations(tree, this, mode, pt) => // (-1) adaptAnnotations(tree, this, mode, pt) case ct @ ConstantType(value) if mode.inNone(TYPEmode | FUNmode) && (ct <:< pt) && canAdaptConstantTypeToLiteral => // (0) @@ -5534,7 +5537,7 @@ trait Typers extends Adaptations with Tags { val isMacroBodyOkay = !tree.symbol.isErroneous && !(tree1 exists (_.isErroneous)) && tree1 != EmptyTree val shouldInheritMacroImplReturnType = ddef.tpt.isEmpty - if (isMacroBodyOkay && shouldInheritMacroImplReturnType) computeMacroDefTypeFromMacroImpl(ddef, macroImplSig(tree1.symbol)) else AnyTpe + if (isMacroBodyOkay && shouldInheritMacroImplReturnType) computeMacroDefTypeFromMacroImplRef(ddef, tree1) else AnyTpe } def transformedOr(tree: Tree, op: => Tree): Tree = transformed remove tree match { diff --git a/src/compiler/scala/tools/reflect/FastTrack.scala b/src/compiler/scala/tools/reflect/FastTrack.scala index 3cf19396ee..5a0ff4f6db 100644 --- a/src/compiler/scala/tools/reflect/FastTrack.scala +++ b/src/compiler/scala/tools/reflect/FastTrack.scala @@ -5,6 +5,7 @@ import scala.reflect.reify.Taggers import scala.tools.nsc.typechecker.{ Analyzer, Macros } import scala.reflect.runtime.Macros.currentMirror import scala.reflect.api.Universe +import scala.reflect.macros.compiler.DefaultMacroCompiler /** Optimizes system macro expansions by hardwiring them directly to their implementations * bypassing standard reflective load and invoke to avoid the overhead of Java/Scala reflection. diff --git a/src/reflect/scala/reflect/api/Trees.scala b/src/reflect/scala/reflect/api/Trees.scala index f4ada814af..f7a6a68946 100644 --- a/src/reflect/scala/reflect/api/Trees.scala +++ b/src/reflect/scala/reflect/api/Trees.scala @@ -296,6 +296,20 @@ trait Trees { self: Universe => def name: Name } + /** The constructor/extractor for `RefTree` instances. + * @group Extractors + */ + val RefTree: RefTreeExtractor + + /** An extractor class to create and pattern match with syntax `RefTree(qual, name)`. + * This AST node corresponds to either Ident, Select or SelectFromTypeTree. + * @group Extractors + */ + abstract class RefTreeExtractor { + def apply(qualifier: Tree, name: Name): RefTree + def unapply(refTree: RefTree): Option[(Tree, Name)] + } + /** A tree which defines a symbol-carrying entity. * @group Trees * @template diff --git a/src/reflect/scala/reflect/internal/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala index 630572464d..5478c54eec 100644 --- a/src/reflect/scala/reflect/internal/Definitions.scala +++ b/src/reflect/scala/reflect/internal/Definitions.scala @@ -501,6 +501,13 @@ trait Definitions extends api.StandardDefinitions { lazy val OptManifestClass = requiredClass[scala.reflect.OptManifest[_]] lazy val NoManifest = requiredModule[scala.reflect.NoManifest.type] + lazy val TreesClass = getClassIfDefined("scala.reflect.api.Trees") // defined in scala-reflect.jar, so we need to be careful + lazy val TreesTreeType = if (TreesClass != NoSymbol) getTypeMember(TreesClass, tpnme.Tree) else NoSymbol + object TreeType { + def unapply(tpe: Type): Boolean = unapply(tpe.typeSymbol) + def unapply(sym: Symbol): Boolean = sym.overrideChain contains TreesTreeType + } + 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 @@ -533,6 +540,7 @@ trait Definitions extends api.StandardDefinitions { lazy val TypeCreatorClass = getClassIfDefined("scala.reflect.api.TypeCreator") // defined in scala-reflect.jar, so we need to be careful lazy val TreeCreatorClass = getClassIfDefined("scala.reflect.api.TreeCreator") // defined in scala-reflect.jar, so we need to be careful + lazy val MacroClass = getClassIfDefined("scala.reflect.macros.Macro") // defined in scala-reflect.jar, so we need to be careful lazy val MacroContextClass = getClassIfDefined("scala.reflect.macros.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) getTypeMember(MacroContextClass, tpnme.PrefixType) else NoSymbol @@ -650,6 +658,12 @@ trait Definitions extends api.StandardDefinitions { } def isTupleType(tp: Type) = isTupleTypeDirect(tp.dealiasWiden) + def isMacroBundleType(tp: Type) = { + val isNonTrivial = tp != ErrorType && tp != NothingTpe && tp != NullTpe + val isMacroCompatible = MacroClass != NoSymbol && tp <:< MacroClass.tpe + isNonTrivial && isMacroCompatible + } + lazy val ProductRootClass: ClassSymbol = requiredClass[scala.Product] def Product_productArity = getMemberMethod(ProductRootClass, nme.productArity) def Product_productElement = getMemberMethod(ProductRootClass, nme.productElement) diff --git a/src/reflect/scala/reflect/internal/StdNames.scala b/src/reflect/scala/reflect/internal/StdNames.scala index a20307882d..81fffc833c 100644 --- a/src/reflect/scala/reflect/internal/StdNames.scala +++ b/src/reflect/scala/reflect/internal/StdNames.scala @@ -8,6 +8,7 @@ package reflect package internal import java.security.MessageDigest +import java.util.UUID.randomUUID import Chars.isOperatorPart import scala.annotation.switch import scala.language.implicitConversions @@ -290,6 +291,9 @@ trait StdNames { val FAKE_LOCAL_THIS: NameType = "this$" val LAZY_LOCAL: NameType = "$lzy" val LAZY_SLOW_SUFFIX: NameType = "$lzycompute" + val MACRO_INVOKER_PACKAGE: NameType = "scala.reflect.macros.synthetic" + // TODO: if I use dollars in MACRO_INVOKER_SUFFIX, as in "$Invoker$", then Scala reflection fails to load implementations + val MACRO_INVOKER_SUFFIX: NameType = "Invoker" val UNIVERSE_BUILD_PREFIX: NameType = "$u.build." val UNIVERSE_PREFIX: NameType = "$u." val UNIVERSE_SHORT: NameType = "$u" @@ -584,6 +588,7 @@ trait StdNames { val box: NameType = "box" val build : NameType = "build" val bytes: NameType = "bytes" + val c: NameType = "c" val canEqual_ : NameType = "canEqual" val checkInitialized: NameType = "checkInitialized" val classOf: NameType = "classOf" diff --git a/src/reflect/scala/reflect/internal/TreeInfo.scala b/src/reflect/scala/reflect/internal/TreeInfo.scala index e9ef9c7945..d1e8a04553 100644 --- a/src/reflect/scala/reflect/internal/TreeInfo.scala +++ b/src/reflect/scala/reflect/internal/TreeInfo.scala @@ -836,8 +836,17 @@ abstract class TreeInfo { } def unapply(tree: Tree) = refPart(tree) match { - case ref: RefTree => Some((ref.qualifier.symbol, ref.symbol, dissectApplied(tree).targs)) - case _ => None + case ref: RefTree => { + val isBundle = definitions.isMacroBundleType(ref.qualifier.tpe) + val owner = + if (isBundle) ref.qualifier.tpe.typeSymbol + else { + val sym = ref.qualifier.symbol + if (sym.isModule) sym.moduleClass else sym + } + Some((isBundle, owner, ref.symbol, dissectApplied(tree).targs)) + } + case _ => None } } diff --git a/src/reflect/scala/reflect/internal/Trees.scala b/src/reflect/scala/reflect/internal/Trees.scala index de0b4e8247..979ee54b4f 100644 --- a/src/reflect/scala/reflect/internal/Trees.scala +++ b/src/reflect/scala/reflect/internal/Trees.scala @@ -253,6 +253,19 @@ trait Trees extends api.Trees { self: SymbolTable => def name: Name } + object RefTree extends RefTreeExtractor { + def apply(qualifier: Tree, name: Name): RefTree = qualifier match { + case EmptyTree => + Ident(name) + case qual if qual.isTerm => + Select(qual, name) + case qual if qual.isType => + assert(name.isTypeName, s"qual = $qual, name = $name") + SelectFromTypeTree(qual, name.toTypeName) + } + def unapply(refTree: RefTree): Option[(Tree, Name)] = Some((refTree.qualifier, refTree.name)) + } + abstract class DefTree extends SymTree with NameTree with DefTreeApi { def name: Name override def isDef = true diff --git a/src/reflect/scala/reflect/macros/Macro.scala b/src/reflect/scala/reflect/macros/Macro.scala new file mode 100644 index 0000000000..44bedf483d --- /dev/null +++ b/src/reflect/scala/reflect/macros/Macro.scala @@ -0,0 +1,39 @@ +package scala.reflect +package macros + +/** + * EXPERIMENTAL + * + * Traditionally macro implementations are defined as methods, + * but this trait provides an alternative way of encoding macro impls as + * bundles, traits which extend `scala.reflect.macros.Macro`. + * + * Instead of: + * + * def impl[T: c.WeakTypeTag](c: Context)(x: c.Expr[Int]) = ... + * + * One can write: + * + * trait Impl extends Macro { + * def apply[T: c.WeakTypeTag](x: c.Expr[Int]) = ... + * } + * + * Without changing anything else at all. + * + * This language feature is useful in itself in cases when macro implementations + * are complex and need to be modularized. State of the art technique of addressing this need is quite heavyweight: + * http://docs.scala-lang.org/overviews/macros/overview.html#writing_bigger_macros. + * + * However utility of this approach to writing macros isn't limited to just convenience. + * When a macro implementation becomes not just a function, but a full-fledged module, + * it can define callbacks that will be called by the compiler upon interesting events. + * In subsequent commits I will add support for programmable type inference + */ +trait Macro { + /** The context to be used by the macro implementation. + * + * Vanilla macro implementations have to carry it in their signatures, however when a macro is a full-fledged module, + * it can define the context next to the implementation, makes implementation signature more lightweight. + */ + val c: Context +} diff --git a/src/reflect/scala/reflect/runtime/JavaMirrors.scala b/src/reflect/scala/reflect/runtime/JavaMirrors.scala index adee155db0..a3684f602f 100644 --- a/src/reflect/scala/reflect/runtime/JavaMirrors.scala +++ b/src/reflect/scala/reflect/runtime/JavaMirrors.scala @@ -972,8 +972,8 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni javaTypeToValueClass(jclazz) orElse lookupClass assert (cls.isType, - sm"""${if (cls == NoSymbol) "not a type: symbol" else "no symbol could be"} - | loaded from $jclazz in $owner with name $simpleName and classloader $classLoader""") + (if (cls != NoSymbol) s"not a type: symbol $cls" else "no symbol could be") + + s" loaded from $jclazz in $owner with name $simpleName and classloader $classLoader") cls.asClass } diff --git a/test/files/neg/macro-invalidimpl.check b/test/files/neg/macro-invalidimpl.check index 7177a8cdee..aaf4f88fc2 100644 --- a/test/files/neg/macro-invalidimpl.check +++ b/test/files/neg/macro-invalidimpl.check @@ -1,15 +1,23 @@ -Macros_Test_2.scala:5: error: macro implementation must be in statically accessible object +Macros_Test_2.scala:5: error: macro implementation reference has wrong shape. required: +macro [].[[]] or +macro [].[[]] def foo(x: Any) = macro impls.foo - ^ -Macros_Test_2.scala:10: error: macro implementation must be in statically accessible object + ^ +Macros_Test_2.scala:10: error: macro implementation reference has wrong shape. required: +macro [].[[]] or +macro [].[[]] def foo(x: Any) = macro impls.foo - ^ -Macros_Test_2.scala:18: error: macro implementation must be in statically accessible object + ^ +Macros_Test_2.scala:18: error: macro implementation reference has wrong shape. required: +macro [].[[]] or +macro [].[[]] def foo(x: Any) = macro Impls3.foo - ^ -Macros_Test_2.scala:22: error: macro implementation must be in statically accessible object + ^ +Macros_Test_2.scala:22: error: macro implementation reference has wrong shape. required: +macro [].[[]] or +macro [].[[]] def foo(x: Any) = macro Impls4.foo - ^ + ^ Macros_Test_2.scala:26: error: ambiguous reference to overloaded definition, both method foo in object Impls5 of type (c: scala.reflect.macros.Context)(x: c.Expr[Any], y: c.Expr[Any])Nothing and method foo in object Impls5 of type (c: scala.reflect.macros.Context)(x: c.Expr[Any])Nothing @@ -27,17 +35,17 @@ Macros_Test_2.scala:31: error: macro implementation has wrong shape: found : (c: scala.reflect.macros.Context)(): c.Expr[Unit] number of parameter sections differ def foo1 = macro Impls6.fooEmpty - ^ + ^ Macros_Test_2.scala:32: error: macro implementation has wrong shape: required: (c: scala.reflect.macros.Context)(): c.Expr[Unit] found : (c: scala.reflect.macros.Context): c.Expr[Unit] number of parameter sections differ def bar1() = macro Impls6.fooNullary - ^ + ^ Macros_Test_2.scala:36: error: type arguments [String] do not conform to method foo's type parameter bounds [U <: Int] def foo = macro Impls7.foo[String] ^ Macros_Test_2.scala:53: error: macro implementation must be public def foo = macro Impls8.impl - ^ + ^ 10 errors found diff --git a/test/files/neg/macro-invalidret.check b/test/files/neg/macro-invalidret.check index d6664e6882..8c6ed4eb45 100644 --- a/test/files/neg/macro-invalidret.check +++ b/test/files/neg/macro-invalidret.check @@ -3,11 +3,11 @@ Macros_Test_2.scala:2: error: macro implementation has wrong shape: found : (c: scala.reflect.macros.Context): Int type mismatch for return type: Int does not conform to c.Expr[Any] def foo1 = macro Impls.foo1 - ^ + ^ Macros_Test_2.scala:3: error: macro implementation has wrong shape: required: (c: scala.reflect.macros.Context): c.Expr[Any] found : (c: scala.reflect.macros.Context): reflect.runtime.universe.Literal type mismatch for return type: reflect.runtime.universe.Literal does not conform to c.Expr[Any] def foo2 = macro Impls.foo2 - ^ + ^ two errors found diff --git a/test/files/neg/macro-invalidshape.check b/test/files/neg/macro-invalidshape.check index cefc95b763..40a2952569 100644 --- a/test/files/neg/macro-invalidshape.check +++ b/test/files/neg/macro-invalidshape.check @@ -1,17 +1,15 @@ -Macros_Test_2.scala:2: error: macro body has wrong shape: - required: macro [].[[]] +Macros_Test_2.scala:2: error: macro implementation reference has wrong shape. required: +macro [].[[]] or +macro [].[[]] def foo1(x: Any) = macro 2 ^ -Macros_Test_2.scala:3: error: macro body has wrong shape: - required: macro [].[[]] +Macros_Test_2.scala:3: error: macro implementation reference has wrong shape. required: +macro [].[[]] or +macro [].[[]] def foo2(x: Any) = macro Impls.foo(null)(null) ^ -Macros_Test_2.scala:4: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses - def foo3(x: Any) = macro {2; Impls.foo} - ^ Macros_Test_2.scala:4: error: missing arguments for method foo in object Impls; follow this method with `_' if you want to treat it as a partially applied function def foo3(x: Any) = macro {2; Impls.foo} ^ -one warning found three errors found diff --git a/test/files/neg/macro-invalidsig-params-badtype.check b/test/files/neg/macro-invalidsig-params-badtype.check index 3ec40d7e5b..3cc1c9abf1 100644 --- a/test/files/neg/macro-invalidsig-params-badtype.check +++ b/test/files/neg/macro-invalidsig-params-badtype.check @@ -1,7 +1,7 @@ Impls_Macros_1.scala:8: error: macro implementation has wrong shape: required: (c: scala.reflect.macros.Context)(x: c.Expr[Int]): c.Expr[Any] - found : (c: scala.reflect.macros.Context)(x: c.universe.Tree): Nothing -type mismatch for parameter x: c.Expr[Int] does not conform to c.universe.Tree + found : (c: scala.reflect.macros.Context)(x: Int): Nothing +type mismatch for parameter x: c.Expr[Int] does not conform to Int def foo(x: Int) = macro Impls.foo - ^ + ^ one error found diff --git a/test/files/neg/macro-invalidsig-params-badtype/Impls_Macros_1.scala b/test/files/neg/macro-invalidsig-params-badtype/Impls_Macros_1.scala index ab90b85881..175683d6d3 100644 --- a/test/files/neg/macro-invalidsig-params-badtype/Impls_Macros_1.scala +++ b/test/files/neg/macro-invalidsig-params-badtype/Impls_Macros_1.scala @@ -1,7 +1,7 @@ import scala.reflect.macros.{Context => Ctx} object Impls { - def foo(c: Ctx)(x: c.universe.Tree) = ??? + def foo(c: Ctx)(x: Int) = ??? } object Macros { diff --git a/test/files/neg/macro-invalidsig.check b/test/files/neg/macro-invalidsig.check index 52074cf783..cbdaf51081 100644 --- a/test/files/neg/macro-invalidsig.check +++ b/test/files/neg/macro-invalidsig.check @@ -3,67 +3,67 @@ Macros_Test_2.scala:2: error: macro implementation has wrong shape: found : (c: scala.reflect.macros.Context)(implicit evidence$2: Numeric[U]): c.universe.Literal macro implementations cannot have implicit parameters other than WeakTypeTag evidences def foo[U] = macro Impls1.foo[U] - ^ + ^ Macros_Test_2.scala:6: error: macro implementation has wrong shape: required: (c: scala.reflect.macros.Context): c.Expr[Any] found : : Nothing number of parameter sections differ def foo = macro Impls2.foo - ^ + ^ Macros_Test_2.scala:10: error: macro implementation has wrong shape: required: (c: scala.reflect.macros.Context): c.Expr[Any] found : (c: scala.reflect.api.Universe): Nothing type mismatch for parameter c: scala.reflect.macros.Context does not conform to scala.reflect.api.Universe def foo = macro Impls3.foo - ^ + ^ Macros_Test_2.scala:14: error: macro implementation has wrong shape: required: (c: scala.reflect.macros.Context): c.Expr[Any] found : (cs: scala.reflect.macros.Context*): Nothing types incompatible for parameter cs: corresponding is not a vararg parameter def foo = macro Impls4.foo - ^ + ^ Macros_Test_2.scala:18: error: macro implementation has wrong shape: required: (c: scala.reflect.macros.Context)(x: c.Expr[Any]): c.Expr[Any] found : (c: scala.reflect.macros.Context): Nothing number of parameter sections differ def foo(x: Any) = macro Impls5.foo - ^ + ^ Macros_Test_2.scala:22: error: macro implementation has wrong shape: required: (c: scala.reflect.macros.Context)(x: c.Expr[Int]): c.Expr[Unit] found : (c: scala.reflect.macros.Context)(implicit x: c.Expr[Int]): c.Expr[Unit] macro implementations cannot have implicit parameters other than WeakTypeTag evidences def foo[U](x: Int) = macro Impls6.foo[T, U] - ^ + ^ Macros_Test_2.scala:26: error: macro implementation has wrong shape: required: (c: scala.reflect.macros.Context)(x: c.Expr[Int]): c.Expr[Any] found : (c: scala.reflect.macros.Context)(x: c.Expr[Int], y: c.Expr[Int]): Nothing parameter lists have different length, found extra parameter y: c.Expr[Int] def foo(x: Int) = macro Impls7.foo - ^ + ^ Macros_Test_2.scala:30: error: macro implementation has wrong shape: required: (c: scala.reflect.macros.Context)(x: c.Expr[Int]): c.Expr[Any] found : (c: scala.reflect.macros.Context)(x: c.universe.Symbol): Nothing type mismatch for parameter x: c.Expr[Int] does not conform to c.universe.Symbol def foo(x: Int) = macro Impls8.foo - ^ + ^ Macros_Test_2.scala:34: error: macro implementation has wrong shape: required: (c: scala.reflect.macros.Context)(x: c.Expr[Int], y: c.Expr[Int]): c.Expr[Any] found : (c: scala.reflect.macros.Context)(xs: c.Expr[Int]*): Nothing parameter lists have different length, required extra parameter y: c.Expr[Int] def foo(x: Int, y: Int) = macro Impls9.foo - ^ + ^ Macros_Test_2.scala:38: error: macro implementation has wrong shape: required: (c: scala.reflect.macros.Context)(x: c.Expr[Int], y: c.Expr[Int]): c.Expr[Any] found : (c: scala.reflect.macros.Context)(y: c.Expr[Int], x: c.Expr[Int]): Nothing parameter names differ: x != y def foo(x: Int, y: Int) = macro Impls10.foo - ^ + ^ Macros_Test_2.scala:42: error: macro implementation has wrong shape: required: (c: scala.reflect.macros.Context): c.Expr[Any] found : (c: scala.reflect.macros.Context)(U: c.universe.Type): Nothing number of parameter sections differ def foo[U] = macro Impls11.foo[U] - ^ + ^ Macros_Test_2.scala:46: error: type arguments [U] do not conform to method foo's type parameter bounds [U <: String] def foo[U] = macro Impls12.foo[U] ^ @@ -72,10 +72,10 @@ Macros_Test_2.scala:50: error: type arguments [U] do not conform to method foo's ^ Macros_Test_2.scala:54: error: wrong number of type parameters for method foo: [U](c: scala.reflect.macros.Context)(implicit evidence$4: c.WeakTypeTag[U])Nothing def foo = macro Impls14.foo - ^ + ^ Macros_Test_2.scala:59: error: wrong number of type parameters for method foo: [T, U, V](c: scala.reflect.macros.Context)(implicit evidence$5: c.WeakTypeTag[T], implicit evidence$6: c.WeakTypeTag[U], implicit V: c.WeakTypeTag[V])c.Expr[Unit] def foo15[V] = macro Impls15.foo - ^ + ^ Macros_Test_2.scala:60: error: wrong number of type parameters for method foo: [T, U, V](c: scala.reflect.macros.Context)(implicit evidence$7: c.WeakTypeTag[T], implicit evidence$8: c.WeakTypeTag[U], implicit V: c.WeakTypeTag[V])c.Expr[Unit] def foo16[V] = macro Impls16.foo[V] ^ diff --git a/test/files/neg/t5689.check b/test/files/neg/t5689.check index 50aaa7dbfe..ad9b79cdcb 100644 --- a/test/files/neg/t5689.check +++ b/test/files/neg/t5689.check @@ -3,5 +3,5 @@ t5689.scala:4: error: macro implementation has wrong shape: found : (c: scala.reflect.macros.Context)(i: c.Expr[Double]): c.Expr[Int] type mismatch for return type: c.Expr[Int] does not conform to c.Expr[String] def returnsString(i: Double): String = macro returnsIntImpl - ^ + ^ one error found diff --git a/test/files/run/macro-bodyexpandstoimpl/Impls_1.scala b/test/files/run/macro-bodyexpandstoimpl/Impls_1.scala index 9c1e4ee46d..56c5252f31 100644 --- a/test/files/run/macro-bodyexpandstoimpl/Impls_1.scala +++ b/test/files/run/macro-bodyexpandstoimpl/Impls_1.scala @@ -7,6 +7,8 @@ object Impls { def refToFoo_impl(c: Ctx)(dummy: c.Expr[Int]) = { import c.universe._ val body = Select(Ident(TermName("Impls")), TermName("foo")) + val global = c.universe.asInstanceOf[scala.tools.nsc.Global] + global.analyzer.markMacroImplRef(body.asInstanceOf[global.Tree]) c.Expr[Int](body) } } \ No newline at end of file diff --git a/test/files/run/macro-bundle.check b/test/files/run/macro-bundle.check new file mode 100644 index 0000000000..2107454960 --- /dev/null +++ b/test/files/run/macro-bundle.check @@ -0,0 +1,3 @@ +() +Int +() diff --git a/test/files/run/macro-bundle.flags b/test/files/run/macro-bundle.flags new file mode 100644 index 0000000000..cd66464f2f --- /dev/null +++ b/test/files/run/macro-bundle.flags @@ -0,0 +1 @@ +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-bundle/Impls_Macros_1.scala b/test/files/run/macro-bundle/Impls_Macros_1.scala new file mode 100644 index 0000000000..3f651c9a43 --- /dev/null +++ b/test/files/run/macro-bundle/Impls_Macros_1.scala @@ -0,0 +1,13 @@ +import scala.reflect.macros.Context +import scala.reflect.macros.Macro + +trait Impl extends Macro { + def mono = c.literalUnit + def poly[T: c.WeakTypeTag] = c.literal(c.weakTypeOf[T].toString) + def weird = macro mono +} + +object Macros { + def mono = macro Impl.mono + def poly[T] = macro Impl.poly[T] +} \ No newline at end of file diff --git a/test/files/run/macro-bundle/Test_2.scala b/test/files/run/macro-bundle/Test_2.scala new file mode 100644 index 0000000000..428f809f9d --- /dev/null +++ b/test/files/run/macro-bundle/Test_2.scala @@ -0,0 +1,5 @@ +object Test extends App { + println(Macros.mono) + println(Macros.poly[Int]) + println(new Impl{val c = ???}.weird) +} \ 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 index ca202d053f..4e766bde89 100644 --- a/test/files/run/macro-toplevel-companion-b/Test_2.scala +++ b/test/files/run/macro-toplevel-companion-b/Test_2.scala @@ -7,5 +7,5 @@ import Macros._ object Test extends App { val tb = cm.mkToolBox() try tb.compile(Select(Ident(TermName("Macros")), TermName("foo"))) - catch { case ToolBoxError(message, _) => println("""macroSynthetic-.*?\.scala""".r.replaceAllIn(message, "")) } + catch { case ToolBoxError(message, _) => println("""(Found in|and) .*?compileLateSynthetic-.*?\.scala""".r.replaceAllIn(message, m => m.group(1) + " ")) } } \ 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 index 0e99903158..c315f8b942 100644 --- a/test/files/run/macro-toplevel-companion-c.scala +++ b/test/files/run/macro-toplevel-companion-c.scala @@ -45,7 +45,7 @@ object Test extends DirectTest { log("Compiling Test_2...") if (compileTest()) log("Success!") else log("Failed...") } - println("""macroSynthetic-.*?\.scala""".r.replaceAllIn(baos.toString, "")) + println("""(Found in|and) .*?compileLateSynthetic-.*?\.scala""".r.replaceAllIn(baos.toString, m => m.group(1) + " ")) System.setErr(prevErr) } } \ No newline at end of file -- cgit v1.2.3 From 463ef75e2f8e15d2e835dd3c2467206fd52b6246 Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Wed, 27 Feb 2013 15:15:36 +0100 Subject: refactors macro runtimes Following typedMacroBody, macroRuntime along with its friends has also been moved out into a separate component. --- .../macros/compiler/DefaultMacroCompiler.scala | 2 +- .../scala/reflect/macros/contexts/Aliases.scala | 35 +++++++++ .../scala/reflect/macros/contexts/Context.scala | 29 ++++++++ .../scala/reflect/macros/contexts/Enclosures.scala | 36 +++++++++ .../scala/reflect/macros/contexts/Evals.scala | 18 +++++ .../scala/reflect/macros/contexts/ExprUtils.scala | 34 +++++++++ .../scala/reflect/macros/contexts/FrontEnds.scala | 22 ++++++ .../reflect/macros/contexts/Infrastructure.scala | 16 ++++ .../scala/reflect/macros/contexts/Names.scala | 26 +++++++ .../scala/reflect/macros/contexts/Parsers.scala | 24 ++++++ .../scala/reflect/macros/contexts/Reifiers.scala | 77 +++++++++++++++++++ .../scala/reflect/macros/contexts/Synthetics.scala | 66 ++++++++++++++++ .../scala/reflect/macros/contexts/Traces.scala | 8 ++ .../scala/reflect/macros/contexts/Typers.scala | 52 +++++++++++++ .../scala/reflect/macros/runtime/Aliases.scala | 35 --------- .../scala/reflect/macros/runtime/Context.scala | 29 -------- .../scala/reflect/macros/runtime/Enclosures.scala | 36 --------- .../scala/reflect/macros/runtime/Evals.scala | 18 ----- .../scala/reflect/macros/runtime/ExprUtils.scala | 34 --------- .../scala/reflect/macros/runtime/FrontEnds.scala | 20 ----- .../reflect/macros/runtime/Infrastructure.scala | 16 ---- .../macros/runtime/JavaReflectionRuntimes.scala | 31 ++++++++ .../reflect/macros/runtime/MacroRuntimes.scala | 74 ++++++++++++++++++ .../scala/reflect/macros/runtime/Names.scala | 26 ------- .../scala/reflect/macros/runtime/Parsers.scala | 24 ------ .../scala/reflect/macros/runtime/Reifiers.scala | 77 ------------------- .../macros/runtime/ScalaReflectionRuntimes.scala | 33 ++++++++ .../scala/reflect/macros/runtime/Synthetics.scala | 66 ---------------- .../scala/reflect/macros/runtime/Traces.scala | 8 -- .../scala/reflect/macros/runtime/Typers.scala | 52 ------------- .../scala/reflect/macros/runtime/package.scala | 5 ++ src/compiler/scala/reflect/reify/Taggers.scala | 2 +- .../scala/tools/nsc/typechecker/Macros.scala | 87 +++------------------- .../tools/nsc/typechecker/StdAttachments.scala | 2 +- .../scala/tools/reflect/MacroImplementations.scala | 2 +- 35 files changed, 601 insertions(+), 521 deletions(-) create mode 100644 src/compiler/scala/reflect/macros/contexts/Aliases.scala create mode 100644 src/compiler/scala/reflect/macros/contexts/Context.scala create mode 100644 src/compiler/scala/reflect/macros/contexts/Enclosures.scala create mode 100644 src/compiler/scala/reflect/macros/contexts/Evals.scala create mode 100644 src/compiler/scala/reflect/macros/contexts/ExprUtils.scala create mode 100644 src/compiler/scala/reflect/macros/contexts/FrontEnds.scala create mode 100644 src/compiler/scala/reflect/macros/contexts/Infrastructure.scala create mode 100644 src/compiler/scala/reflect/macros/contexts/Names.scala create mode 100644 src/compiler/scala/reflect/macros/contexts/Parsers.scala create mode 100644 src/compiler/scala/reflect/macros/contexts/Reifiers.scala create mode 100644 src/compiler/scala/reflect/macros/contexts/Synthetics.scala create mode 100644 src/compiler/scala/reflect/macros/contexts/Traces.scala create mode 100644 src/compiler/scala/reflect/macros/contexts/Typers.scala delete mode 100644 src/compiler/scala/reflect/macros/runtime/Aliases.scala delete mode 100644 src/compiler/scala/reflect/macros/runtime/Context.scala delete mode 100644 src/compiler/scala/reflect/macros/runtime/Enclosures.scala delete mode 100644 src/compiler/scala/reflect/macros/runtime/Evals.scala delete mode 100644 src/compiler/scala/reflect/macros/runtime/ExprUtils.scala delete mode 100644 src/compiler/scala/reflect/macros/runtime/FrontEnds.scala delete mode 100644 src/compiler/scala/reflect/macros/runtime/Infrastructure.scala create mode 100644 src/compiler/scala/reflect/macros/runtime/JavaReflectionRuntimes.scala create mode 100644 src/compiler/scala/reflect/macros/runtime/MacroRuntimes.scala delete mode 100644 src/compiler/scala/reflect/macros/runtime/Names.scala delete mode 100644 src/compiler/scala/reflect/macros/runtime/Parsers.scala delete mode 100644 src/compiler/scala/reflect/macros/runtime/Reifiers.scala create mode 100644 src/compiler/scala/reflect/macros/runtime/ScalaReflectionRuntimes.scala delete mode 100644 src/compiler/scala/reflect/macros/runtime/Synthetics.scala delete mode 100644 src/compiler/scala/reflect/macros/runtime/Traces.scala delete mode 100644 src/compiler/scala/reflect/macros/runtime/Typers.scala create mode 100644 src/compiler/scala/reflect/macros/runtime/package.scala diff --git a/src/compiler/scala/reflect/macros/compiler/DefaultMacroCompiler.scala b/src/compiler/scala/reflect/macros/compiler/DefaultMacroCompiler.scala index 749e730c0e..32c6da8007 100644 --- a/src/compiler/scala/reflect/macros/compiler/DefaultMacroCompiler.scala +++ b/src/compiler/scala/reflect/macros/compiler/DefaultMacroCompiler.scala @@ -2,7 +2,7 @@ package scala.reflect.macros package compiler import scala.tools.nsc.Global -import scala.reflect.macros.runtime.Context +import scala.reflect.macros.contexts.Context abstract class DefaultMacroCompiler extends Resolvers with Validators diff --git a/src/compiler/scala/reflect/macros/contexts/Aliases.scala b/src/compiler/scala/reflect/macros/contexts/Aliases.scala new file mode 100644 index 0000000000..cc64d97d85 --- /dev/null +++ b/src/compiler/scala/reflect/macros/contexts/Aliases.scala @@ -0,0 +1,35 @@ +package scala.reflect.macros +package contexts + +trait Aliases { + self: Context => + + override type Symbol = universe.Symbol + override type Type = universe.Type + override type Name = universe.Name + override type TermName = universe.TermName + override type TypeName = universe.TypeName + override type Tree = universe.Tree + override type Position = universe.Position + override type Scope = universe.Scope + override type Modifiers = universe.Modifiers + + override type Expr[+T] = universe.Expr[T] + override val Expr = universe.Expr + def Expr[T: WeakTypeTag](tree: Tree): Expr[T] = universe.Expr[T](mirror, universe.FixedMirrorTreeCreator(mirror, tree)) + + override type WeakTypeTag[T] = universe.WeakTypeTag[T] + override type TypeTag[T] = universe.TypeTag[T] + override val WeakTypeTag = universe.WeakTypeTag + override val TypeTag = universe.TypeTag + def WeakTypeTag[T](tpe: Type): WeakTypeTag[T] = universe.WeakTypeTag[T](mirror, universe.FixedMirrorTypeCreator(mirror, tpe)) + def TypeTag[T](tpe: Type): TypeTag[T] = universe.TypeTag[T](mirror, universe.FixedMirrorTypeCreator(mirror, tpe)) + override def weakTypeTag[T](implicit attag: WeakTypeTag[T]) = attag + override def typeTag[T](implicit ttag: TypeTag[T]) = ttag + override def weakTypeOf[T](implicit attag: WeakTypeTag[T]): Type = attag.tpe + override def typeOf[T](implicit ttag: TypeTag[T]): Type = ttag.tpe + + implicit class RichOpenImplicit(oi: universe.analyzer.OpenImplicit) { + def toImplicitCandidate = ImplicitCandidate(oi.info.pre, oi.info.sym, oi.pt, oi.tree) + } +} \ No newline at end of file diff --git a/src/compiler/scala/reflect/macros/contexts/Context.scala b/src/compiler/scala/reflect/macros/contexts/Context.scala new file mode 100644 index 0000000000..bd1d7d5248 --- /dev/null +++ b/src/compiler/scala/reflect/macros/contexts/Context.scala @@ -0,0 +1,29 @@ +package scala.reflect.macros +package contexts + +import scala.tools.nsc.Global + +abstract class Context extends scala.reflect.macros.Context + with Aliases + with Enclosures + with Names + with Reifiers + with FrontEnds + with Infrastructure + with Typers + with Parsers + with Evals + with ExprUtils + with Synthetics + with Traces { + + val universe: Global + + val mirror: universe.Mirror = universe.rootMirror + + val callsiteTyper: universe.analyzer.Typer + + val prefix: Expr[PrefixType] + + val expandee: Tree +} diff --git a/src/compiler/scala/reflect/macros/contexts/Enclosures.scala b/src/compiler/scala/reflect/macros/contexts/Enclosures.scala new file mode 100644 index 0000000000..bb88c8d5e1 --- /dev/null +++ b/src/compiler/scala/reflect/macros/contexts/Enclosures.scala @@ -0,0 +1,36 @@ +package scala.reflect.macros +package contexts + +import scala.reflect.{ClassTag, classTag} + +trait Enclosures { + self: Context => + + import universe._ + + type MacroRole = analyzer.MacroRole + def APPLY_ROLE = analyzer.APPLY_ROLE + def macroRole: MacroRole + + private lazy val site = callsiteTyper.context + private lazy val enclTrees = site.enclosingContextChain map (_.tree) + private lazy val enclPoses = enclosingMacros map (_.macroApplication.pos) filterNot (_ eq NoPosition) + + private def lenientEnclosure[T <: Tree : ClassTag]: Tree = enclTrees collectFirst { case x: T => x } getOrElse EmptyTree + private def strictEnclosure[T <: Tree : ClassTag]: T = enclTrees collectFirst { case x: T => x } getOrElse (throw new EnclosureException(classTag[T].runtimeClass, enclTrees)) + + // vals are eager to simplify debugging + // after all we wouldn't save that much time by making them lazy + val macroApplication: Tree = expandee + def enclosingPackage: PackageDef = strictEnclosure[PackageDef] + val enclosingClass: Tree = lenientEnclosure[ImplDef] + def enclosingImpl: ImplDef = strictEnclosure[ImplDef] + def enclosingTemplate: Template = strictEnclosure[Template] + val enclosingImplicits: List[ImplicitCandidate] = site.openImplicits.map(_.toImplicitCandidate) + val enclosingMacros: List[Context] = this :: universe.analyzer.openMacros // include self + val enclosingMethod: Tree = lenientEnclosure[DefDef] + def enclosingDef: DefDef = strictEnclosure[DefDef] + val enclosingPosition: Position = if (enclPoses.isEmpty) NoPosition else enclPoses.head.pos + val enclosingUnit: CompilationUnit = universe.currentRun.currentUnit + val enclosingRun: Run = universe.currentRun +} diff --git a/src/compiler/scala/reflect/macros/contexts/Evals.scala b/src/compiler/scala/reflect/macros/contexts/Evals.scala new file mode 100644 index 0000000000..84928ddf86 --- /dev/null +++ b/src/compiler/scala/reflect/macros/contexts/Evals.scala @@ -0,0 +1,18 @@ +package scala.reflect.macros +package contexts + +import scala.reflect.runtime.{universe => ru} +import scala.tools.reflect.ToolBox + +trait Evals { + self: Context => + + private lazy val evalMirror = ru.runtimeMirror(universe.analyzer.defaultMacroClassloader) + private lazy val evalToolBox = evalMirror.mkToolBox() + private lazy val evalImporter = ru.mkImporter(universe).asInstanceOf[ru.Importer { val from: universe.type }] + + def eval[T](expr: Expr[T]): T = { + val imported = evalImporter.importTree(expr.tree) + evalToolBox.eval(imported).asInstanceOf[T] + } +} \ No newline at end of file diff --git a/src/compiler/scala/reflect/macros/contexts/ExprUtils.scala b/src/compiler/scala/reflect/macros/contexts/ExprUtils.scala new file mode 100644 index 0000000000..4846325d1e --- /dev/null +++ b/src/compiler/scala/reflect/macros/contexts/ExprUtils.scala @@ -0,0 +1,34 @@ +package scala.reflect.macros +package contexts + +trait ExprUtils { + self: Context => + + import universe._ + + def literalNull = Expr[Null](Literal(Constant(null)))(TypeTag.Null) + + def literalUnit = Expr[Unit](Literal(Constant(())))(TypeTag.Unit) + + def literalTrue = Expr[Boolean](Literal(Constant(true)))(TypeTag.Boolean) + + def literalFalse = Expr[Boolean](Literal(Constant(false)))(TypeTag.Boolean) + + def literal(x: Boolean) = Expr[Boolean](Literal(Constant(x)))(TypeTag.Boolean) + + def literal(x: Byte) = Expr[Byte](Literal(Constant(x)))(TypeTag.Byte) + + def literal(x: Short) = Expr[Short](Literal(Constant(x)))(TypeTag.Short) + + def literal(x: Int) = Expr[Int](Literal(Constant(x)))(TypeTag.Int) + + def literal(x: Long) = Expr[Long](Literal(Constant(x)))(TypeTag.Long) + + def literal(x: Float) = Expr[Float](Literal(Constant(x)))(TypeTag.Float) + + def literal(x: Double) = Expr[Double](Literal(Constant(x)))(TypeTag.Double) + + def literal(x: String) = Expr[String](Literal(Constant(x)))(TypeTag[String](definitions.StringClass.toTypeConstructor)) + + def literal(x: Char) = Expr[Char](Literal(Constant(x)))(TypeTag.Char) +} diff --git a/src/compiler/scala/reflect/macros/contexts/FrontEnds.scala b/src/compiler/scala/reflect/macros/contexts/FrontEnds.scala new file mode 100644 index 0000000000..fda05de09c --- /dev/null +++ b/src/compiler/scala/reflect/macros/contexts/FrontEnds.scala @@ -0,0 +1,22 @@ +package scala.reflect.macros +package contexts + +import scala.reflect.macros.runtime.AbortMacroException + +trait FrontEnds { + self: Context => + + def echo(pos: Position, msg: String): Unit = universe.reporter.echo(pos, msg) + + def info(pos: Position, msg: String, force: Boolean): Unit = universe.reporter.info(pos, msg, force) + + def hasWarnings: Boolean = universe.reporter.hasErrors + + def hasErrors: Boolean = universe.reporter.hasErrors + + def warning(pos: Position, msg: String): Unit = callsiteTyper.context.warning(pos, msg) + + def error(pos: Position, msg: String): Unit = callsiteTyper.context.error(pos, msg) + + def abort(pos: Position, msg: String): Nothing = throw new AbortMacroException(pos, msg) +} diff --git a/src/compiler/scala/reflect/macros/contexts/Infrastructure.scala b/src/compiler/scala/reflect/macros/contexts/Infrastructure.scala new file mode 100644 index 0000000000..df7aa4d2be --- /dev/null +++ b/src/compiler/scala/reflect/macros/contexts/Infrastructure.scala @@ -0,0 +1,16 @@ +package scala.reflect.macros +package contexts + +trait Infrastructure { + self: Context => + + def settings: List[String] = { + val us = universe.settings + import us._ + userSetSettings collectFirst { case x: MultiStringSetting if x.name == XmacroSettings.name => x.value } getOrElse Nil + } + + def compilerSettings: List[String] = universe.settings.recreateArgs + + def classPath: List[java.net.URL] = global.classPath.asURLs +} diff --git a/src/compiler/scala/reflect/macros/contexts/Names.scala b/src/compiler/scala/reflect/macros/contexts/Names.scala new file mode 100644 index 0000000000..e535754a98 --- /dev/null +++ b/src/compiler/scala/reflect/macros/contexts/Names.scala @@ -0,0 +1,26 @@ +package scala.reflect.macros +package contexts + +trait Names { + self: Context => + + lazy val freshNameCreator = callsiteTyper.context.unit.fresh + + def fresh(): String = + freshName() + + def fresh(name: String): String = + freshName(name) + + def fresh[NameType <: Name](name: NameType): NameType = + freshName[NameType](name) + + def freshName(): String = + freshNameCreator.newName() + + def freshName(name: String): String = + freshNameCreator.newName(name) + + def freshName[NameType <: Name](name: NameType): NameType = + name.mapName(freshNameCreator.newName(_)).asInstanceOf[NameType] +} \ No newline at end of file diff --git a/src/compiler/scala/reflect/macros/contexts/Parsers.scala b/src/compiler/scala/reflect/macros/contexts/Parsers.scala new file mode 100644 index 0000000000..3dab02beba --- /dev/null +++ b/src/compiler/scala/reflect/macros/contexts/Parsers.scala @@ -0,0 +1,24 @@ +package scala.reflect.macros +package contexts + +import scala.language.existentials +import scala.tools.reflect.ToolBox +import scala.tools.reflect.ToolBoxError + +trait Parsers { + self: Context => + + def parse(code: String): Tree = + // todo. provide decent implementation + // see `Typers.typedUseCase` for details + try { + import scala.reflect.runtime.{universe => ru} + val parsed = ru.rootMirror.mkToolBox().parse(code) + val importer = universe.mkImporter(ru) + importer.importTree(parsed) + } catch { + case ToolBoxError(msg, cause) => + // todo. provide a position + throw new ParseException(universe.NoPosition, msg) + } +} diff --git a/src/compiler/scala/reflect/macros/contexts/Reifiers.scala b/src/compiler/scala/reflect/macros/contexts/Reifiers.scala new file mode 100644 index 0000000000..ecef1c7289 --- /dev/null +++ b/src/compiler/scala/reflect/macros/contexts/Reifiers.scala @@ -0,0 +1,77 @@ +/* NSC -- new Scala compiler + * Copyright 2005-2013 LAMP/EPFL + * @author Gilles Dubochet + */ + +package scala.reflect.macros +package contexts + +trait Reifiers { + self: Context => + + val global: universe.type = universe + import universe._ + import definitions._ + + def reifyTree(universe: Tree, mirror: Tree, tree: Tree): Tree = { + assert(ExprClass != NoSymbol) + val result = scala.reflect.reify.`package`.reifyTree(self.universe)(callsiteTyper, universe, mirror, tree) + logFreeVars(enclosingPosition, result) + result + } + + def reifyType(universe: Tree, mirror: Tree, tpe: Type, concrete: Boolean = false): Tree = { + assert(TypeTagsClass != NoSymbol) + val result = scala.reflect.reify.`package`.reifyType(self.universe)(callsiteTyper, universe, mirror, tpe, concrete) + logFreeVars(enclosingPosition, result) + result + } + + def reifyRuntimeClass(tpe: Type, concrete: Boolean = true): Tree = + scala.reflect.reify.`package`.reifyRuntimeClass(universe)(callsiteTyper, tpe, concrete = concrete) + + def reifyEnclosingRuntimeClass: Tree = + scala.reflect.reify.`package`.reifyEnclosingRuntimeClass(universe)(callsiteTyper) + + def unreifyTree(tree: Tree): Tree = { + assert(ExprSplice != NoSymbol) + Select(tree, ExprSplice) + } + + // fixme: if I put utils here, then "global" from utils' early initialization syntax + // and "global" that comes from here conflict with each other when incrementally compiling + // the problem is that both are pickled with the same owner - trait Reifiers + // and this upsets the compiler, so that oftentimes it throws assertion failures + // Martin knows the details + // + // object utils extends { + // val global: self.global.type = self.global + // val typer: global.analyzer.Typer = self.callsiteTyper + // } with scala.reflect.reify.utils.Utils + // import utils._ + + private def logFreeVars(position: Position, reification: Tree): Unit = { + object utils extends { + val global: self.global.type = self.global + val typer: global.analyzer.Typer = self.callsiteTyper + } with scala.reflect.reify.utils.Utils + import utils._ + + def logFreeVars(symtab: SymbolTable): Unit = + // logging free vars only when they are untyped prevents avalanches of duplicate messages + symtab.syms map (sym => symtab.symDef(sym)) foreach { + case FreeTermDef(_, _, binding, _, origin) if universe.settings.logFreeTerms && binding.tpe == null => + reporter.echo(position, "free term: %s %s".format(showRaw(binding), origin)) + case FreeTypeDef(_, _, binding, _, origin) if universe.settings.logFreeTypes && binding.tpe == null => + reporter.echo(position, "free type: %s %s".format(showRaw(binding), origin)) + case _ => + // do nothing + } + + if (universe.settings.logFreeTerms || universe.settings.logFreeTypes) + reification match { + case ReifiedTree(_, _, symtab, _, _, _, _) => logFreeVars(symtab) + case ReifiedType(_, _, symtab, _, _, _) => logFreeVars(symtab) + } + } +} diff --git a/src/compiler/scala/reflect/macros/contexts/Synthetics.scala b/src/compiler/scala/reflect/macros/contexts/Synthetics.scala new file mode 100644 index 0000000000..ada16a8113 --- /dev/null +++ b/src/compiler/scala/reflect/macros/contexts/Synthetics.scala @@ -0,0 +1,66 @@ +/* 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/reflect/macros/contexts/Traces.scala b/src/compiler/scala/reflect/macros/contexts/Traces.scala new file mode 100644 index 0000000000..df47f6ba81 --- /dev/null +++ b/src/compiler/scala/reflect/macros/contexts/Traces.scala @@ -0,0 +1,8 @@ +package scala.reflect.macros +package contexts + +trait Traces extends util.Traces { + self: Context => + + def globalSettings = universe.settings +} diff --git a/src/compiler/scala/reflect/macros/contexts/Typers.scala b/src/compiler/scala/reflect/macros/contexts/Typers.scala new file mode 100644 index 0000000000..4a1122b913 --- /dev/null +++ b/src/compiler/scala/reflect/macros/contexts/Typers.scala @@ -0,0 +1,52 @@ +package scala.reflect.macros +package contexts + +import scala.reflect.internal.Mode + +trait Typers { + self: Context => + + def openMacros: List[Context] = this :: universe.analyzer.openMacros + + def openImplicits: List[ImplicitCandidate] = callsiteTyper.context.openImplicits.map(_.toImplicitCandidate) + + /** + * @see [[scala.tools.reflect.ToolBox.typeCheck]] + */ + def typeCheck(tree: Tree, pt: Type = universe.WildcardType, silent: Boolean = false, withImplicitViewsDisabled: Boolean = false, withMacrosDisabled: Boolean = false): Tree = { + macroLogVerbose("typechecking %s with expected type %s, implicit views = %s, macros = %s".format(tree, pt, !withImplicitViewsDisabled, !withMacrosDisabled)) + val context = callsiteTyper.context + val wrapper1 = if (!withImplicitViewsDisabled) (context.withImplicitsEnabled[Tree] _) else (context.withImplicitsDisabled[Tree] _) + val wrapper2 = if (!withMacrosDisabled) (context.withMacrosEnabled[Tree] _) else (context.withMacrosDisabled[Tree] _) + def wrapper (tree: => Tree) = wrapper1(wrapper2(tree)) + // if you get a "silent mode is not available past typer" here + // don't rush to change the typecheck not to use the silent method when the silent parameter is false + // typechecking uses silent anyways (e.g. in typedSelect), so you'll only waste your time + // I'd advise fixing the root cause: finding why the context is not set to report errors + // (also see reflect.runtime.ToolBoxes.typeCheckExpr for a workaround that might work for you) + wrapper(callsiteTyper.silent(_.typed(tree, pt), reportAmbiguousErrors = false) match { + case universe.analyzer.SilentResultValue(result) => + macroLogVerbose(result) + result + case error @ universe.analyzer.SilentTypeError(_) => + macroLogVerbose(error.err.errMsg) + if (!silent) throw new TypecheckException(error.err.errPos, error.err.errMsg) + universe.EmptyTree + }) + } + + def inferImplicitValue(pt: Type, silent: Boolean = true, withMacrosDisabled: Boolean = false, pos: Position = enclosingPosition): Tree = { + macroLogVerbose("inferring implicit value of type %s, macros = %s".format(pt, !withMacrosDisabled)) + universe.analyzer.inferImplicit(universe.EmptyTree, pt, false, callsiteTyper.context, silent, withMacrosDisabled, pos, (pos, msg) => throw TypecheckException(pos, msg)) + } + + def inferImplicitView(tree: Tree, from: Type, to: Type, silent: Boolean = true, withMacrosDisabled: Boolean = false, pos: Position = enclosingPosition): Tree = { + macroLogVerbose("inferring implicit view from %s to %s for %s, macros = %s".format(from, to, tree, !withMacrosDisabled)) + val viewTpe = universe.appliedType(universe.definitions.FunctionClass(1).toTypeConstructor, List(from, to)) + universe.analyzer.inferImplicit(tree, viewTpe, true, callsiteTyper.context, silent, withMacrosDisabled, pos, (pos, msg) => throw TypecheckException(pos, msg)) + } + + def resetAllAttrs(tree: Tree): Tree = universe.resetAllAttrs(tree) + + def resetLocalAttrs(tree: Tree): Tree = universe.resetLocalAttrs(tree) +} diff --git a/src/compiler/scala/reflect/macros/runtime/Aliases.scala b/src/compiler/scala/reflect/macros/runtime/Aliases.scala deleted file mode 100644 index 1c6703aeee..0000000000 --- a/src/compiler/scala/reflect/macros/runtime/Aliases.scala +++ /dev/null @@ -1,35 +0,0 @@ -package scala.reflect.macros -package runtime - -trait Aliases { - self: Context => - - override type Symbol = universe.Symbol - override type Type = universe.Type - override type Name = universe.Name - override type TermName = universe.TermName - override type TypeName = universe.TypeName - override type Tree = universe.Tree - override type Position = universe.Position - override type Scope = universe.Scope - override type Modifiers = universe.Modifiers - - override type Expr[+T] = universe.Expr[T] - override val Expr = universe.Expr - def Expr[T: WeakTypeTag](tree: Tree): Expr[T] = universe.Expr[T](mirror, universe.FixedMirrorTreeCreator(mirror, tree)) - - override type WeakTypeTag[T] = universe.WeakTypeTag[T] - override type TypeTag[T] = universe.TypeTag[T] - override val WeakTypeTag = universe.WeakTypeTag - override val TypeTag = universe.TypeTag - def WeakTypeTag[T](tpe: Type): WeakTypeTag[T] = universe.WeakTypeTag[T](mirror, universe.FixedMirrorTypeCreator(mirror, tpe)) - def TypeTag[T](tpe: Type): TypeTag[T] = universe.TypeTag[T](mirror, universe.FixedMirrorTypeCreator(mirror, tpe)) - override def weakTypeTag[T](implicit attag: WeakTypeTag[T]) = attag - override def typeTag[T](implicit ttag: TypeTag[T]) = ttag - override def weakTypeOf[T](implicit attag: WeakTypeTag[T]): Type = attag.tpe - override def typeOf[T](implicit ttag: TypeTag[T]): Type = ttag.tpe - - implicit class RichOpenImplicit(oi: universe.analyzer.OpenImplicit) { - def toImplicitCandidate = ImplicitCandidate(oi.info.pre, oi.info.sym, oi.pt, oi.tree) - } -} \ No newline at end of file diff --git a/src/compiler/scala/reflect/macros/runtime/Context.scala b/src/compiler/scala/reflect/macros/runtime/Context.scala deleted file mode 100644 index 76c684f6d7..0000000000 --- a/src/compiler/scala/reflect/macros/runtime/Context.scala +++ /dev/null @@ -1,29 +0,0 @@ -package scala.reflect.macros -package runtime - -import scala.tools.nsc.Global - -abstract class Context extends scala.reflect.macros.Context - with Aliases - with Enclosures - with Names - with Reifiers - with FrontEnds - with Infrastructure - with Typers - with Parsers - with Evals - with ExprUtils - with Synthetics - with Traces { - - val universe: Global - - val mirror: universe.Mirror = universe.rootMirror - - val callsiteTyper: universe.analyzer.Typer - - val prefix: Expr[PrefixType] - - val expandee: Tree -} diff --git a/src/compiler/scala/reflect/macros/runtime/Enclosures.scala b/src/compiler/scala/reflect/macros/runtime/Enclosures.scala deleted file mode 100644 index f3f92550de..0000000000 --- a/src/compiler/scala/reflect/macros/runtime/Enclosures.scala +++ /dev/null @@ -1,36 +0,0 @@ -package scala.reflect.macros -package runtime - -import scala.reflect.{ClassTag, classTag} - -trait Enclosures { - self: Context => - - import universe._ - - type MacroRole = analyzer.MacroRole - def APPLY_ROLE = analyzer.APPLY_ROLE - def macroRole: MacroRole - - private lazy val site = callsiteTyper.context - private lazy val enclTrees = site.enclosingContextChain map (_.tree) - private lazy val enclPoses = enclosingMacros map (_.macroApplication.pos) filterNot (_ eq NoPosition) - - private def lenientEnclosure[T <: Tree : ClassTag]: Tree = enclTrees collectFirst { case x: T => x } getOrElse EmptyTree - private def strictEnclosure[T <: Tree : ClassTag]: T = enclTrees collectFirst { case x: T => x } getOrElse (throw new EnclosureException(classTag[T].runtimeClass, enclTrees)) - - // vals are eager to simplify debugging - // after all we wouldn't save that much time by making them lazy - val macroApplication: Tree = expandee - def enclosingPackage: PackageDef = strictEnclosure[PackageDef] - val enclosingClass: Tree = lenientEnclosure[ImplDef] - def enclosingImpl: ImplDef = strictEnclosure[ImplDef] - def enclosingTemplate: Template = strictEnclosure[Template] - val enclosingImplicits: List[ImplicitCandidate] = site.openImplicits.map(_.toImplicitCandidate) - val enclosingMacros: List[Context] = this :: universe.analyzer.openMacros // include self - val enclosingMethod: Tree = lenientEnclosure[DefDef] - def enclosingDef: DefDef = strictEnclosure[DefDef] - val enclosingPosition: Position = if (enclPoses.isEmpty) NoPosition else enclPoses.head.pos - val enclosingUnit: CompilationUnit = universe.currentRun.currentUnit - val enclosingRun: Run = universe.currentRun -} diff --git a/src/compiler/scala/reflect/macros/runtime/Evals.scala b/src/compiler/scala/reflect/macros/runtime/Evals.scala deleted file mode 100644 index 1f7b5f2ff1..0000000000 --- a/src/compiler/scala/reflect/macros/runtime/Evals.scala +++ /dev/null @@ -1,18 +0,0 @@ -package scala.reflect.macros -package runtime - -import scala.reflect.runtime.{universe => ru} -import scala.tools.reflect.ToolBox - -trait Evals { - self: Context => - - private lazy val evalMirror = ru.runtimeMirror(universe.analyzer.macroClassloader) - private lazy val evalToolBox = evalMirror.mkToolBox() - private lazy val evalImporter = ru.mkImporter(universe).asInstanceOf[ru.Importer { val from: universe.type }] - - def eval[T](expr: Expr[T]): T = { - val imported = evalImporter.importTree(expr.tree) - evalToolBox.eval(imported).asInstanceOf[T] - } -} \ No newline at end of file diff --git a/src/compiler/scala/reflect/macros/runtime/ExprUtils.scala b/src/compiler/scala/reflect/macros/runtime/ExprUtils.scala deleted file mode 100644 index a719beed97..0000000000 --- a/src/compiler/scala/reflect/macros/runtime/ExprUtils.scala +++ /dev/null @@ -1,34 +0,0 @@ -package scala.reflect.macros -package runtime - -trait ExprUtils { - self: Context => - - import universe._ - - def literalNull = Expr[Null](Literal(Constant(null)))(TypeTag.Null) - - def literalUnit = Expr[Unit](Literal(Constant(())))(TypeTag.Unit) - - def literalTrue = Expr[Boolean](Literal(Constant(true)))(TypeTag.Boolean) - - def literalFalse = Expr[Boolean](Literal(Constant(false)))(TypeTag.Boolean) - - def literal(x: Boolean) = Expr[Boolean](Literal(Constant(x)))(TypeTag.Boolean) - - def literal(x: Byte) = Expr[Byte](Literal(Constant(x)))(TypeTag.Byte) - - def literal(x: Short) = Expr[Short](Literal(Constant(x)))(TypeTag.Short) - - def literal(x: Int) = Expr[Int](Literal(Constant(x)))(TypeTag.Int) - - def literal(x: Long) = Expr[Long](Literal(Constant(x)))(TypeTag.Long) - - def literal(x: Float) = Expr[Float](Literal(Constant(x)))(TypeTag.Float) - - def literal(x: Double) = Expr[Double](Literal(Constant(x)))(TypeTag.Double) - - def literal(x: String) = Expr[String](Literal(Constant(x)))(TypeTag[String](definitions.StringClass.toTypeConstructor)) - - def literal(x: Char) = Expr[Char](Literal(Constant(x)))(TypeTag.Char) -} diff --git a/src/compiler/scala/reflect/macros/runtime/FrontEnds.scala b/src/compiler/scala/reflect/macros/runtime/FrontEnds.scala deleted file mode 100644 index a6a198e1b4..0000000000 --- a/src/compiler/scala/reflect/macros/runtime/FrontEnds.scala +++ /dev/null @@ -1,20 +0,0 @@ -package scala.reflect.macros -package runtime - -trait FrontEnds { - self: Context => - - def echo(pos: Position, msg: String): Unit = universe.reporter.echo(pos, msg) - - def info(pos: Position, msg: String, force: Boolean): Unit = universe.reporter.info(pos, msg, force) - - def hasWarnings: Boolean = universe.reporter.hasErrors - - def hasErrors: Boolean = universe.reporter.hasErrors - - def warning(pos: Position, msg: String): Unit = callsiteTyper.context.warning(pos, msg) - - def error(pos: Position, msg: String): Unit = callsiteTyper.context.error(pos, msg) - - def abort(pos: Position, msg: String): Nothing = throw new AbortMacroException(pos, msg) -} diff --git a/src/compiler/scala/reflect/macros/runtime/Infrastructure.scala b/src/compiler/scala/reflect/macros/runtime/Infrastructure.scala deleted file mode 100644 index 7781693822..0000000000 --- a/src/compiler/scala/reflect/macros/runtime/Infrastructure.scala +++ /dev/null @@ -1,16 +0,0 @@ -package scala.reflect.macros -package runtime - -trait Infrastructure { - self: Context => - - def settings: List[String] = { - val us = universe.settings - import us._ - userSetSettings collectFirst { case x: MultiStringSetting if x.name == XmacroSettings.name => x.value } getOrElse Nil - } - - def compilerSettings: List[String] = universe.settings.recreateArgs - - def classPath: List[java.net.URL] = global.classPath.asURLs -} diff --git a/src/compiler/scala/reflect/macros/runtime/JavaReflectionRuntimes.scala b/src/compiler/scala/reflect/macros/runtime/JavaReflectionRuntimes.scala new file mode 100644 index 0000000000..3ef11fad9d --- /dev/null +++ b/src/compiler/scala/reflect/macros/runtime/JavaReflectionRuntimes.scala @@ -0,0 +1,31 @@ +package scala.reflect.macros +package runtime + +import scala.reflect.runtime.ReflectionUtils +import scala.reflect.macros.{Context => ApiContext} + +trait JavaReflectionRuntimes { + self: scala.tools.nsc.typechecker.Analyzer => + + trait JavaReflectionResolvers { + self: MacroRuntimeResolver => + + import global._ + + def resolveJavaReflectionRuntime(classLoader: ClassLoader): MacroRuntime = { + val implClass = Class.forName(className, true, classLoader) + val implMeths = implClass.getDeclaredMethods.find(_.getName == methName) + // relies on the fact that macro impls cannot be overloaded + // so every methName can resolve to at maximum one method + val implMeth = implMeths getOrElse { throw new NoSuchMethodException(s"$className.$methName") } + macroLogVerbose(s"successfully loaded macro impl as ($implClass, $implMeth)") + args => { + val implObj = + if (isBundle) implClass.getConstructor(classOf[ApiContext]).newInstance(args.c) + else ReflectionUtils.staticSingletonInstance(implClass) + val implArgs = if (isBundle) args.others else args.c +: args.others + implMeth.invoke(implObj, implArgs.asInstanceOf[Seq[AnyRef]]: _*) + } + } + } +} \ No newline at end of file diff --git a/src/compiler/scala/reflect/macros/runtime/MacroRuntimes.scala b/src/compiler/scala/reflect/macros/runtime/MacroRuntimes.scala new file mode 100644 index 0000000000..0f89163803 --- /dev/null +++ b/src/compiler/scala/reflect/macros/runtime/MacroRuntimes.scala @@ -0,0 +1,74 @@ +package scala.reflect.macros +package runtime + +import scala.collection.mutable.{Map => MutableMap} +import scala.reflect.internal.Flags._ +import scala.reflect.runtime.ReflectionUtils +import scala.tools.nsc.util.ScalaClassLoader +import scala.tools.nsc.util.AbstractFileClassLoader + +trait MacroRuntimes extends JavaReflectionRuntimes with ScalaReflectionRuntimes { + self: scala.tools.nsc.typechecker.Analyzer => + + import global._ + import definitions._ + + /** Produces a function that can be used to invoke macro implementation for a given macro definition: + * 1) Looks up macro implementation symbol in this universe. + * 2) Loads its enclosing class from the macro classloader. + * 3) Loads the companion of that enclosing class from the macro classloader. + * 4) Resolves macro implementation within the loaded companion. + * + * @return Requested runtime if macro implementation can be loaded successfully from either of the mirrors, + * `null` otherwise. + */ + private val macroRuntimesCache = perRunCaches.newWeakMap[Symbol, MacroRuntime] + def macroRuntime(macroDef: Symbol): MacroRuntime = { + macroLogVerbose(s"looking for macro implementation: $macroDef") + if (fastTrack contains macroDef) { + macroLogVerbose("macro expansion is serviced by a fast track") + fastTrack(macroDef) + } else { + macroRuntimesCache.getOrElseUpdate(macroDef, new MacroRuntimeResolver(macroDef).resolveRuntime()) + } + } + + /** Macro classloader that is used to resolve and run macro implementations. + * Loads classes from from -cp (aka the library classpath). + * Is also capable of detecting REPL and reusing its classloader. + * + * When -Xmacro-jit is enabled, we sometimes fallback to on-the-fly compilation of macro implementations, + * which compiles implementations into a virtual directory (very much like REPL does) and then conjures + * a classloader mapped to that virtual directory. + */ + lazy val defaultMacroClassloader: ClassLoader = findMacroClassLoader() + + /** Abstracts away resolution of macro runtimes. + */ + type MacroRuntime = MacroArgs => Any + class MacroRuntimeResolver(val macroDef: Symbol) extends JavaReflectionResolvers + with ScalaReflectionResolvers { + val binding = loadMacroImplBinding(macroDef) + val isBundle = binding.isBundle + val className = binding.className + val methName = binding.methName + + def resolveRuntime(): MacroRuntime = { + if (className == Predef_???.owner.javaClassName && methName == Predef_???.name.encoded) { + args => throw new AbortMacroException(args.c.enclosingPosition, "macro implementation is missing") + } else { + try { + macroLogVerbose(s"resolving macro implementation as $className.$methName (isBundle = $isBundle)") + macroLogVerbose(s"classloader is: ${ReflectionUtils.show(defaultMacroClassloader)}") + // resolveScalaReflectionRuntime(defaultMacroClassloader) + resolveJavaReflectionRuntime(defaultMacroClassloader) + } catch { + case ex: Exception => + macroLogVerbose(s"macro runtime failed to load: ${ex.toString}") + macroDef setFlag IS_ERROR + null + } + } + } + } +} \ No newline at end of file diff --git a/src/compiler/scala/reflect/macros/runtime/Names.scala b/src/compiler/scala/reflect/macros/runtime/Names.scala deleted file mode 100644 index 635e8bcd45..0000000000 --- a/src/compiler/scala/reflect/macros/runtime/Names.scala +++ /dev/null @@ -1,26 +0,0 @@ -package scala.reflect.macros -package runtime - -trait Names { - self: Context => - - lazy val freshNameCreator = callsiteTyper.context.unit.fresh - - def fresh(): String = - freshName() - - def fresh(name: String): String = - freshName(name) - - def fresh[NameType <: Name](name: NameType): NameType = - freshName[NameType](name) - - def freshName(): String = - freshNameCreator.newName() - - def freshName(name: String): String = - freshNameCreator.newName(name) - - def freshName[NameType <: Name](name: NameType): NameType = - name.mapName(freshNameCreator.newName(_)).asInstanceOf[NameType] -} \ No newline at end of file diff --git a/src/compiler/scala/reflect/macros/runtime/Parsers.scala b/src/compiler/scala/reflect/macros/runtime/Parsers.scala deleted file mode 100644 index 566bcde73d..0000000000 --- a/src/compiler/scala/reflect/macros/runtime/Parsers.scala +++ /dev/null @@ -1,24 +0,0 @@ -package scala.reflect.macros -package runtime - -import scala.language.existentials -import scala.tools.reflect.ToolBox -import scala.tools.reflect.ToolBoxError - -trait Parsers { - self: Context => - - def parse(code: String): Tree = - // todo. provide decent implementation - // see `Typers.typedUseCase` for details - try { - import scala.reflect.runtime.{universe => ru} - val parsed = ru.rootMirror.mkToolBox().parse(code) - val importer = universe.mkImporter(ru) - importer.importTree(parsed) - } catch { - case ToolBoxError(msg, cause) => - // todo. provide a position - throw new ParseException(universe.NoPosition, msg) - } -} diff --git a/src/compiler/scala/reflect/macros/runtime/Reifiers.scala b/src/compiler/scala/reflect/macros/runtime/Reifiers.scala deleted file mode 100644 index 7ec3457c6a..0000000000 --- a/src/compiler/scala/reflect/macros/runtime/Reifiers.scala +++ /dev/null @@ -1,77 +0,0 @@ -/* NSC -- new Scala compiler - * Copyright 2005-2013 LAMP/EPFL - * @author Gilles Dubochet - */ - -package scala.reflect.macros -package runtime - -trait Reifiers { - self: Context => - - val global: universe.type = universe - import universe._ - import definitions._ - - def reifyTree(universe: Tree, mirror: Tree, tree: Tree): Tree = { - assert(ExprClass != NoSymbol) - val result = scala.reflect.reify.`package`.reifyTree(self.universe)(callsiteTyper, universe, mirror, tree) - logFreeVars(enclosingPosition, result) - result - } - - def reifyType(universe: Tree, mirror: Tree, tpe: Type, concrete: Boolean = false): Tree = { - assert(TypeTagsClass != NoSymbol) - val result = scala.reflect.reify.`package`.reifyType(self.universe)(callsiteTyper, universe, mirror, tpe, concrete) - logFreeVars(enclosingPosition, result) - result - } - - def reifyRuntimeClass(tpe: Type, concrete: Boolean = true): Tree = - scala.reflect.reify.`package`.reifyRuntimeClass(universe)(callsiteTyper, tpe, concrete = concrete) - - def reifyEnclosingRuntimeClass: Tree = - scala.reflect.reify.`package`.reifyEnclosingRuntimeClass(universe)(callsiteTyper) - - def unreifyTree(tree: Tree): Tree = { - assert(ExprSplice != NoSymbol) - Select(tree, ExprSplice) - } - - // fixme: if I put utils here, then "global" from utils' early initialization syntax - // and "global" that comes from here conflict with each other when incrementally compiling - // the problem is that both are pickled with the same owner - trait Reifiers - // and this upsets the compiler, so that oftentimes it throws assertion failures - // Martin knows the details - // - // object utils extends { - // val global: self.global.type = self.global - // val typer: global.analyzer.Typer = self.callsiteTyper - // } with scala.reflect.reify.utils.Utils - // import utils._ - - private def logFreeVars(position: Position, reification: Tree): Unit = { - object utils extends { - val global: self.global.type = self.global - val typer: global.analyzer.Typer = self.callsiteTyper - } with scala.reflect.reify.utils.Utils - import utils._ - - def logFreeVars(symtab: SymbolTable): Unit = - // logging free vars only when they are untyped prevents avalanches of duplicate messages - symtab.syms map (sym => symtab.symDef(sym)) foreach { - case FreeTermDef(_, _, binding, _, origin) if universe.settings.logFreeTerms && binding.tpe == null => - reporter.echo(position, "free term: %s %s".format(showRaw(binding), origin)) - case FreeTypeDef(_, _, binding, _, origin) if universe.settings.logFreeTypes && binding.tpe == null => - reporter.echo(position, "free type: %s %s".format(showRaw(binding), origin)) - case _ => - // do nothing - } - - if (universe.settings.logFreeTerms || universe.settings.logFreeTypes) - reification match { - case ReifiedTree(_, _, symtab, _, _, _, _) => logFreeVars(symtab) - case ReifiedType(_, _, symtab, _, _, _) => logFreeVars(symtab) - } - } -} diff --git a/src/compiler/scala/reflect/macros/runtime/ScalaReflectionRuntimes.scala b/src/compiler/scala/reflect/macros/runtime/ScalaReflectionRuntimes.scala new file mode 100644 index 0000000000..1999e525ff --- /dev/null +++ b/src/compiler/scala/reflect/macros/runtime/ScalaReflectionRuntimes.scala @@ -0,0 +1,33 @@ +package scala.reflect.macros +package runtime + +import scala.reflect.runtime.{universe => ru} + +trait ScalaReflectionRuntimes { + self: scala.tools.nsc.typechecker.Analyzer => + + trait ScalaReflectionResolvers { + self: MacroRuntimeResolver => + + import global._ + + def resolveScalaReflectionRuntime(classLoader: ClassLoader): MacroRuntime = { + val macroMirror: ru.JavaMirror = ru.runtimeMirror(classLoader) + val implContainerSym = macroMirror.classSymbol(Class.forName(className, true, classLoader)) + val implMethSym = implContainerSym.typeSignature.member(ru.TermName(methName)).asMethod + macroLogVerbose(s"successfully loaded macro impl as ($implContainerSym, $implMethSym)") + args => { + val implContainer = + if (isBundle) { + val implCtorSym = implContainerSym.typeSignature.member(ru.nme.CONSTRUCTOR).asMethod + macroMirror.reflectClass(implContainerSym).reflectConstructor(implCtorSym)(args.c) + } else { + macroMirror.reflectModule(implContainerSym.module.asModule).instance + } + val implMeth = macroMirror.reflect(implContainer).reflectMethod(implMethSym) + val implArgs = if (isBundle) args.others else args.c +: args.others + implMeth(implArgs: _*) + } + } + } +} diff --git a/src/compiler/scala/reflect/macros/runtime/Synthetics.scala b/src/compiler/scala/reflect/macros/runtime/Synthetics.scala deleted file mode 100644 index 1156769a80..0000000000 --- a/src/compiler/scala/reflect/macros/runtime/Synthetics.scala +++ /dev/null @@ -1,66 +0,0 @@ -/* NSC -- new Scala compiler - * Copyright 2005-2013 LAMP/EPFL - */ - -package scala.reflect.macros -package runtime - -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/reflect/macros/runtime/Traces.scala b/src/compiler/scala/reflect/macros/runtime/Traces.scala deleted file mode 100644 index 0238e9f84e..0000000000 --- a/src/compiler/scala/reflect/macros/runtime/Traces.scala +++ /dev/null @@ -1,8 +0,0 @@ -package scala.reflect.macros -package runtime - -trait Traces extends util.Traces { - self: Context => - - def globalSettings = universe.settings -} diff --git a/src/compiler/scala/reflect/macros/runtime/Typers.scala b/src/compiler/scala/reflect/macros/runtime/Typers.scala deleted file mode 100644 index f92d99a3f2..0000000000 --- a/src/compiler/scala/reflect/macros/runtime/Typers.scala +++ /dev/null @@ -1,52 +0,0 @@ -package scala.reflect.macros -package runtime - -import scala.reflect.internal.Mode - -trait Typers { - self: Context => - - def openMacros: List[Context] = this :: universe.analyzer.openMacros - - def openImplicits: List[ImplicitCandidate] = callsiteTyper.context.openImplicits.map(_.toImplicitCandidate) - - /** - * @see [[scala.tools.reflect.ToolBox.typeCheck]] - */ - def typeCheck(tree: Tree, pt: Type = universe.WildcardType, silent: Boolean = false, withImplicitViewsDisabled: Boolean = false, withMacrosDisabled: Boolean = false): Tree = { - macroLogVerbose("typechecking %s with expected type %s, implicit views = %s, macros = %s".format(tree, pt, !withImplicitViewsDisabled, !withMacrosDisabled)) - val context = callsiteTyper.context - val wrapper1 = if (!withImplicitViewsDisabled) (context.withImplicitsEnabled[Tree] _) else (context.withImplicitsDisabled[Tree] _) - val wrapper2 = if (!withMacrosDisabled) (context.withMacrosEnabled[Tree] _) else (context.withMacrosDisabled[Tree] _) - def wrapper (tree: => Tree) = wrapper1(wrapper2(tree)) - // if you get a "silent mode is not available past typer" here - // don't rush to change the typecheck not to use the silent method when the silent parameter is false - // typechecking uses silent anyways (e.g. in typedSelect), so you'll only waste your time - // I'd advise fixing the root cause: finding why the context is not set to report errors - // (also see reflect.runtime.ToolBoxes.typeCheckExpr for a workaround that might work for you) - wrapper(callsiteTyper.silent(_.typed(tree, pt), reportAmbiguousErrors = false) match { - case universe.analyzer.SilentResultValue(result) => - macroLogVerbose(result) - result - case error @ universe.analyzer.SilentTypeError(_) => - macroLogVerbose(error.err.errMsg) - if (!silent) throw new TypecheckException(error.err.errPos, error.err.errMsg) - universe.EmptyTree - }) - } - - def inferImplicitValue(pt: Type, silent: Boolean = true, withMacrosDisabled: Boolean = false, pos: Position = enclosingPosition): Tree = { - macroLogVerbose("inferring implicit value of type %s, macros = %s".format(pt, !withMacrosDisabled)) - universe.analyzer.inferImplicit(universe.EmptyTree, pt, false, callsiteTyper.context, silent, withMacrosDisabled, pos, (pos, msg) => throw TypecheckException(pos, msg)) - } - - def inferImplicitView(tree: Tree, from: Type, to: Type, silent: Boolean = true, withMacrosDisabled: Boolean = false, pos: Position = enclosingPosition): Tree = { - macroLogVerbose("inferring implicit view from %s to %s for %s, macros = %s".format(from, to, tree, !withMacrosDisabled)) - val viewTpe = universe.appliedType(universe.definitions.FunctionClass(1).toTypeConstructor, List(from, to)) - universe.analyzer.inferImplicit(tree, viewTpe, true, callsiteTyper.context, silent, withMacrosDisabled, pos, (pos, msg) => throw TypecheckException(pos, msg)) - } - - def resetAllAttrs(tree: Tree): Tree = universe.resetAllAttrs(tree) - - def resetLocalAttrs(tree: Tree): Tree = universe.resetLocalAttrs(tree) -} diff --git a/src/compiler/scala/reflect/macros/runtime/package.scala b/src/compiler/scala/reflect/macros/runtime/package.scala new file mode 100644 index 0000000000..9ef8200760 --- /dev/null +++ b/src/compiler/scala/reflect/macros/runtime/package.scala @@ -0,0 +1,5 @@ +package scala.reflect.macros + +package object runtime { + type Context = scala.reflect.macros.contexts.Context +} \ 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 9659134e5b..0bffe55403 100644 --- a/src/compiler/scala/reflect/reify/Taggers.scala +++ b/src/compiler/scala/reflect/reify/Taggers.scala @@ -1,7 +1,7 @@ package scala.reflect.reify import scala.reflect.macros.{ReificationException, UnexpectedReificationException, TypecheckException} -import scala.reflect.macros.runtime.Context +import scala.reflect.macros.contexts.Context abstract class Taggers { val c: Context diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala index 40f284c94c..8d650b3653 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala @@ -10,9 +10,10 @@ import scala.reflect.ClassTag import scala.reflect.internal.util.Statistics import scala.reflect.macros.util._ import scala.util.control.ControlThrowable -import scala.reflect.macros.runtime.AbortMacroException +import scala.reflect.macros.runtime.{AbortMacroException, MacroRuntimes} import scala.reflect.runtime.{universe => ru} import scala.reflect.macros.compiler.DefaultMacroCompiler +import scala.tools.reflect.FastTrack /** * Code to deal with macros, namely with: @@ -39,7 +40,7 @@ import scala.reflect.macros.compiler.DefaultMacroCompiler * (Expr(elems)) * (TypeTag(Int)) */ -trait Macros extends scala.tools.reflect.FastTrack with Traces with Helpers { +trait Macros extends FastTrack with MacroRuntimes with Traces with Helpers { self: Analyzer => import global._ @@ -77,7 +78,7 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces with Helpers { * Includes a path to load the implementation via Java reflection, * and various accounting information necessary when composing an argument list for the reflective invocation. */ - private case class MacroImplBinding( + case class MacroImplBinding( // Is this macro impl a bundle (a trait extending Macro) or a vanilla def? val isBundle: Boolean, // Java class name of the class that contains the macro implementation @@ -99,9 +100,9 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces with Helpers { // these trees don't refer to a macro impl, so we can pickle them as is targs: List[Tree]) - private final val IMPLPARAM_TAG = 0 // actually it's zero and above, this is just a lower bound for >= checks - private final val IMPLPARAM_OTHER = -1 - private final val IMPLPARAM_EXPR = -2 + final val IMPLPARAM_TAG = 0 // actually it's zero and above, this is just a lower bound for >= checks + final val IMPLPARAM_OTHER = -1 + final val IMPLPARAM_EXPR = -2 /** Macro def -> macro impl bindings are serialized into a `macroImpl` annotation * with synthetic content that carries the payload described in `MacroImplBinding`. @@ -120,7 +121,7 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces with Helpers { * "versionFormat" = , * "className" = "Macros$")) */ - private object MacroImplBinding { + object MacroImplBinding { val versionFormat = 3 def pickleAtom(obj: Any): Tree = @@ -220,12 +221,12 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces with Helpers { } } - private def bindMacroImpl(macroDef: Symbol, macroImplRef: Tree): Unit = { + def bindMacroImpl(macroDef: Symbol, macroImplRef: Tree): Unit = { val pickle = MacroImplBinding.pickle(macroImplRef) macroDef withAnnotation AnnotationInfo(MacroImplAnnotation.tpe, List(pickle), Nil) } - private def loadMacroImplBinding(macroDef: Symbol): MacroImplBinding = { + def loadMacroImplBinding(macroDef: Symbol): MacroImplBinding = { val Some(AnnotationInfo(_, List(pickle), _)) = macroDef.getAnnotation(MacroImplAnnotation) MacroImplBinding.unpickle(pickle) } @@ -309,73 +310,7 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces with Helpers { } } - /** Macro classloader that is used to resolve and run macro implementations. - * Loads classes from from -cp (aka the library classpath). - * Is also capable of detecting REPL and reusing its classloader. - */ - lazy val macroClassloader: ClassLoader = findMacroClassLoader() - - /** Reflective mirror built from `macroClassloader`. - */ - private lazy val macroMirror: ru.JavaMirror = ru.runtimeMirror(macroClassloader) - - /** Produces a function that can be used to invoke macro implementation for a given macro definition: - * 1) Looks up macro implementation symbol in this universe. - * 2) Loads its enclosing class from the macro classloader. - * 3) Loads the companion of that enclosing class from the macro classloader. - * 4) Resolves macro implementation within the loaded companion. - * - * @return Requested runtime if macro implementation can be loaded successfully from either of the mirrors, - * `null` otherwise. - */ - type MacroRuntime = MacroArgs => Any - private val macroRuntimesCache = perRunCaches.newWeakMap[Symbol, MacroRuntime]() - private def macroRuntime(macroDef: Symbol): MacroRuntime = { - macroLogVerbose(s"looking for macro implementation: $macroDef") - if (fastTrack contains macroDef) { - macroLogVerbose("macro expansion is serviced by a fast track") - fastTrack(macroDef) - } else { - macroRuntimesCache.getOrElseUpdate(macroDef, { - val binding = loadMacroImplBinding(macroDef) - val isBundle = binding.isBundle - val className = binding.className - val methName = binding.methName - macroLogVerbose(s"resolved implementation as $className.$methName") - - if (binding.className == Predef_???.owner.javaClassName && binding.methName == Predef_???.name.encoded) { - args => throw new AbortMacroException(args.c.enclosingPosition, "macro implementation is missing") - } else { - try { - macroLogVerbose(s"loading implementation class: $className") - macroLogVerbose(s"classloader is: ${ReflectionUtils.show(macroClassloader)}") - val implContainerSym = macroMirror.classSymbol(Class.forName(className, true, macroClassloader)) - val implMethSym = implContainerSym.typeSignature.member(ru.TermName(methName)).asMethod - macroLogVerbose(s"successfully loaded macro impl as ($implContainerSym, $implMethSym)") - args => { - val implContainer = - if (isBundle) { - val implCtorSym = implContainerSym.typeSignature.member(ru.nme.CONSTRUCTOR).asMethod - macroMirror.reflectClass(implContainerSym).reflectConstructor(implCtorSym)(args.c) - } else { - macroMirror.reflectModule(implContainerSym.module.asModule).instance - } - val implMeth = macroMirror.reflect(implContainer).reflectMethod(implMethSym) - val implArgs = if (isBundle) args.others else args.c +: args.others - implMeth(implArgs: _*) - } - } catch { - case ex: Exception => - macroLogVerbose(s"macro runtime failed to load: ${ex.toString}") - macroDef setFlag IS_ERROR - null - } - } - }) - } - } - - private def macroContext(typer: Typer, prefixTree: Tree, expandeeTree: Tree): MacroContext = { + def macroContext(typer: Typer, prefixTree: Tree, expandeeTree: Tree): MacroContext = { new { val universe: self.global.type = self.global val callsiteTyper: universe.analyzer.Typer = typer.asInstanceOf[global.analyzer.Typer] diff --git a/src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala b/src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala index a208924acb..c616ded704 100644 --- a/src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala +++ b/src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala @@ -10,7 +10,7 @@ trait StdAttachments { * At times we need to store this info, because macro expansion can be delayed until its targs are inferred. * After a macro application has been successfully expanded, this attachment is destroyed. */ - type UnaffiliatedMacroContext = scala.reflect.macros.runtime.Context + type UnaffiliatedMacroContext = scala.reflect.macros.contexts.Context type MacroContext = UnaffiliatedMacroContext { val universe: self.global.type } case class MacroRuntimeAttachment(delayed: Boolean, typerContext: Context, macroContext: Option[MacroContext]) diff --git a/src/compiler/scala/tools/reflect/MacroImplementations.scala b/src/compiler/scala/tools/reflect/MacroImplementations.scala index 109c148b7e..8e1bcb5f87 100644 --- a/src/compiler/scala/tools/reflect/MacroImplementations.scala +++ b/src/compiler/scala/tools/reflect/MacroImplementations.scala @@ -1,6 +1,6 @@ package scala.tools.reflect -import scala.reflect.macros.runtime.Context +import scala.reflect.macros.contexts.Context import scala.collection.mutable.ListBuffer import scala.collection.mutable.Stack import scala.reflect.internal.util.OffsetPosition -- cgit v1.2.3 From 363230a1a3882909936b5f32b97d590357b26bc6 Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Mon, 27 May 2013 23:02:06 +0200 Subject: changes some definitions to use Symbol.map --- .../scala/reflect/internal/Definitions.scala | 50 +++++++++++----------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/src/reflect/scala/reflect/internal/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala index 5478c54eec..1b46d9e00b 100644 --- a/src/reflect/scala/reflect/internal/Definitions.scala +++ b/src/reflect/scala/reflect/internal/Definitions.scala @@ -491,8 +491,8 @@ trait Definitions extends api.StandardDefinitions { lazy val ReflectPackage = requiredModule[scala.reflect.`package`.type] lazy val ReflectApiPackage = getPackageObjectIfDefined("scala.reflect.api") // defined in scala-reflect.jar, so we need to be careful 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 + def ReflectRuntimeUniverse = ReflectRuntimePackage.map(sym => getMemberValue(sym, nme.universe)) + def ReflectRuntimeCurrentMirror = ReflectRuntimePackage.map(sym => getMemberMethod(sym, nme.currentMirror)) lazy val PartialManifestClass = getTypeMember(ReflectPackage, tpnme.ClassManifest) lazy val PartialManifestModule = requiredModule[scala.reflect.ClassManifestFactory.type] @@ -502,16 +502,16 @@ trait Definitions extends api.StandardDefinitions { lazy val NoManifest = requiredModule[scala.reflect.NoManifest.type] lazy val TreesClass = getClassIfDefined("scala.reflect.api.Trees") // defined in scala-reflect.jar, so we need to be careful - lazy val TreesTreeType = if (TreesClass != NoSymbol) getTypeMember(TreesClass, tpnme.Tree) else NoSymbol + lazy val TreesTreeType = TreesClass.map(sym => getTypeMember(sym, tpnme.Tree)) object TreeType { def unapply(tpe: Type): Boolean = unapply(tpe.typeSymbol) def unapply(sym: Symbol): Boolean = sym.overrideChain contains TreesTreeType } 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 ExprClass = ExprsClass.map(sym => getMemberClass(sym, tpnme.Expr)) + def ExprSplice = ExprClass.map(sym => getMemberMethod(sym, nme.splice)) + def ExprValue = ExprClass.map(sym => getMemberMethod(sym, nme.value)) object ExprClassOf { def unapply(tpe: Type): Option[Type] = tpe.dealias match { case ExistentialType(_, underlying) => unapply(underlying) @@ -523,16 +523,16 @@ trait Definitions extends api.StandardDefinitions { lazy val ClassTagModule = requiredModule[scala.reflect.ClassTag[_]] lazy val ClassTagClass = requiredClass[scala.reflect.ClassTag[_]] lazy val TypeTagsClass = getClassIfDefined("scala.reflect.api.TypeTags") // defined in scala-reflect.jar, so we need to be careful - lazy val WeakTypeTagClass = if (TypeTagsClass != NoSymbol) getMemberClass(TypeTagsClass, tpnme.WeakTypeTag) else NoSymbol - lazy val WeakTypeTagModule = if (TypeTagsClass != NoSymbol) getMemberModule(TypeTagsClass, nme.WeakTypeTag) else NoSymbol - lazy val TypeTagClass = if (TypeTagsClass != NoSymbol) getMemberClass(TypeTagsClass, tpnme.TypeTag) else NoSymbol - lazy val TypeTagModule = if (TypeTagsClass != NoSymbol) getMemberModule(TypeTagsClass, nme.TypeTag) else NoSymbol + lazy val WeakTypeTagClass = TypeTagsClass.map(sym => getMemberClass(sym, tpnme.WeakTypeTag)) + lazy val WeakTypeTagModule = TypeTagsClass.map(sym => getMemberModule(sym, nme.WeakTypeTag)) + lazy val TypeTagClass = TypeTagsClass.map(sym => getMemberClass(sym, tpnme.TypeTag)) + lazy val TypeTagModule = TypeTagsClass.map(sym => getMemberModule(sym, nme.TypeTag)) def materializeClassTag = getMemberMethod(ReflectPackage, nme.materializeClassTag) - def materializeWeakTypeTag = if (ReflectApiPackage != NoSymbol) getMemberMethod(ReflectApiPackage, nme.materializeWeakTypeTag) else NoSymbol - def materializeTypeTag = if (ReflectApiPackage != NoSymbol) getMemberMethod(ReflectApiPackage, nme.materializeTypeTag) else NoSymbol + def materializeWeakTypeTag = ReflectApiPackage.map(sym => getMemberMethod(sym, nme.materializeWeakTypeTag)) + def materializeTypeTag = ReflectApiPackage.map(sym => getMemberMethod(sym, nme.materializeTypeTag)) 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 + def ApiUniverseReify = ApiUniverseClass.map(sym => getMemberMethod(sym, nme.reify)) lazy val JavaUniverseClass = getClassIfDefined("scala.reflect.api.JavaUniverse") // defined in scala-reflect.jar, so we need to be careful lazy val MirrorClass = getClassIfDefined("scala.reflect.api.Mirror") // defined in scala-reflect.jar, so we need to be careful @@ -540,18 +540,18 @@ trait Definitions extends api.StandardDefinitions { lazy val TypeCreatorClass = getClassIfDefined("scala.reflect.api.TypeCreator") // defined in scala-reflect.jar, so we need to be careful lazy val TreeCreatorClass = getClassIfDefined("scala.reflect.api.TreeCreator") // defined in scala-reflect.jar, so we need to be careful - lazy val MacroClass = getClassIfDefined("scala.reflect.macros.Macro") // defined in scala-reflect.jar, so we need to be careful - lazy val MacroContextClass = getClassIfDefined("scala.reflect.macros.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) getTypeMember(MacroContextClass, tpnme.PrefixType) else NoSymbol - def MacroContextUniverse = if (MacroContextClass != NoSymbol) getMemberMethod(MacroContextClass, nme.universe) else NoSymbol - def MacroContextExprClass = if (MacroContextClass != NoSymbol) getTypeMember(MacroContextClass, tpnme.Expr) else NoSymbol - def MacroContextWeakTypeTagClass = if (MacroContextClass != NoSymbol) getTypeMember(MacroContextClass, tpnme.WeakTypeTag) else NoSymbol - def MacroContextTreeType = if (MacroContextClass != NoSymbol) getTypeMember(MacroContextClass, tpnme.Tree) else NoSymbol - lazy val MacroImplAnnotation = requiredClass[scala.reflect.macros.internal.macroImpl] - - lazy val StringContextClass = requiredClass[scala.StringContext] - def StringContext_f = getMemberMethod(StringContextClass, nme.f) + lazy val MacroClass = getClassIfDefined("scala.reflect.macros.Macro") // defined in scala-reflect.jar, so we need to be careful + lazy val MacroContextClass = getClassIfDefined("scala.reflect.macros.Context") // defined in scala-reflect.jar, so we need to be careful + def MacroContextPrefix = MacroContextClass.map(sym => getMemberMethod(sym, nme.prefix)) + def MacroContextPrefixType = MacroContextClass.map(sym => getTypeMember(sym, tpnme.PrefixType)) + def MacroContextUniverse = MacroContextClass.map(sym => getMemberMethod(sym, nme.universe)) + def MacroContextExprClass = MacroContextClass.map(sym => getTypeMember(sym, tpnme.Expr)) + def MacroContextWeakTypeTagClass = MacroContextClass.map(sym => getTypeMember(sym, tpnme.WeakTypeTag)) + def MacroContextTreeType = MacroContextClass.map(sym => getTypeMember(sym, tpnme.Tree)) + lazy val MacroImplAnnotation = requiredClass[scala.reflect.macros.internal.macroImpl] + + lazy val StringContextClass = requiredClass[scala.StringContext] + def StringContext_f = getMemberMethod(StringContextClass, nme.f) lazy val ScalaSignatureAnnotation = requiredClass[scala.reflect.ScalaSignature] lazy val ScalaLongSignatureAnnotation = requiredClass[scala.reflect.ScalaLongSignature] -- cgit v1.2.3 From d5bfbd597e5fd4707b322c8bc13fd57f084ff1e4 Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Mon, 27 May 2013 23:07:03 +0200 Subject: applying Jason's aesthetics suggestion --- src/compiler/scala/tools/nsc/typechecker/Macros.scala | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala index 8d650b3653..baef84bc8e 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala @@ -98,7 +98,11 @@ trait Macros extends FastTrack with MacroRuntimes with Traces with Helpers { signature: List[List[Int]], // type arguments part of a macro impl ref (the right-hand side of a macro definition) // these trees don't refer to a macro impl, so we can pickle them as is - targs: List[Tree]) + targs: List[Tree]) { + + // Was this binding derived from a `def ... = macro ???` definition? + def is_??? = className == Predef_???.owner.javaClassName && methName == Predef_???.name.encoded + } final val IMPLPARAM_TAG = 0 // actually it's zero and above, this is just a lower bound for >= checks final val IMPLPARAM_OTHER = -1 @@ -353,9 +357,7 @@ trait Macros extends FastTrack with MacroRuntimes with Traces with Helpers { else MacroTooFewArgumentListsError(expandee) } else { - val binding = loadMacroImplBinding(macroDef) - if (binding.className == Predef_???.owner.javaClassName && binding.methName == Predef_???.name.encoded) Nil - else { + def calculateMacroArgs(binding: MacroImplBinding) = { val signature = if (binding.isBundle) binding.signature else binding.signature.tail macroLogVerbose(s"binding: $binding") @@ -427,6 +429,10 @@ trait Macros extends FastTrack with MacroRuntimes with Traces with Helpers { // that's because macro impls can't have implicit parameters other than c.WeakTypeTag[T] (trees :+ tags).flatten } + + val binding = loadMacroImplBinding(macroDef) + if (binding.is_???) Nil + else calculateMacroArgs(binding) } macroLogVerbose(s"macroImplArgs: $macroImplArgs") MacroArgs(context, macroImplArgs) -- cgit v1.2.3 From b136b42d43a8d745848e58a4dbba57d866bdc2cc Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Tue, 28 May 2013 11:06:43 +0200 Subject: more refactoring and explanations in importers --- src/reflect/scala/reflect/internal/Importers.scala | 102 +++++++++++---------- 1 file changed, 54 insertions(+), 48 deletions(-) diff --git a/src/reflect/scala/reflect/internal/Importers.scala b/src/reflect/scala/reflect/internal/Importers.scala index ae1c2a9a77..f8584ac9b0 100644 --- a/src/reflect/scala/reflect/internal/Importers.scala +++ b/src/reflect/scala/reflect/internal/Importers.scala @@ -59,17 +59,28 @@ trait Importers extends api.Importers { to: SymbolTable => // ============== SYMBOLS ============== - protected def recreatedSymbolCompleter(their: from.Symbol) = { - val mytypeParams = their.typeParams map importSymbol - new LazyPolyType(mytypeParams) with FlagAgnosticCompleter { - override def complete(my: to.Symbol): Unit = { - val theirCore = their.info match { - case from.PolyType(_, core) => core - case core => core + protected def recreatedSymbolCompleter(my: to.Symbol, their: from.Symbol) = { + // we lock the symbol that is imported for a very short period of time + // i.e. only for when type parameters of the symbol are being imported + // the lock is used to communicate to the recursive importSymbol calls + // that type parameters need to be created from scratch + // because otherwise type parameters are imported by looking into owner.typeParams + // which is obviously unavailable while the completer is being created + try { + my setFlag Flags.LOCKED + val mytypeParams = their.typeParams map importSymbol + new LazyPolyType(mytypeParams) with FlagAgnosticCompleter { + override def complete(my: to.Symbol): Unit = { + val theirCore = their.info match { + case from.PolyType(_, core) => core + case core => core + } + my setInfo GenPolyType(mytypeParams, importType(theirCore)) + my setAnnotations (their.annotations map importAnnotationInfo) } - my setInfo GenPolyType(mytypeParams, importType(theirCore)) - my setAnnotations (their.annotations map importAnnotationInfo) } + } finally { + my resetFlag Flags.LOCKED } } @@ -121,9 +132,7 @@ trait Importers extends api.Importers { to: SymbolTable => myowner.newTypeSymbol(myname.toTypeName, mypos, myflags) } symMap.weakUpdate(their, my) - my setFlag Flags.LOCKED - my setInfo recreatedSymbolCompleter(their) - my resetFlag Flags.LOCKED + my setInfo recreatedSymbolCompleter(my, their) } def importSymbol(their0: from.Symbol): Symbol = { @@ -142,53 +151,50 @@ trait Importers extends api.Importers { to: SymbolTable => else if (their.isRoot) rootMirror.RootClass // !!! replace with actual mirror when we move importers to the mirror else { + val isModuleClass = their.isModuleClass + val isTparam = their.isTypeParameter && their.paramPos >= 0 + val isOverloaded = their.isOverloaded + var theirscope = if (their.owner.isClass && !their.owner.isRefinementClass) their.owner.info else from.NoType - var theirexisting = theirscope.decl(their.name) - if (their.isModuleClass) theirexisting = theirexisting.moduleClass + val theirexisting = if (isModuleClass) theirscope.decl(their.name).moduleClass else theirscope.decl(their.name) if (!theirexisting.exists) theirscope = from.NoType val myname = importName(their.name) val myowner = importSymbol(their.owner) val myscope = if (theirscope != from.NoType && !(myowner hasFlag Flags.LOCKED)) myowner.info else NoType - var myexisting = if (myscope != NoType) myscope.decl(myname) else NoSymbol // cannot load myexisting in general case, because it creates cycles for methods - - if (their.isModuleClass) - myexisting = importSymbol(their.sourceModule).moduleClass - - if (!their.isOverloaded && myexisting.isOverloaded) { - myexisting = - if (their.isMethod) { - val localCopy = cachedRecreateSymbol(their) - myexisting filter (_.tpe matches localCopy.tpe) - } else { - myexisting filter (!_.isMethod) + val myexisting = { + if (isModuleClass) importSymbol(their.sourceModule).moduleClass + else if (isTparam) (if (myowner hasFlag Flags.LOCKED) NoSymbol else myowner.typeParams(their.paramPos)) + else if (isOverloaded) myowner.newOverloaded(myowner.thisType, their.alternatives map importSymbol) + else { + def disambiguate(my: Symbol) = { + val result = + if (their.isMethod) { + val localCopy = cachedRecreateSymbol(their) + my filter (_.tpe matches localCopy.tpe) + } else { + my filter (!_.isMethod) + } + assert(!result.isOverloaded, + "import failure: cannot determine unique overloaded method alternative from\n "+ + (result.alternatives map (_.defString) mkString "\n")+"\n that matches "+their+":"+their.tpe) + result } - assert(!myexisting.isOverloaded, - "import failure: cannot determine unique overloaded method alternative from\n "+ - (myexisting.alternatives map (_.defString) mkString "\n")+"\n that matches "+their+":"+their.tpe) + + val myexisting = if (myscope != NoType) myscope.decl(myname) else NoSymbol + if (myexisting.isOverloaded) disambiguate(myexisting) + else myexisting + } } - val my = { - if (their.isOverloaded) { - myowner.newOverloaded(myowner.thisType, their.alternatives map importSymbol) - } else if (their.isTypeParameter && their.paramPos >= 0 && !(myowner hasFlag Flags.LOCKED)) { - assert(myowner.typeParams.length > their.paramPos, - "import failure: cannot determine parameter "+their+" (#"+their.paramPos+") in "+ - myowner+typeParamsString(myowner.rawInfo)+"\n original symbol was: "+ - their.owner+from.typeParamsString(their.owner.info)) - myowner.typeParams(their.paramPos) - } else { - myexisting.orElse { - val my = cachedRecreateSymbol(their) - if (myscope != NoType) { - assert(myscope.decls.lookup(myname) == NoSymbol, myname+" "+myscope.decl(myname)+" "+myexisting) - myscope.decls enter my - } - my - } + myexisting.orElse { + val my = cachedRecreateSymbol(their) + if (myscope != NoType) { + assert(myscope.decls.lookup(myname) == NoSymbol, myname+" "+myscope.decl(myname)+" "+myexisting) + myscope.decls enter my } + my } - my } } // end recreateOrRelink -- cgit v1.2.3 From 82f0925b69db8b5f9a3b10f58926c574433ca423 Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Tue, 28 May 2013 11:42:33 +0200 Subject: refactors IMPLPARAM_xxx constants into value classes --- .../scala/tools/nsc/typechecker/Macros.scala | 76 +++++++++++++++------- src/library/scala/runtime/ScalaRunTime.scala | 13 ++++ 2 files changed, 66 insertions(+), 23 deletions(-) diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala index baef84bc8e..6c4d1e20aa 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala @@ -14,6 +14,8 @@ import scala.reflect.macros.runtime.{AbortMacroException, MacroRuntimes} import scala.reflect.runtime.{universe => ru} import scala.reflect.macros.compiler.DefaultMacroCompiler import scala.tools.reflect.FastTrack +import scala.runtime.ScalaRunTime +import Fingerprint._ /** * Code to deal with macros, namely with: @@ -94,8 +96,8 @@ trait Macros extends FastTrack with MacroRuntimes with Traces with Helpers { // * c.WeakTypeTag[T] => index of the type parameter corresponding to that type tag // * everything else (e.g. scala.reflect.macros.Context) => IMPLPARAM_OTHER // f.ex. for: def impl[T: WeakTypeTag, U, V: WeakTypeTag](c: Context)(x: c.Expr[T], y: c.Tree): (U, V) = ??? - // `signature` will be equal to List(List(-1), List(-1, -2), List(0, 2)) - signature: List[List[Int]], + // `signature` will be equal to List(List(Other), List(Lifted, Other), List(Tagged(0), Tagged(2))) + signature: List[List[Fingerprint]], // type arguments part of a macro impl ref (the right-hand side of a macro definition) // these trees don't refer to a macro impl, so we can pickle them as is targs: List[Tree]) { @@ -104,10 +106,6 @@ trait Macros extends FastTrack with MacroRuntimes with Traces with Helpers { def is_??? = className == Predef_???.owner.javaClassName && methName == Predef_???.name.encoded } - final val IMPLPARAM_TAG = 0 // actually it's zero and above, this is just a lower bound for >= checks - final val IMPLPARAM_OTHER = -1 - final val IMPLPARAM_EXPR = -2 - /** Macro def -> macro impl bindings are serialized into a `macroImpl` annotation * with synthetic content that carries the payload described in `MacroImplBinding`. * @@ -120,28 +118,30 @@ trait Macros extends FastTrack with MacroRuntimes with Traces with Helpers { * @scala.reflect.macros.internal.macroImpl( * `macro`( * "isBundle" = false, - * "signature" = List(-1), + * "signature" = List(Other), * "methodName" = "impl", * "versionFormat" = , * "className" = "Macros$")) */ object MacroImplBinding { - val versionFormat = 3 + val versionFormat = 4.0 def pickleAtom(obj: Any): Tree = obj match { case list: List[_] => Apply(Ident(ListModule), list map pickleAtom) case s: String => Literal(Constant(s)) - case i: Int => Literal(Constant(i)) + case d: Double => Literal(Constant(d)) case b: Boolean => Literal(Constant(b)) + case f: Fingerprint => Literal(Constant(f.value)) } def unpickleAtom(tree: Tree): Any = tree match { case Apply(list @ Ident(_), args) if list.symbol == ListModule => args map unpickleAtom case Literal(Constant(s: String)) => s - case Literal(Constant(i: Int)) => i + case Literal(Constant(d: Double)) => d case Literal(Constant(b: Boolean)) => b + case Literal(Constant(i: Int)) => new Fingerprint(i) } def pickle(macroImplRef: Tree): Tree = { @@ -161,15 +161,15 @@ trait Macros extends FastTrack with MacroRuntimes with Traces with Helpers { loop(owner) } - def signature: List[List[Int]] = { - def fingerprint(tpe: Type): Int = tpe.dealiasWiden match { + def signature: List[List[Fingerprint]] = { + def fingerprint(tpe: Type): Fingerprint = tpe.dealiasWiden match { case TypeRef(_, RepeatedParamClass, underlying :: Nil) => fingerprint(underlying) - case ExprClassOf(_) => IMPLPARAM_EXPR - case _ => IMPLPARAM_OTHER + case ExprClassOf(_) => Lifted + case _ => Other } val transformed = transformTypeTagEvidenceParams(macroImplRef, (param, tparam) => tparam) - mmap(transformed)(p => if (p.isTerm) fingerprint(p.info) else p.paramPos) + mmap(transformed)(p => if (p.isTerm) fingerprint(p.info) else Tagged(p.paramPos)) } val payload = List[(String, Any)]( @@ -214,13 +214,25 @@ trait Macros extends FastTrack with MacroRuntimes with Traces with Helpers { val Apply(_, pickledPayload) = wrapped val payload = pickledPayload.map{ case Assign(k, v) => (unpickleAtom(k), unpickleAtom(v)) }.toMap - val pickleVersionFormat = payload("versionFormat").asInstanceOf[Int] - if (versionFormat != pickleVersionFormat) throw new Error(s"macro impl binding format mismatch: expected $versionFormat, actual $pickleVersionFormat") + def fail(msg: String) = abort(s"bad macro impl binding: $msg") + def unpickle[T](field: String, clazz: Class[T]): T = { + def failField(msg: String) = fail(s"$field $msg") + if (!payload.contains(field)) failField("is supposed to be there") + val raw: Any = payload(field) + if (raw == null) failField(s"is not supposed to be null") + val expected = ScalaRunTime.box(clazz) + val actual = raw.getClass + if (!expected.isAssignableFrom(actual)) failField(s"has wrong type: expected $expected, actual $actual") + raw.asInstanceOf[T] + } + + val pickleVersionFormat = unpickle("versionFormat", classOf[Double]) + if (versionFormat != pickleVersionFormat) fail(s"expected version format $versionFormat, actual $pickleVersionFormat") - val isBundle = payload("isBundle").asInstanceOf[Boolean] - val className = payload("className").asInstanceOf[String] - val methodName = payload("methodName").asInstanceOf[String] - val signature = payload("signature").asInstanceOf[List[List[Int]]] + val isBundle = unpickle("isBundle", classOf[Boolean]) + val className = unpickle("className", classOf[String]) + val methodName = unpickle("methodName", classOf[String]) + val signature = unpickle("signature", classOf[List[List[Fingerprint]]]) MacroImplBinding(isBundle, className, methodName, signature, targs) } } @@ -376,7 +388,7 @@ trait Macros extends FastTrack with MacroRuntimes with Traces with Helpers { val wrappedArgs = mapWithIndex(args)((arg, j) => { val fingerprint = implParams(min(j, implParams.length - 1)) fingerprint match { - case IMPLPARAM_EXPR => context.Expr[Nothing](arg)(TypeTag.Nothing) // TODO: SI-5752 + case Lifted => context.Expr[Nothing](arg)(TypeTag.Nothing) // TODO: SI-5752 case _ => abort(s"unexpected fingerprint $fingerprint in $binding with paramss being $paramss " + s"corresponding to arg $arg in $argss") } @@ -406,7 +418,7 @@ trait Macros extends FastTrack with MacroRuntimes with Traces with Helpers { // then T and U need to be inferred from the lexical scope of the call using `asSeenFrom` // whereas V won't be resolved by asSeenFrom and need to be loaded directly from `expandee` which needs to contain a TypeApply node // also, macro implementation reference may contain a regular type as a type argument, then we pass it verbatim - val tags = signature.flatten filter (_ >= IMPLPARAM_TAG) map (paramPos => { + val tags = signature.flatten collect { case f if f.isTag => f.paramPos } map (paramPos => { val targ = binding.targs(paramPos).tpe.typeSymbol val tpe = if (targ.isTypeParameterOrSkolem) { if (targ.owner == macroDef) { @@ -787,3 +799,21 @@ object MacrosStats { val macroExpandCount = Statistics.newCounter ("#macro expansions", "typer") val macroExpandNanos = Statistics.newSubTimer("time spent in macroExpand", typerNanos) } + +class Fingerprint(val value: Int) extends AnyVal { + def paramPos = { assert(isTag, this); value } + def isTag = value >= 0 + def isOther = this == Other + def isExpr = this == Lifted + override def toString = this match { + case Other => "Other" + case Lifted => "Expr" + case _ => s"Tag($value)" + } +} + +object Fingerprint { + def Tagged(tparamPos: Int) = new Fingerprint(tparamPos) + val Other = new Fingerprint(-1) + val Lifted = new Fingerprint(-2) +} diff --git a/src/library/scala/runtime/ScalaRunTime.scala b/src/library/scala/runtime/ScalaRunTime.scala index ea1f392e2b..3a85207235 100644 --- a/src/library/scala/runtime/ScalaRunTime.scala +++ b/src/library/scala/runtime/ScalaRunTime.scala @@ -350,4 +350,17 @@ object ScalaRunTime { } } } + + def box[T](clazz: jClass[T]): jClass[_] = clazz match { + case java.lang.Byte.TYPE => classOf[java.lang.Byte] + case java.lang.Short.TYPE => classOf[java.lang.Short] + case java.lang.Character.TYPE => classOf[java.lang.Character] + case java.lang.Integer.TYPE => classOf[java.lang.Integer] + case java.lang.Long.TYPE => classOf[java.lang.Long] + case java.lang.Float.TYPE => classOf[java.lang.Float] + case java.lang.Double.TYPE => classOf[java.lang.Double] + case java.lang.Void.TYPE => classOf[scala.runtime.BoxedUnit] + case java.lang.Boolean.TYPE => classOf[java.lang.Boolean] + case _ => clazz + } } -- cgit v1.2.3