From 7c7de8d404b0e6d5ed0c67b4a7862c62b36e0958 Mon Sep 17 00:00:00 2001 From: Jack Koenig Date: Mon, 20 Dec 2021 12:08:39 -0800 Subject: [plugin] Internal refactor, remove useBundlePlugin It is always true. The scalacOption to enable it is still supported and prints a warning that the option no longer does anything. --- .../main/scala/chisel3/internal/plugin/BundleComponent.scala | 8 ++------ .../src/main/scala/chisel3/internal/plugin/ChiselPlugin.scala | 10 +++++++--- 2 files changed, 9 insertions(+), 9 deletions(-) (limited to 'plugin/src') diff --git a/plugin/src/main/scala/chisel3/internal/plugin/BundleComponent.scala b/plugin/src/main/scala/chisel3/internal/plugin/BundleComponent.scala index 67d744fc..c3a001fa 100644 --- a/plugin/src/main/scala/chisel3/internal/plugin/BundleComponent.scala +++ b/plugin/src/main/scala/chisel3/internal/plugin/BundleComponent.scala @@ -26,14 +26,10 @@ private[plugin] class BundleComponent(val global: Global, arguments: ChiselPlugi // instead we just check the version and if its an early Scala version, the plugin does nothing val scalaVersion = scala.util.Properties.versionNumberString.split('.') val scalaVersionOk = scalaVersion(0).toInt == 2 && scalaVersion(1).toInt >= 12 - if (scalaVersionOk && arguments.useBundlePlugin) { + if (scalaVersionOk) { unit.body = new MyTypingTransformer(unit).transform(unit.body) } else { - val reason = if (!scalaVersionOk) { - s"invalid Scala version '${scala.util.Properties.versionNumberString}'" - } else { - s"not enabled via '${arguments.useBundlePluginFullOpt}'" - } + val reason = s"invalid Scala version '${scala.util.Properties.versionNumberString}'" // Enable this with scalacOption '-Ylog:chiselbundlephase' global.log(s"Skipping BundleComponent on account of $reason.") } diff --git a/plugin/src/main/scala/chisel3/internal/plugin/ChiselPlugin.scala b/plugin/src/main/scala/chisel3/internal/plugin/ChiselPlugin.scala index 23082329..2282059f 100644 --- a/plugin/src/main/scala/chisel3/internal/plugin/ChiselPlugin.scala +++ b/plugin/src/main/scala/chisel3/internal/plugin/ChiselPlugin.scala @@ -7,14 +7,18 @@ import nsc.Global import nsc.plugins.{Plugin, PluginComponent} import scala.reflect.internal.util.NoPosition -private[plugin] case class ChiselPluginArguments(var useBundlePlugin: Boolean = true) { +private[plugin] case class ChiselPluginArguments() { def useBundlePluginOpt = "useBundlePlugin" - def useBundlePluginFullOpt = s"-P:chiselplugin:$useBundlePluginOpt" + def useBundlePluginFullOpt = s"-P:${ChiselPlugin.name}:$useBundlePluginOpt" +} + +object ChiselPlugin { + val name = "chiselplugin" } // The plugin to be run by the Scala compiler during compilation of Chisel code class ChiselPlugin(val global: Global) extends Plugin { - val name = "chiselplugin" + val name = ChiselPlugin.name val description = "Plugin for Chisel 3 Hardware Description Language" private val arguments = ChiselPluginArguments() val components: List[PluginComponent] = List[PluginComponent]( -- cgit v1.2.3 From 6388385fb38378d04b8c3df84dba5870f2904ae4 Mon Sep 17 00:00:00 2001 From: Jack Koenig Date: Mon, 20 Dec 2021 13:21:12 -0800 Subject: [plugin] add -P:chiselplugin:INTERNALskipFile This enables skipping files in the compiler plugin, only needed for unidoc generation. --- .../chisel3/internal/plugin/BundleComponent.scala | 10 +----- .../chisel3/internal/plugin/ChiselComponent.scala | 7 ++--- .../chisel3/internal/plugin/ChiselPlugin.scala | 36 ++++++++++++++++++++-- 3 files changed, 37 insertions(+), 16 deletions(-) (limited to 'plugin/src') diff --git a/plugin/src/main/scala/chisel3/internal/plugin/BundleComponent.scala b/plugin/src/main/scala/chisel3/internal/plugin/BundleComponent.scala index c3a001fa..e56380a1 100644 --- a/plugin/src/main/scala/chisel3/internal/plugin/BundleComponent.scala +++ b/plugin/src/main/scala/chisel3/internal/plugin/BundleComponent.scala @@ -22,16 +22,8 @@ private[plugin] class BundleComponent(val global: Global, arguments: ChiselPlugi private class BundlePhase(prev: Phase) extends StdPhase(prev) { override def name: String = phaseName def apply(unit: CompilationUnit): Unit = { - // This plugin doesn't work on Scala 2.11 nor Scala 3. Rather than complicate the sbt build flow, - // instead we just check the version and if its an early Scala version, the plugin does nothing - val scalaVersion = scala.util.Properties.versionNumberString.split('.') - val scalaVersionOk = scalaVersion(0).toInt == 2 && scalaVersion(1).toInt >= 12 - if (scalaVersionOk) { + if (ChiselPlugin.runComponent(global, arguments)(unit)) { unit.body = new MyTypingTransformer(unit).transform(unit.body) - } else { - val reason = s"invalid Scala version '${scala.util.Properties.versionNumberString}'" - // Enable this with scalacOption '-Ylog:chiselbundlephase' - global.log(s"Skipping BundleComponent on account of $reason.") } } } diff --git a/plugin/src/main/scala/chisel3/internal/plugin/ChiselComponent.scala b/plugin/src/main/scala/chisel3/internal/plugin/ChiselComponent.scala index af22e6a7..cee11df5 100644 --- a/plugin/src/main/scala/chisel3/internal/plugin/ChiselComponent.scala +++ b/plugin/src/main/scala/chisel3/internal/plugin/ChiselComponent.scala @@ -11,7 +11,7 @@ import scala.tools.nsc.transform.TypingTransformers // The component of the chisel plugin. Not sure exactly what the difference is between // a Plugin and a PluginComponent. -class ChiselComponent(val global: Global) extends PluginComponent with TypingTransformers { +class ChiselComponent(val global: Global, arguments: ChiselPluginArguments) extends PluginComponent with TypingTransformers { import global._ val runsAfter: List[String] = List[String]("typer") val phaseName: String = "chiselcomponent" @@ -19,10 +19,7 @@ class ChiselComponent(val global: Global) extends PluginComponent with TypingTra class ChiselComponentPhase(prev: Phase) extends StdPhase(prev) { override def name: String = phaseName def apply(unit: CompilationUnit): Unit = { - // This plugin doesn't work on Scala 2.11 nor Scala 3. Rather than complicate the sbt build flow, - // instead we just check the version and if its an early Scala version, the plugin does nothing - val scalaVersion = scala.util.Properties.versionNumberString.split('.') - if (scalaVersion(0).toInt == 2 && scalaVersion(1).toInt >= 12) { + if (ChiselPlugin.runComponent(global, arguments)(unit)) { unit.body = new MyTypingTransformer(unit).transform(unit.body) } } diff --git a/plugin/src/main/scala/chisel3/internal/plugin/ChiselPlugin.scala b/plugin/src/main/scala/chisel3/internal/plugin/ChiselPlugin.scala index 2282059f..eadb76b6 100644 --- a/plugin/src/main/scala/chisel3/internal/plugin/ChiselPlugin.scala +++ b/plugin/src/main/scala/chisel3/internal/plugin/ChiselPlugin.scala @@ -6,14 +6,40 @@ import scala.tools.nsc import nsc.Global import nsc.plugins.{Plugin, PluginComponent} import scala.reflect.internal.util.NoPosition +import scala.collection.mutable -private[plugin] case class ChiselPluginArguments() { +private[plugin] case class ChiselPluginArguments(val skipFiles: mutable.HashSet[String] = mutable.HashSet.empty) { def useBundlePluginOpt = "useBundlePlugin" def useBundlePluginFullOpt = s"-P:${ChiselPlugin.name}:$useBundlePluginOpt" + + // Annoying because this shouldn't be used by users + def skipFilePluginOpt = "INTERNALskipFile:" + def skipFilePluginFullOpt = s"-P:${ChiselPlugin.name}:$skipFilePluginOpt" } object ChiselPlugin { val name = "chiselplugin" + + // Also logs why the compoennt was not run + private[plugin] def runComponent(global: Global, arguments: ChiselPluginArguments)(unit: global.CompilationUnit): Boolean = { + // This plugin doesn't work on Scala 2.11 nor Scala 3. Rather than complicate the sbt build flow, + // instead we just check the version and if its an early Scala version, the plugin does nothing + val scalaVersion = scala.util.Properties.versionNumberString.split('.') + val scalaVersionOk = scalaVersion(0).toInt == 2 && scalaVersion(1).toInt >= 12 + val skipFile = arguments.skipFiles(unit.source.file.path) + if (scalaVersionOk && !skipFile) { + true + } else { + val reason = if (!scalaVersionOk) { + s"invalid Scala version '${scala.util.Properties.versionNumberString}'" + } else { + s"file skipped via '${arguments.skipFilePluginFullOpt}'" + } + // Enable this with scalacOption '-Ylog:chiselbundlephase' + global.log(s"Skipping BundleComponent on account of $reason.") + false + } + } } // The plugin to be run by the Scala compiler during compilation of Chisel code @@ -22,7 +48,7 @@ class ChiselPlugin(val global: Global) extends Plugin { val description = "Plugin for Chisel 3 Hardware Description Language" private val arguments = ChiselPluginArguments() val components: List[PluginComponent] = List[PluginComponent]( - new ChiselComponent(global), + new ChiselComponent(global, arguments), new BundleComponent(global, arguments) ) @@ -31,6 +57,12 @@ class ChiselPlugin(val global: Global) extends Plugin { if (option == arguments.useBundlePluginOpt) { val msg = s"'${arguments.useBundlePluginFullOpt}' is now default behavior, you can stop using the scalacOption." global.reporter.warning(NoPosition, msg) + } else if (option.startsWith(arguments.skipFilePluginOpt)) { + val filename = option.stripPrefix(arguments.skipFilePluginOpt) + arguments.skipFiles += filename + // Be annoying and warn because users are not supposed to use this + val msg = s"Option -P:${ChiselPlugin.name}:$option should only be used for internal chisel3 compiler purposes!" + global.reporter.warning(NoPosition, msg) } else { error(s"Option not understood: '$option'") } -- cgit v1.2.3 From 3131c0daad41dea78bede4517669e376c41a325a Mon Sep 17 00:00:00 2001 From: Jack Koenig Date: Mon, 10 Jan 2022 10:39:52 -0800 Subject: Apply scalafmt Command: sbt scalafmtAll --- .../chisel3/internal/plugin/BundleComponent.scala | 9 ++-- .../chisel3/internal/plugin/ChiselComponent.scala | 63 +++++++++++----------- .../chisel3/internal/plugin/ChiselPlugin.scala | 8 +-- 3 files changed, 42 insertions(+), 38 deletions(-) (limited to 'plugin/src') diff --git a/plugin/src/main/scala/chisel3/internal/plugin/BundleComponent.scala b/plugin/src/main/scala/chisel3/internal/plugin/BundleComponent.scala index e56380a1..2d3a2cae 100644 --- a/plugin/src/main/scala/chisel3/internal/plugin/BundleComponent.scala +++ b/plugin/src/main/scala/chisel3/internal/plugin/BundleComponent.scala @@ -70,11 +70,9 @@ private[plugin] class BundleComponent(val global: Global, arguments: ChiselPlugi (primaryConstructor, paramAccessors.toList) } - override def transform(tree: Tree): Tree = tree match { case bundle: ClassDef if isBundle(bundle.symbol) && !bundle.mods.hasFlag(Flag.ABSTRACT) => - // ==================== Generate _cloneTypeImpl ==================== val (con, params) = getConstructorAndParams(bundle.impl.body) if (con.isEmpty) { @@ -99,13 +97,14 @@ private[plugin] class BundleComponent(val global: Global, arguments: ChiselPlugi if (isData(vp.symbol)) cloneTypeFull(select) else select }) - val tparamList = bundle.tparams.map{ t => Ident(t.symbol) } - val ttpe = if(tparamList.nonEmpty) AppliedTypeTree(Ident(bundle.symbol), tparamList) else Ident(bundle.symbol) + val tparamList = bundle.tparams.map { t => Ident(t.symbol) } + val ttpe = if (tparamList.nonEmpty) AppliedTypeTree(Ident(bundle.symbol), tparamList) else Ident(bundle.symbol) val newUntyped = New(ttpe, conArgs) val neww = localTyper.typed(newUntyped) // Create the symbol for the method and have it be associated with the Bundle class - val cloneTypeSym = bundle.symbol.newMethod(TermName("_cloneTypeImpl"), bundle.symbol.pos.focus, Flag.OVERRIDE | Flag.PROTECTED) + val cloneTypeSym = + bundle.symbol.newMethod(TermName("_cloneTypeImpl"), bundle.symbol.pos.focus, Flag.OVERRIDE | Flag.PROTECTED) // Handwritten cloneTypes don't have the Method flag set, unclear if it matters cloneTypeSym.resetFlag(Flags.METHOD) // Need to set the type to chisel3.Bundle for the override to work diff --git a/plugin/src/main/scala/chisel3/internal/plugin/ChiselComponent.scala b/plugin/src/main/scala/chisel3/internal/plugin/ChiselComponent.scala index cee11df5..eced652b 100644 --- a/plugin/src/main/scala/chisel3/internal/plugin/ChiselComponent.scala +++ b/plugin/src/main/scala/chisel3/internal/plugin/ChiselComponent.scala @@ -11,7 +11,9 @@ import scala.tools.nsc.transform.TypingTransformers // The component of the chisel plugin. Not sure exactly what the difference is between // a Plugin and a PluginComponent. -class ChiselComponent(val global: Global, arguments: ChiselPluginArguments) extends PluginComponent with TypingTransformers { +class ChiselComponent(val global: Global, arguments: ChiselPluginArguments) + extends PluginComponent + with TypingTransformers { import global._ val runsAfter: List[String] = List[String]("typer") val phaseName: String = "chiselcomponent" @@ -25,8 +27,7 @@ class ChiselComponent(val global: Global, arguments: ChiselPluginArguments) exte } } - class MyTypingTransformer(unit: CompilationUnit) - extends TypingTransformer(unit) { + class MyTypingTransformer(unit: CompilationUnit) extends TypingTransformer(unit) { private def shouldMatchGen(bases: Tree*): Type => Boolean = { val cache = mutable.HashMap.empty[Type, Boolean] @@ -51,7 +52,7 @@ class ChiselComponent(val global: Global, arguments: ChiselPluginArguments) exte recShouldMatch(s.typeArgs.head, seen + s) } else { // This is the standard inheritance hierarchy, Scalac catches loops here - s.parents.exists( p => recShouldMatch(p, seen) ) + s.parents.exists(p => recShouldMatch(p, seen)) } } @@ -62,24 +63,25 @@ class ChiselComponent(val global: Global, arguments: ChiselPluginArguments) exte // Return function so that it captures the cache { q: Type => - cache.getOrElseUpdate(q, { - // First check if a match, then check early exit, then recurse - if(terminate(q)){ - true - } else if(earlyExit(q)) { - false - } else { - recShouldMatch(q, Set.empty) + cache.getOrElseUpdate( + q, { + // First check if a match, then check early exit, then recurse + if (terminate(q)) { + true + } else if (earlyExit(q)) { + false + } else { + recShouldMatch(q, Set.empty) + } } - }) + ) } } - - private val shouldMatchData : Type => Boolean = shouldMatchGen(tq"chisel3.Data") - private val shouldMatchDataOrMem : Type => Boolean = shouldMatchGen(tq"chisel3.Data", tq"chisel3.MemBase[_]") - private val shouldMatchModule : Type => Boolean = shouldMatchGen(tq"chisel3.experimental.BaseModule") - private val shouldMatchInstance : Type => Boolean = shouldMatchGen(tq"chisel3.experimental.hierarchy.Instance[_]") + private val shouldMatchData: Type => Boolean = shouldMatchGen(tq"chisel3.Data") + private val shouldMatchDataOrMem: Type => Boolean = shouldMatchGen(tq"chisel3.Data", tq"chisel3.MemBase[_]") + private val shouldMatchModule: Type => Boolean = shouldMatchGen(tq"chisel3.experimental.BaseModule") + private val shouldMatchInstance: Type => Boolean = shouldMatchGen(tq"chisel3.experimental.hierarchy.Instance[_]") // Given a type tree, infer the type and return it private def inferType(t: Tree): Type = localTyper.typed(t, nsc.Mode.TYPEmode).tpe @@ -97,13 +99,13 @@ class ChiselComponent(val global: Global, arguments: ChiselPluginArguments) exte Flags.CASEACCESSOR, Flags.PARAMACCESSOR ) - badFlags.forall{ x => !mods.hasFlag(x)} + badFlags.forall { x => !mods.hasFlag(x) } } // Ensure expression isn't null, as you can't call `null.autoName("myname")` val isNull = dd.rhs match { case Literal(Constant(null)) => true - case _ => false + case _ => false } okFlags(dd.mods) && !isNull && dd.rhs != EmptyTree @@ -130,7 +132,7 @@ class ChiselComponent(val global: Global, arguments: ChiselPluginArguments) exte // Ensure expression isn't null, as you can't call `null.autoName("myname")` val isNull = dd.rhs match { case Literal(Constant(null)) => true - case _ => false + case _ => false } val tpe = inferType(dd.tpt) definitions.isTupleType(tpe) && okFlags(dd.mods) && !isNull && dd.rhs != EmptyTree @@ -139,7 +141,7 @@ class ChiselComponent(val global: Global, arguments: ChiselPluginArguments) exte private def findUnapplyNames(tree: Tree): Option[List[String]] = { val applyArgs: Option[List[Tree]] = tree match { case Match(_, List(CaseDef(_, _, Apply(_, args)))) => Some(args) - case _ => None + case _ => None } applyArgs.flatMap { args => var ok = true @@ -147,7 +149,7 @@ class ChiselComponent(val global: Global, arguments: ChiselPluginArguments) exte args.foreach { case Ident(TermName(name)) => result += name // Anything unexpected and we abort - case _ => ok = false + case _ => ok = false } if (ok) Some(result.toList) else None } @@ -169,9 +171,9 @@ class ChiselComponent(val global: Global, arguments: ChiselPluginArguments) exte // If a Data and in a Bundle, just get the name but not a prefix if (shouldMatchData(tpe) && inBundle(dd)) { val str = stringFromTermName(name) - val newRHS = transform(rhs) // chisel3.internal.plugin.autoNameRecursively + val newRHS = transform(rhs) // chisel3.internal.plugin.autoNameRecursively val named = q"chisel3.internal.plugin.autoNameRecursively($str)($newRHS)" - treeCopy.ValDef(dd, mods, name, tpt, localTyper typed named) + treeCopy.ValDef(dd, mods, name, tpt, localTyper.typed(named)) } // If a Data or a Memory, get the name and a prefix else if (shouldMatchDataOrMem(tpe)) { @@ -179,18 +181,18 @@ class ChiselComponent(val global: Global, arguments: ChiselPluginArguments) exte val newRHS = transform(rhs) val prefixed = q"chisel3.experimental.prefix.apply[$tpt](name=$str)(f=$newRHS)" val named = q"chisel3.internal.plugin.autoNameRecursively($str)($prefixed)" - treeCopy.ValDef(dd, mods, name, tpt, localTyper typed named) + treeCopy.ValDef(dd, mods, name, tpt, localTyper.typed(named)) // If an instance, just get a name but no prefix } else if (shouldMatchModule(tpe)) { val str = stringFromTermName(name) val newRHS = transform(rhs) val named = q"chisel3.internal.plugin.autoNameRecursively($str)($newRHS)" - treeCopy.ValDef(dd, mods, name, tpt, localTyper typed named) + treeCopy.ValDef(dd, mods, name, tpt, localTyper.typed(named)) } else if (shouldMatchInstance(tpe)) { val str = stringFromTermName(name) val newRHS = transform(rhs) val named = q"chisel3.internal.plugin.autoNameRecursively($str)($newRHS)" - treeCopy.ValDef(dd, mods, name, tpt, localTyper typed named) + treeCopy.ValDef(dd, mods, name, tpt, localTyper.typed(named)) } else { // Otherwise, continue super.transform(tree) @@ -202,9 +204,10 @@ class ChiselComponent(val global: Global, arguments: ChiselPluginArguments) exte if (fieldsOfInterest.reduce(_ || _)) { findUnapplyNames(rhs) match { case Some(names) => - val onames: List[Option[String]] = fieldsOfInterest.zip(names).map { case (ok, name) => if (ok) Some(name) else None } + val onames: List[Option[String]] = + fieldsOfInterest.zip(names).map { case (ok, name) => if (ok) Some(name) else None } val named = q"chisel3.internal.plugin.autoNameRecursivelyProduct($onames)($rhs)" - treeCopy.ValDef(dd, mods, name, tpt, localTyper typed named) + treeCopy.ValDef(dd, mods, name, tpt, localTyper.typed(named)) case None => // It's not clear how this could happen but we don't want to crash super.transform(tree) } diff --git a/plugin/src/main/scala/chisel3/internal/plugin/ChiselPlugin.scala b/plugin/src/main/scala/chisel3/internal/plugin/ChiselPlugin.scala index eadb76b6..bd02d50c 100644 --- a/plugin/src/main/scala/chisel3/internal/plugin/ChiselPlugin.scala +++ b/plugin/src/main/scala/chisel3/internal/plugin/ChiselPlugin.scala @@ -21,7 +21,11 @@ object ChiselPlugin { val name = "chiselplugin" // Also logs why the compoennt was not run - private[plugin] def runComponent(global: Global, arguments: ChiselPluginArguments)(unit: global.CompilationUnit): Boolean = { + private[plugin] def runComponent( + global: Global, + arguments: ChiselPluginArguments + )(unit: global.CompilationUnit + ): Boolean = { // This plugin doesn't work on Scala 2.11 nor Scala 3. Rather than complicate the sbt build flow, // instead we just check the version and if its an early Scala version, the plugin does nothing val scalaVersion = scala.util.Properties.versionNumberString.split('.') @@ -70,6 +74,4 @@ class ChiselPlugin(val global: Global) extends Plugin { true } - } - -- cgit v1.2.3