Permalink
Browse files

makes it more convenient to work with SuppressMacroExpansionAttachment

  • Loading branch information...
1 parent f89f2d9 commit 55decf733eb361c235ef1bd9039e5c6226202a96 @xeno-by xeno-by committed Jun 27, 2013
View
12 bincompat-backward.whitelist.conf
@@ -227,6 +227,18 @@ filter {
{
matchName="scala.reflect.internal.Definitions#DefinitionsClass.primitiveGetClassMethods"
problemName=MissingMethodProblem
+ },
+ {
+ matchName="scala.reflect.internal.StdAttachments.unsuppressMacroExpansion"
+ problemName=MissingMethodProblem
+ },
+ {
+ matchName="scala.reflect.internal.StdAttachments.suppressMacroExpansion"
+ problemName=MissingMethodProblem
+ },
+ {
+ matchName="scala.reflect.internal.StdAttachments.isMacroExpansionSuppressed"
+ problemName=MissingMethodProblem
}
]
}
View
24 bincompat-forward.whitelist.conf
@@ -479,6 +479,30 @@ filter {
{
matchName="scala.reflect.internal.Definitions#DefinitionsClass.primitiveGetClassMethods"
problemName=MissingMethodProblem
+ },
+ {
+ matchName="scala.reflect.internal.StdAttachments.unsuppressMacroExpansion"
+ problemName=MissingMethodProblem
+ },
+ {
+ matchName="scala.reflect.internal.StdAttachments.suppressMacroExpansion"
+ problemName=MissingMethodProblem
+ },
+ {
+ matchName="scala.reflect.internal.StdAttachments.isMacroExpansionSuppressed"
+ problemName=MissingMethodProblem
+ },
+ {
+ matchName="scala.reflect.internal.SymbolTable.unsuppressMacroExpansion"
+ problemName=MissingMethodProblem
+ },
+ {
+ matchName="scala.reflect.internal.SymbolTable.suppressMacroExpansion"
+ problemName=MissingMethodProblem
+ },
+ {
+ matchName="scala.reflect.internal.SymbolTable.isMacroExpansionSuppressed"
+ problemName=MissingMethodProblem
}
]
}
View
4 src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -1147,7 +1147,7 @@ trait Typers extends Modes with Adaptations with Tags {
else if (
inExprModeButNot(mode, FUNmode) && !tree.isDef && // typechecking application
tree.symbol != null && tree.symbol.isTermMacro && // of a macro
- !tree.attachments.get[SuppressMacroExpansionAttachment.type].isDefined)
+ !isMacroExpansionSuppressed(tree))
macroExpand(this, tree, mode, pt)
else if ((mode & (PATTERNmode | FUNmode)) == (PATTERNmode | FUNmode))
adaptConstrPattern()
@@ -5352,7 +5352,7 @@ trait Typers extends Modes with Adaptations with Tags {
// that typecheck must not trigger macro expansions, so we explicitly prohibit them
// however we cannot do `context.withMacrosDisabled`
// because `expr` might contain nested macro calls (see SI-6673)
- val exprTyped = typed1(expr updateAttachment SuppressMacroExpansionAttachment, mode, pt)
+ val exprTyped = typed1(suppressMacroExpansion(expr), mode, pt)
exprTyped match {
case macroDef if macroDef.symbol != null && macroDef.symbol.isTermMacro && !macroDef.symbol.isErroneous =>
MacroEtaError(exprTyped)
View
31 src/reflect/scala/reflect/internal/StdAttachments.scala
@@ -42,4 +42,35 @@ trait StdAttachments {
* (but think thrice before using that API - see the discussion at https://github.com/scala/scala/pull/1639).
*/
case object SuppressMacroExpansionAttachment
+
+ /** Suppresses macro expansion of the tree by putting SuppressMacroExpansionAttachment on it.
+ */
+ def suppressMacroExpansion(tree: Tree) = tree.updateAttachment(SuppressMacroExpansionAttachment)
+
+ /** Unsuppresses macro expansion of the tree by removing SuppressMacroExpansionAttachment from it and its children.
+ */
+ def unsuppressMacroExpansion(tree: Tree): Tree = {
+ tree.removeAttachment[SuppressMacroExpansionAttachment.type]
+ tree match {
+ // see the comment to `isMacroExpansionSuppressed` to learn why we need
+ // a special traversal strategy here
+ case Apply(fn, _) => unsuppressMacroExpansion(fn)
+ case TypeApply(fn, _) => unsuppressMacroExpansion(fn)
+ case _ => // do nothing
+ }
+ tree
+ }
+
+ /** 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 =
+ if (tree.attachments.get[SuppressMacroExpansionAttachment.type].isDefined) true
+ else tree match {
+ // we have to account for the fact that during typechecking an expandee might become wrapped,
+ // i.e. surrounded by an inferred implicit argument application or by an inferred type argument application.
+ // in that case the expandee itself will no longer be suppressed and we need to look at the core
+ case Apply(fn, _) => isMacroExpansionSuppressed(fn)
+ case TypeApply(fn, _) => isMacroExpansionSuppressed(fn)
+ case _ => false
+ }
}

0 comments on commit 55decf7

Please sign in to comment.