diff options
Diffstat (limited to 'src/compiler/scala/tools/nsc')
3 files changed, 23 insertions, 14 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, |