summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala
diff options
context:
space:
mode:
authorEugene Burmako <xeno.by@gmail.com>2013-01-19 12:28:19 +0100
committerEugene Burmako <xeno.by@gmail.com>2013-05-28 10:19:19 +0200
commit10229316dbf7afa7545d8e279b5960da6ee3db7d (patch)
treecfa50a3207aa5c1b2ce17ffba0fe1413a6f0dd53 /src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala
parente0bbe0af094b9055942c24fcaaa290a31415fa0a (diff)
downloadscala-10229316dbf7afa7545d8e279b5960da6ee3db7d.tar.gz
scala-10229316dbf7afa7545d8e279b5960da6ee3db7d.tar.bz2
scala-10229316dbf7afa7545d8e279b5960da6ee3db7d.zip
refactors macro compilation
Upgrades the way that macro defs are compiled by factoring out most of the logic in typedMacroBody and related errors in ContextErrors into an standalone cake. This leads to tighter cohesion and better code reuse as the cake is isolated from the rest of the compiler and is much easier to evolve than just a method body. Increased convenience of coding macro compilation allowed me to further clarify the implementation of the macro engine (e.g. take a look at Validators.scala) and to easily implement additional features, namely: 1) Parameters and return type of macro implementations can now be plain c.Tree's instead of previously mandatory c.Expr's. This makes macros more lightweight as there are a lot of situations when one doesn't need to splice macro params (the only motivation to use exprs over trees). Also as we're on the verge of having quasiquotes in trunk, there soon will be no reason to use exprs at all, since quasiquotes can splice everything. 2) Macro implementations can now be defined in bundles, standalone cakes built around a macro context: http://docs.scala-lang.org/overviews/macros/bundles.html. This further reduces boilerplate by simplifying implementations complex macros due to the fact that macro programmers no longer need to play path-dependent games to use helpers.
Diffstat (limited to 'src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala')
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala27
1 files changed, 27 insertions, 0 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala b/src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala
index 64fcda3b80..a208924acb 100644
--- a/src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala
@@ -127,4 +127,31 @@ trait StdAttachments {
/** Determines whether the given tree has an associated SuperArgsAttachment.
*/
def hasSuperArgs(tree: Tree): Boolean = superArgs(tree).nonEmpty
+
+ /** @see markMacroImplRef
+ */
+ case object MacroImplRefAttachment
+
+ /** Marks the tree as a macro impl reference, which is a naked reference to a method.
+ *
+ * This is necessary for typechecking macro impl references (see `DefaultMacroCompiler.defaultResolveMacroImpl`),
+ * because otherwise typing a naked reference will result in the "follow this method with `_' if you want to
+ * treat it as a partially applied function" errors.
+ *
+ * This mark suppresses adapt except for when the annottee is a macro application.
+ */
+ def markMacroImplRef(tree: Tree): Tree = tree.updateAttachment(MacroImplRefAttachment)
+
+ /** Unmarks the tree as a macro impl reference (see `markMacroImplRef` for more information).
+ *
+ * This is necessary when a tree that was previously deemed to be a macro impl reference,
+ * typechecks to be a macro application. Then we need to unmark it, expand it and try to treat
+ * its expansion as a macro impl reference.
+ */
+ def unmarkMacroImplRef(tree: Tree): Tree = tree.removeAttachment[MacroImplRefAttachment.type]
+
+ /** Determines whether a tree should or should not be adapted,
+ * because someone has put MacroImplRefAttachment on it.
+ */
+ def isMacroImplRef(tree: Tree): Boolean = tree.attachments.get[MacroImplRefAttachment.type].isDefined
} \ No newline at end of file