summaryrefslogtreecommitdiff
path: root/coreMacros/src/main/scala/chisel3/internal/sourceinfo
diff options
context:
space:
mode:
Diffstat (limited to 'coreMacros/src/main/scala/chisel3/internal/sourceinfo')
-rw-r--r--coreMacros/src/main/scala/chisel3/internal/sourceinfo/NamingAnnotations.scala205
1 files changed, 0 insertions, 205 deletions
diff --git a/coreMacros/src/main/scala/chisel3/internal/sourceinfo/NamingAnnotations.scala b/coreMacros/src/main/scala/chisel3/internal/sourceinfo/NamingAnnotations.scala
deleted file mode 100644
index bf4879ec..00000000
--- a/coreMacros/src/main/scala/chisel3/internal/sourceinfo/NamingAnnotations.scala
+++ /dev/null
@@ -1,205 +0,0 @@
-// See LICENSE for license details.
-
-// Transform implementations for name-propagation related annotations.
-//
-// Helpful references:
-// http://docs.scala-lang.org/overviews/quasiquotes/syntax-summary.html#definitions
-// for quasiquote structures of various Scala structures
-// http://jsuereth.com/scala/2009/02/05/leveraging-annotations-in-scala.html
-// use of Transformer
-// http://www.scala-lang.org/old/sites/default/files/sids/rytz/Wed,%202010-01-27,%2015:10/annots.pdf
-// general annotations reference
-
-package chisel3.internal.naming
-
-import scala.reflect.macros.whitebox.Context
-import scala.annotation.{StaticAnnotation, compileTimeOnly}
-import scala.language.experimental.macros
-
-// Workaround for https://github.com/sbt/sbt/issues/3966
-object DebugTransforms
-class DebugTransforms(val c: Context) {
- import c.universe._
-
- /** Passthrough transform that prints the annottee for debugging purposes.
- * No guarantees are made on what this annotation does, and it may very well change over time.
- *
- * The print is warning level to make it visually easier to spot, as well as a reminder that
- * this annotation should not make it to production / committed code.
- */
- def dump(annottees: c.Tree*): c.Tree = {
- val combined = annottees.map({ tree => show(tree) }).mkString("\r\n\r\n")
- annottees.foreach(tree => c.warning(c.enclosingPosition, s"Debug dump:\n$combined"))
- q"..$annottees"
- }
-
- /** Passthrough transform that prints the annottee as a tree for debugging purposes.
- * No guarantees are made on what this annotation does, and it may very well change over time.
- *
- * The print is warning level to make it visually easier to spot, as well as a reminder that
- * this annotation should not make it to production / committed code.
- */
- def treedump(annottees: c.Tree*): c.Tree = {
- val combined = annottees.map({ tree => showRaw(tree) }).mkString("\r\n")
- annottees.foreach(tree => c.warning(c.enclosingPosition, s"Debug tree dump:\n$combined"))
- q"..$annottees"
- }
-}
-
-// Workaround for https://github.com/sbt/sbt/issues/3966
-object NamingTransforms
-class NamingTransforms(val c: Context) {
- import c.universe._
-
- val globalNamingStack = q"_root_.chisel3.internal.DynamicNamingStack"
-
- /** Base transformer that provides the val name transform.
- * Should not be instantiated, since by default this will recurse everywhere and break the
- * naming context variable bounds.
- */
- trait ValNameTransformer extends Transformer {
- val contextVar: TermName
-
- override def transform(tree: Tree): Tree = tree match {
- // Intentionally not prefixed with $mods, since modifiers usually mean the val definition
- // is in a non-transformable location, like as a parameter list.
- // TODO: is this exhaustive / correct in all cases?
- case q"val $tname: $tpt = $expr" => {
- val TermName(tnameStr: String) = tname
- val transformedExpr = super.transform(expr)
- q"val $tname: $tpt = $contextVar.name($transformedExpr, $tnameStr)"
- }
- case other => super.transform(other)
- }
- }
-
- /** Module-specific val name transform, containing logic to prevent from recursing into inner
- * classes and applies the naming transform on inner functions.
- */
- class ClassBodyTransformer(val contextVar: TermName) extends ValNameTransformer {
- override def transform(tree: Tree): Tree = tree match {
- case q"$mods class $tpname[..$tparams] $ctorMods(...$paramss) extends { ..$earlydefns } with ..$parents { $self => ..$stats }" => // scalastyle:ignore line.size.limit
- tree // don't recurse into inner classes
- case q"$mods trait $tpname[..$tparams] extends { ..$earlydefns } with ..$parents { $self => ..$stats }" =>
- tree // don't recurse into inner classes
- case q"$mods def $tname[..$tparams](...$paramss): $tpt = $expr" => {
- val Modifiers(_, _, annotations) = mods
- // don't apply naming transform twice
- val containsChiselName = annotations.map({q"new chiselName()" equalsStructure _}).fold(false)({_||_})
- // transforming overloaded initializers causes errors, and the transform isn't helpful
- val isInitializer = tname == TermName("<init>")
- if (containsChiselName || isInitializer) {
- tree
- } else {
- // apply chiselName transform by default
- val transformedExpr = transformHierarchicalMethod(expr)
- q"$mods def $tname[..$tparams](...$paramss): $tpt = $transformedExpr"
- }
- }
- case other => super.transform(other)
- }
- }
-
- /** Method-specific val name transform, handling the return case.
- */
- class MethodTransformer(val contextVar: TermName) extends ValNameTransformer {
- override def transform(tree: Tree): Tree = tree match {
- // TODO: better error messages when returning nothing
- case q"return $expr" => q"return $globalNamingStack.popReturnContext($expr, $contextVar)"
- // Do not recurse into methods
- case q"$mods def $tname[..$tparams](...$paramss): $tpt = $expr" => tree
- case other => super.transform(other)
- }
- }
-
- /** Applies the val name transform to a class body.
- * Closes context on top level or return local context to englobing context.
- * Closing context only makes sense when top level a Module.
- * A Module is always the naming top level.
- * Transformed classes can be either Module or standard class.
- */
- def transformClassBody(stats: List[c.Tree]): Tree = {
- val contextVar = TermName(c.freshName("namingContext"))
- val transformedBody = (new ClassBodyTransformer(contextVar)).transformTrees(stats)
- // Note: passing "this" to popReturnContext is mandatory for propagation through non-module classes
- q"""
- val $contextVar = $globalNamingStack.pushContext()
- ..$transformedBody
- if($globalNamingStack.length == 1){
- $contextVar.namePrefix("")
- }
- $globalNamingStack.popReturnContext(this, $contextVar)
- """
- }
-
- /** Applies the val name transform to a method body, doing additional bookkeeping with the
- * context to allow names to propagate and prefix through the function call stack.
- */
- def transformHierarchicalMethod(expr: c.Tree): Tree = {
- val contextVar = TermName(c.freshName("namingContext"))
- val transformedBody = (new MethodTransformer(contextVar)).transform(expr)
-
- q"""{
- val $contextVar = $globalNamingStack.pushContext()
- $globalNamingStack.popReturnContext($transformedBody, $contextVar)
- }
- """
- }
-
- /** Applies naming transforms to vals in the annotated module or method.
- *
- * For methods, a hierarchical naming transform is used, where it will try to give objects names
- * based on the call stack, assuming all functions on the stack are annotated as such and return
- * a non-AnyVal object. Does not recurse into inner functions.
- *
- * For modules, this serves as the root of the call stack hierarchy for naming purposes. Methods
- * will have chiselName annotations (non-recursively), but this does NOT affect inner classes.
- *
- * Basically rewrites all instances of:
- * val name = expr
- * to:
- * val name = context.name(expr, name)
- */
- def chiselName(annottees: c.Tree*): c.Tree = {
- var namedElts: Int = 0
-
- val transformed = annottees.map(annottee => annottee match {
- // scalastyle:off line.size.limit
- case q"$mods class $tpname[..$tparams] $ctorMods(...$paramss) extends { ..$earlydefns } with ..$parents { $self => ..$stats }" => {
- val transformedStats = transformClassBody(stats)
- namedElts += 1
- q"$mods class $tpname[..$tparams] $ctorMods(...$paramss) extends { ..$earlydefns } with ..$parents { $self => ..$transformedStats }"
- }
- case q"$mods object $tname extends { ..$earlydefns } with ..$parents { $self => ..$body }" => {
- annottee // Don't fail noisly when a companion object is passed in with the actual class def
- }
- // Currently disallow on traits, this won't work well with inheritance.
- case q"$mods def $tname[..$tparams](...$paramss): $tpt = $expr" => {
- val transformedExpr = transformHierarchicalMethod(expr)
- namedElts += 1
- q"$mods def $tname[..$tparams](...$paramss): $tpt = $transformedExpr"
- }
- case other => c.abort(c.enclosingPosition, s"@chiselName annotion may only be used on classes and methods, got ${showCode(other)}")
- })
-
- if (namedElts != 1) {
- c.abort(c.enclosingPosition, s"@chiselName annotation did not match exactly one valid tree, got:\r\n${annottees.map(tree => showCode(tree)).mkString("\r\n\r\n")}")
- }
- // scalastyle:on line.size.limit
-
- q"..$transformed"
- }
-}
-
-@compileTimeOnly("enable macro paradise to expand macro annotations")
-class dump extends StaticAnnotation { // scalastyle:ignore class.name
- def macroTransform(annottees: Any*): Any = macro chisel3.internal.naming.DebugTransforms.dump
-}
-@compileTimeOnly("enable macro paradise to expand macro annotations")
-class treedump extends StaticAnnotation { // scalastyle:ignore class.name
- def macroTransform(annottees: Any*): Any = macro chisel3.internal.naming.DebugTransforms.treedump
-}
-@compileTimeOnly("enable macro paradise to expand macro annotations")
-class chiselName extends StaticAnnotation { // scalastyle:ignore class.name
- def macroTransform(annottees: Any*): Any = macro chisel3.internal.naming.NamingTransforms.chiselName
-}