summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/typechecker/Macros.scala
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2013-12-18 16:55:15 +0100
committerEugene Burmako <xeno.by@gmail.com>2014-01-08 20:50:08 +0100
commitd744921f855a6c5d4f4df62895bc3b17b8e0e532 (patch)
tree5ab2f9bf09b1f6091bb71c05c99a2cc077f28570 /src/compiler/scala/tools/nsc/typechecker/Macros.scala
parentd6b4cda628d43c2c7ede1fbfbffbff7cd62d2919 (diff)
downloadscala-d744921f855a6c5d4f4df62895bc3b17b8e0e532.tar.gz
scala-d744921f855a6c5d4f4df62895bc3b17b8e0e532.tar.bz2
scala-d744921f855a6c5d4f4df62895bc3b17b8e0e532.zip
SI-8064 Automatic position repair for macro expansion
- Replace NoPosition with the focus of the macro application - Focus all range positions, for example, those of spliced arguments
Diffstat (limited to 'src/compiler/scala/tools/nsc/typechecker/Macros.scala')
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Macros.scala26
1 files changed, 25 insertions, 1 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala
index 006ab792fc..c32b986d9c 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala
@@ -760,7 +760,31 @@ trait Macros extends FastTrack with MacroRuntimes with Traces with Helpers {
macroLogLite("" + expanded + "\n" + showRaw(expanded))
val freeSyms = expanded.freeTerms ++ expanded.freeTypes
freeSyms foreach (sym => MacroFreeSymbolError(expandee, sym))
- Success(atPos(enclosingMacroPosition.focus)(expanded))
+ // Macros might have spliced arguments with range positions into non-compliant
+ // locations, notably, under a tree without a range position. Or, they might
+ // splice a tree that `resetAttrs` has assigned NoPosition.
+ //
+ // Here, we just convert all positions in the tree to offset positions, and
+ // convert NoPositions to something sensible.
+ //
+ // Given that the IDE now sees the expandee (by using -Ymacro-expand:discard),
+ // this loss of position fidelity shouldn't cause any real problems.
+ //
+ // Alternatively, we could pursue a way to exclude macro expansions from position
+ // invariant checking, or find a way not to touch expansions that happen to validate.
+ //
+ // This would be useful for cases like:
+ //
+ // macro1 { macro2 { "foo" } }
+ //
+ // to allow `macro1` to see the range position of the "foo".
+ val expandedPos = enclosingMacroPosition.focus
+ def fixPosition(pos: Position) =
+ if (pos == NoPosition) expandedPos else pos.focus
+ expanded.foreach(t => t.pos = fixPosition(t.pos))
+
+ val result = atPos(enclosingMacroPosition.focus)(expanded)
+ Success(result)
}
expanded match {
case expanded: Expr[_] if expandee.symbol.isTermMacro => validateResultingTree(expanded.tree)