diff options
Diffstat (limited to 'coreMacros/src/main/scala/chisel3/internal/sourceinfo')
| -rw-r--r-- | coreMacros/src/main/scala/chisel3/internal/sourceinfo/NamingAnnotations.scala | 205 |
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 -} |
