diff options
| author | Schuyler Eldridge | 2019-04-22 21:20:08 -0400 |
|---|---|---|
| committer | Schuyler Eldridge | 2019-04-25 16:24:15 -0400 |
| commit | ef8f06f23b9ee6cf86de2450752dfd0fcd32da80 (patch) | |
| tree | 79e2e8c5753903ca6d14e9b952c26a07442bd980 /src/main/scala/firrtl/options/Registration.scala | |
| parent | 47fe781c4ace38dff7f31da7e78f772e131d689e (diff) | |
Add ShellOption, DeletedWrapper
Abstracts away option writing such that users no longer have to
understand scopt semantics. This adds a ShellOption class and a
HasShellOptions trait for something which provides one or more
ShellOptions. This refactors the FIRRTL codebase to use this style of
option specification.
Adds and uses DeletedWrapper to automatically generate
DeletedAnnotations.
Signed-off-by: Schuyler Eldridge <schuyler.eldridge@ibm.com>
Diffstat (limited to 'src/main/scala/firrtl/options/Registration.scala')
| -rw-r--r-- | src/main/scala/firrtl/options/Registration.scala | 58 |
1 files changed, 44 insertions, 14 deletions
diff --git a/src/main/scala/firrtl/options/Registration.scala b/src/main/scala/firrtl/options/Registration.scala index a826ec50..c832ec7c 100644 --- a/src/main/scala/firrtl/options/Registration.scala +++ b/src/main/scala/firrtl/options/Registration.scala @@ -4,40 +4,70 @@ package firrtl.options import firrtl.{AnnotationSeq, Transform} -import scopt.OptionParser +import scopt.{OptionDef, OptionParser, Read} + +/** Contains information about a [[Shell]] command line option + * @tparam the type of the command line argument + * @param longOption a long, double-dash option + * @param toAnnotationSeq a function to convert the type into an [[firrtl.AnnotationSeq AnnotationSeq]] + * @param helpText help text + * @param shortOption an optional single-dash option + * @param helpValueName a string to show as a placeholder argument in help text + */ +final class ShellOption[A: Read] ( + val longOption: String, + val toAnnotationSeq: A => AnnotationSeq, + val helpText: String, + val shortOption: Option[String] = None, + val helpValueName: Option[String] = None +) { + + /** Add this specific shell (command line) option to an option parser + * @param p an option parser + */ + final def addOption(p: OptionParser[AnnotationSeq]): Unit = { + val f = Seq( + (p: OptionDef[A, AnnotationSeq]) => p.action( (x, c) => toAnnotationSeq(x).reverse ++ c ), + (p: OptionDef[A, AnnotationSeq]) => p.text(helpText), + (p: OptionDef[A, AnnotationSeq]) => p.unbounded()) ++ + shortOption.map( a => (p: OptionDef[A, AnnotationSeq]) => p.abbr(a) ) ++ + helpValueName.map( a => (p: OptionDef[A, AnnotationSeq]) => p.valueName(a) ) + + f.foldLeft(p.opt[A](longOption))( (a, b) => b(a) ) + } +} /** Indicates that this class/object includes options (but does not add these as a registered class) */ -trait HasScoptOptions { +trait HasShellOptions { - /** This method will be called to add options to an OptionParser ('''OPTIONS SHOULD BE PREPENDED''') - * - * - * '''The ordering of [[firrtl.annotations.Annotation Annotation]] is important and has meaning for parallel - * compilations. For deterministic behavior, you should always prepend any annotations to the [[firrtl.AnnotationSeq - * AnnotationSeq]]. The [[firrtl.AnnotationSeq AnnotationSeq]] will be automatically reversed after a [[Stage]] - * parses it.''' - * + /** A sequence of options provided + */ + def options: Seq[ShellOption[_]] + + /** Add all shell (command line) options to an option parser * @param p an option parser */ - def addOptions(p: OptionParser[AnnotationSeq]): Unit + final def addOptions(p: OptionParser[AnnotationSeq]): Unit = options.foreach(_.addOption(p)) + } -/** A [[Transform]] that includes options that should be exposed at the top level. +/** A [[Transform]] that includes an option that should be exposed at the top level. * * @note To complete registration, include an entry in * src/main/resources/META-INF/services/firrtl.options.RegisteredTransform */ -trait RegisteredTransform extends HasScoptOptions { this: Transform => } +trait RegisteredTransform extends HasShellOptions { this: Transform => } /** A class that includes options that should be exposed as a group at the top level. * * @note To complete registration, include an entry in * src/main/resources/META-INF/services/firrtl.options.RegisteredLibrary */ -trait RegisteredLibrary extends HasScoptOptions { +trait RegisteredLibrary extends HasShellOptions { /** The name of this library. * * This will be used when generating help text. */ def name: String + } |
