summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/typechecker/Macros.scala
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2013-12-17 10:36:26 +0100
committerEugene Burmako <xeno.by@gmail.com>2014-01-08 21:02:01 +0100
commit6e4c926b4a4c5e8dd350ae3a150490a794b139ca (patch)
tree45d8e1a893e30477ee71c358c0cba2a049883b83 /src/compiler/scala/tools/nsc/typechecker/Macros.scala
parentd744921f855a6c5d4f4df62895bc3b17b8e0e532 (diff)
downloadscala-6e4c926b4a4c5e8dd350ae3a150490a794b139ca.tar.gz
scala-6e4c926b4a4c5e8dd350ae3a150490a794b139ca.tar.bz2
scala-6e4c926b4a4c5e8dd350ae3a150490a794b139ca.zip
Use macro expandee, rather than expansion, in pres. compiler
The presentation compiler is primarily interested in trees that represent the code that one sees in the IDE, not the expansion of macros. This commit continues to expand macros, but adds a hook in which the presentation compiler discards the expansion, retaining instead the expandee. The expandee is attributed with the type of the expansion, which allows white box macros to work. In addition, any domain specific errors and warnings issued by the macro will still be reported, as a side-effect of the expansion. The failing test from the last commit now correctly resolves hyperlinks in macro arguments. Related IDE ticket: https://www.assembla.com/spaces/scala-ide/tickets/1001449# This facility is configured as follows: // expand macros as per normal -Ymacro-expand:normal // don't expand the macro, takes the place of -Ymacro-no-expand -Ymacro-expand:none // expand macros to compute type and emit warnings, // but retain expandee. Set automatically be the presentation // compiler -Ymacro-expand:discard This leaves to door ajar for a new option: // Don't expand blackbox macros; expand whitebox // but retain expandee -Ymacro-expand:discard-whitebox-only The existing test for SI-6812 has been duplicated. One copy exercises the now-deprecated -Ymacro-no-expand, and the other uses the new option.
Diffstat (limited to 'src/compiler/scala/tools/nsc/typechecker/Macros.scala')
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Macros.scala27
1 files changed, 15 insertions, 12 deletions
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