diff options
-rw-r--r-- | src/compiler/scala/tools/nsc/settings/ScalaSettings.scala | 8 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Macros.scala | 27 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala | 2 | ||||
-rw-r--r-- | src/interactive/scala/tools/nsc/interactive/Global.scala | 4 | ||||
-rw-r--r-- | test/files/presentation/hyperlinks-macro.check | 4 | ||||
-rw-r--r-- | test/files/presentation/hyperlinks-macro/src/MacroCall.scala | 1 | ||||
-rw-r--r-- | test/scaladoc/run/SI-6812.check | 1 | ||||
-rw-r--r-- | test/scaladoc/run/SI-6812.scala | 2 | ||||
-rw-r--r-- | test/scaladoc/run/SI-6812b.check | 1 | ||||
-rw-r--r-- | test/scaladoc/run/SI-6812b.scala | 24 |
10 files changed, 55 insertions, 19 deletions
diff --git a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala index 7568c789fb..1f9987c83b 100644 --- a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala +++ b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala @@ -172,7 +172,8 @@ trait ScalaSettings extends AbsScalaSettings val Yrangepos = BooleanSetting ("-Yrangepos", "Use range positions for syntax trees.") val Ymemberpos = StringSetting ("-Yshow-member-pos", "output style", "Show start and end positions of members", "") withPostSetHook (_ => Yrangepos.value = true) val Yreifycopypaste = BooleanSetting ("-Yreify-copypaste", "Dump the reified trees in copypasteable representation.") - val Ymacronoexpand = BooleanSetting ("-Ymacro-no-expand", "Don't expand macros. Might be useful for scaladoc and presentation compiler, but will crash anything which uses macros and gets past typer.") + val Ymacroexpand = ChoiceSetting ("-Ymacro-expand", "policy", "Control expansion of macros, useful for scaladoc and presentation compiler", List(MacroExpand.Normal, MacroExpand.None, MacroExpand.Discard), MacroExpand.Normal) + val Ymacronoexpand = BooleanSetting ("-Ymacro-no-expand", "Don't expand macros. Might be useful for scaladoc and presentation compiler, but will crash anything which uses macros and gets past typer.") withDeprecationMessage(s"Use ${Ymacroexpand.name}:${MacroExpand.None}") withPostSetHook(_ => Ymacroexpand.value = MacroExpand.None) val Yreplsync = BooleanSetting ("-Yrepl-sync", "Do not use asynchronous code for repl startup") val Yreplclassbased = BooleanSetting ("-Yrepl-class-based", "Use classes to wrap REPL snippets instead of objects") val Yreploutdir = StringSetting ("-Yrepl-outdir", "path", "Write repl-generated classfiles to given output directory (use \"\" to generate a temporary dir)" , "") @@ -249,4 +250,9 @@ trait ScalaSettings extends AbsScalaSettings def isBCodeAskedFor = (Ybackend.value != "GenASM") def isICodeAskedFor = ((Ybackend.value == "GenASM") || optimiseSettings.exists(_.value) || writeICode.isSetByUser) + object MacroExpand { + val None = "none" + val Normal = "normal" + val Discard = "discard" + } } diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala index c32b986d9c..c1a6ac32c9 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala @@ -535,25 +535,25 @@ trait Macros extends FastTrack with MacroRuntimes with Traces with Helpers { * the expandee with an error marker set if the expansion has been cancelled due malformed arguments or implementation * the expandee with an error marker set if there has been an error */ - abstract class MacroExpander[Result: ClassTag](val role: MacroRole, val typer: Typer, val expandee: Tree) { + abstract class MacroExpander(val role: MacroRole, val typer: Typer, val expandee: Tree) { def allowExpandee(expandee: Tree): Boolean = true def allowExpanded(expanded: Tree): Boolean = true def allowedExpansions: String = "anything" - def allowResult(result: Result): Boolean = true + def allowResult(result: Tree): Boolean = true - def onSuccess(expanded: Tree): Result - def onFallback(expanded: Tree): Result - def onSuppressed(expandee: Tree): Result = expandee match { case expandee: Result => expandee } - def onDelayed(expanded: Tree): Result = expanded match { case expanded: Result => expanded } - def onSkipped(expanded: Tree): Result = expanded match { case expanded: Result => expanded } - def onFailure(expanded: Tree): Result = { typer.infer.setError(expandee); expandee match { case expandee: Result => expandee } } + def onSuccess(expanded: Tree): Tree + def onFallback(expanded: Tree): Tree + def onSuppressed(expandee: Tree): Tree = expandee + def onDelayed(expanded: Tree): Tree = expanded + def onSkipped(expanded: Tree): Tree = expanded + def onFailure(expanded: Tree): Tree = { typer.infer.setError(expandee); expandee } - def apply(desugared: Tree): Result = { + def apply(desugared: Tree): Tree = { if (isMacroExpansionSuppressed(desugared)) onSuppressed(expandee) else expand(desugared) } - protected def expand(desugared: Tree): Result = { + protected def expand(desugared: Tree): Tree = { def showDetailed(tree: Tree) = showRaw(tree, printIds = true, printTypes = true) def summary() = s"expander = $this, expandee = ${showDetailed(expandee)}, desugared = ${if (expandee == desugared) () else showDetailed(desugared)}" if (macroDebugVerbose) println(s"macroExpand: ${summary()}") @@ -580,7 +580,10 @@ trait Macros extends FastTrack with MacroRuntimes with Traces with Helpers { // also see http://groups.google.com/group/scala-internals/browse_thread/thread/492560d941b315cc val expanded1 = try onSuccess(duplicateAndKeepPositions(expanded)) finally popMacroContext() if (!hasMacroExpansionAttachment(expanded1)) linkExpandeeAndExpanded(expandee, expanded1) - if (allowResult(expanded1)) expanded1 else onFailure(expanded) + if (allowResult(expanded1)) { + if (settings.Ymacroexpand.value == settings.MacroExpand.Discard) expandee.setType(expanded1.tpe) + else expanded1 + } else onFailure(expanded) } else { typer.TyperErrorGen.MacroInvalidExpansionError(expandee, role.name, allowedExpansions) onFailure(expanded) @@ -605,7 +608,7 @@ trait Macros extends FastTrack with MacroRuntimes with Traces with Helpers { * @param innerPt Expected type that comes from the signature of a macro def, possibly wildcarded to help type inference. */ class DefMacroExpander(typer: Typer, expandee: Tree, mode: Mode, outerPt: Type) - extends MacroExpander[Tree](APPLY_ROLE, typer, expandee) { + extends MacroExpander(APPLY_ROLE, typer, expandee) { lazy val innerPt = { val tp = if (isNullaryInvocation(expandee)) expandee.tpe.finalResultType else expandee.tpe if (isBlackbox(expandee)) tp diff --git a/src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala b/src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala index 14f47a00fd..70a3acbb6c 100644 --- a/src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala +++ b/src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala @@ -95,7 +95,7 @@ trait StdAttachments { /** Determines whether a tree should not be expanded, because someone has put SuppressMacroExpansionAttachment on it or one of its children. */ def isMacroExpansionSuppressed(tree: Tree): Boolean = - ( settings.Ymacronoexpand.value // SI-6812 + ( settings.Ymacroexpand.value == settings.MacroExpand.None // SI-6812 || tree.attachments.get[SuppressMacroExpansionAttachment.type].isDefined || (tree match { // we have to account for the fact that during typechecking an expandee might become wrapped, diff --git a/src/interactive/scala/tools/nsc/interactive/Global.scala b/src/interactive/scala/tools/nsc/interactive/Global.scala index 27f10ff00a..b55a573029 100644 --- a/src/interactive/scala/tools/nsc/interactive/Global.scala +++ b/src/interactive/scala/tools/nsc/interactive/Global.scala @@ -88,7 +88,6 @@ trait InteractiveAnalyzer extends Analyzer { } } - /** The main class of the presentation compiler in an interactive environment such as an IDE */ class Global(settings: Settings, _reporter: Reporter, projectName: String = "") extends { @@ -105,6 +104,9 @@ class Global(settings: Settings, _reporter: Reporter, projectName: String = "") import definitions._ + if (!settings.Ymacroexpand.isSetByUser) + settings.Ymacroexpand.value = settings.MacroExpand.Discard + val debugIDE: Boolean = settings.YpresentationDebug.value val verboseIDE: Boolean = settings.YpresentationVerbose.value diff --git a/test/files/presentation/hyperlinks-macro.check b/test/files/presentation/hyperlinks-macro.check index 39e66d1eca..80d2268fa1 100644 --- a/test/files/presentation/hyperlinks-macro.check +++ b/test/files/presentation/hyperlinks-macro.check @@ -1,8 +1,8 @@ reload: MacroCall.scala -askHyperlinkPos for `<local Test>` at (5,7) MacroCall.scala +askHyperlinkPos for `foo` at (5,7) MacroCall.scala ================================================================================ -[response] found askHyperlinkPos for `<local Test>` at (1,13) MacroCall.scala +[response] found askHyperlinkPos for `foo` at (2,7) MacroCall.scala ================================================================================ askHyperlinkPos for `foo` at (9,7) MacroCall.scala diff --git a/test/files/presentation/hyperlinks-macro/src/MacroCall.scala b/test/files/presentation/hyperlinks-macro/src/MacroCall.scala index 42685735b2..d9676b3d2a 100644 --- a/test/files/presentation/hyperlinks-macro/src/MacroCall.scala +++ b/test/files/presentation/hyperlinks-macro/src/MacroCall.scala @@ -9,4 +9,3 @@ object Test { foo/*#*/ } } -// Currently, the hyperlink within the argument to the macro `reify` does not resolve correctly. diff --git a/test/scaladoc/run/SI-6812.check b/test/scaladoc/run/SI-6812.check index 619c56180b..3be8a300e7 100644 --- a/test/scaladoc/run/SI-6812.check +++ b/test/scaladoc/run/SI-6812.check @@ -1 +1,2 @@ +warning: -Ymacro-no-expand is deprecated: Use -Ymacro-expand:none Done. diff --git a/test/scaladoc/run/SI-6812.scala b/test/scaladoc/run/SI-6812.scala index 059c327e7e..6893e816d0 100644 --- a/test/scaladoc/run/SI-6812.scala +++ b/test/scaladoc/run/SI-6812.scala @@ -19,6 +19,6 @@ object Test extends ScaladocModelTest { """ def scaladocSettings = "" - override def extraSettings = super.extraSettings + " -Ymacro-no-expand" + override def extraSettings = super.extraSettings + " -Ymacro-no-expand -deprecation" def testModel(root: Package) = () } diff --git a/test/scaladoc/run/SI-6812b.check b/test/scaladoc/run/SI-6812b.check new file mode 100644 index 0000000000..619c56180b --- /dev/null +++ b/test/scaladoc/run/SI-6812b.check @@ -0,0 +1 @@ +Done. diff --git a/test/scaladoc/run/SI-6812b.scala b/test/scaladoc/run/SI-6812b.scala new file mode 100644 index 0000000000..b8a8140357 --- /dev/null +++ b/test/scaladoc/run/SI-6812b.scala @@ -0,0 +1,24 @@ +import scala.tools.nsc.doc.model._ +import scala.tools.partest.ScaladocModelTest +import language._ + +object Test extends ScaladocModelTest { + + override def code = """ + import scala.reflect.macros.BlackboxContext + import language.experimental.macros + + object Macros { + def impl(c: BlackboxContext) = c.literalUnit + def foo: Unit = macro impl + } + + class C { + def bar = Macros.foo + } + """ + + def scaladocSettings = "" + override def extraSettings = super.extraSettings + " -Ymacro-expand:none" + def testModel(root: Package) = () +} |