summaryrefslogtreecommitdiff
path: root/src/compiler/scala
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler/scala')
-rw-r--r--src/compiler/scala/tools/nsc/settings/ScalaSettings.scala8
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Macros.scala27
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala2
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,