diff options
author | Jason Zaugg <jzaugg@gmail.com> | 2013-12-18 16:55:15 +0100 |
---|---|---|
committer | Eugene Burmako <xeno.by@gmail.com> | 2014-01-08 20:50:08 +0100 |
commit | d744921f855a6c5d4f4df62895bc3b17b8e0e532 (patch) | |
tree | 5ab2f9bf09b1f6091bb71c05c99a2cc077f28570 /src | |
parent | d6b4cda628d43c2c7ede1fbfbffbff7cd62d2919 (diff) | |
download | scala-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')
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Macros.scala | 26 |
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) |