summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/cmd/Reference.scala
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2010-04-11 00:32:00 +0000
committerPaul Phillips <paulp@improving.org>2010-04-11 00:32:00 +0000
commite93c1a93a2c8a40265b34bb9f1dd61b9470c908d (patch)
treeb9f13ffbe1d1ef59380e32f74380f9797b7fd2cb /src/compiler/scala/tools/cmd/Reference.scala
parent71b6aca681ab697304590a96b13847b9bba141dc (diff)
downloadscala-e93c1a93a2c8a40265b34bb9f1dd61b9470c908d.tar.gz
scala-e93c1a93a2c8a40265b34bb9f1dd61b9470c908d.tar.bz2
scala-e93c1a93a2c8a40265b34bb9f1dd61b9470c908d.zip
Introduces scala.tools.cmd providing command li...
Introduces scala.tools.cmd providing command line tool infrastructure. For a quick look at what can be done, see scala.tools.cmd.Demo For a more involved, potentially eye-straining look, see scala.tools.partest.PartestSpec To experience it through the eyes of Joe Partest User, run test/partest Review by community.
Diffstat (limited to 'src/compiler/scala/tools/cmd/Reference.scala')
-rw-r--r--src/compiler/scala/tools/cmd/Reference.scala98
1 files changed, 98 insertions, 0 deletions
diff --git a/src/compiler/scala/tools/cmd/Reference.scala b/src/compiler/scala/tools/cmd/Reference.scala
new file mode 100644
index 0000000000..695868191b
--- /dev/null
+++ b/src/compiler/scala/tools/cmd/Reference.scala
@@ -0,0 +1,98 @@
+/* NSC -- new Scala compiler
+ * Copyright 2005-2010 LAMP/EPFL
+ * @author Paul Phillips
+ */
+
+package scala.tools
+package cmd
+
+import collection.mutable.ListBuffer
+import nsc.Properties.envOrNone
+
+/** Mixes in the specification trait and uses the vals therein to
+ * side-effect private accumulators. From this emerges formatted help,
+ * lists of unary and binary arguments, an apply which can creates
+ * instances of the specification, and etc.
+ *
+ * @see Instance
+ */
+trait Reference extends Spec {
+ lazy val options = new Reference.Accumulators()
+ import options._
+
+ def helpMsg = options.helpMsg
+ def propertyArgs: List[String] = Nil
+
+ def isUnaryOption(s: String) = unary contains toOpt(s)
+ def isBinaryOption(s: String) = binary contains toOpt(s)
+ def isExpandOption(s: String) = expansionMap contains toOpt(s)
+ def isAnyOption(s: String) = isUnaryOption(s) || isBinaryOption(s) || isExpandOption(s)
+
+ def expandArg(arg: String) = expansionMap.getOrElse(fromOpt(arg), List(arg))
+
+ protected def help(str: => String) = addHelp(() => str)
+
+ type ThisCommandLine <: SpecCommandLine
+ class SpecCommandLine(args: List[String]) extends CommandLine(Reference.this, args) { }
+ protected def creator(args: List[String]): ThisCommandLine
+ final def apply(args: String*): ThisCommandLine = creator(propertyArgs ++ args flatMap expandArg)
+
+ type OptionMagic = Opt.Reference
+ protected implicit def optionMagicAdditions(name: String) = new Opt.Reference(programInfo, options, name)
+}
+
+object Reference {
+ val MaxLine = 80
+
+ class Accumulators() {
+ private var _help = new ListBuffer[() => String]
+ private var _unary = List[String]()
+ private var _binary = List[String]()
+ private var _expand = Map[String, List[String]]()
+
+ def helpFormatStr = " %-" + longestArg + "s %s"
+ def defaultFormatStr = (" " * (longestArg + 7)) + "%s"
+
+ def addUnary(s: String) = _unary +:= s
+ def addBinary(s: String) = _binary +:= s
+
+ def addExpand(opt: String, expanded: List[String]) =
+ _expand += (opt -> expanded)
+
+ def mapHelp(g: String => String) = {
+ val idx = _help.length - 1
+ val f = _help(idx)
+
+ _help(idx) = () => g(f())
+ }
+
+ def addHelp(f: () => String) = _help += f
+ def addHelpAlias(f: () => String) = mapHelp { s =>
+ val str = "alias for '%s'" format f()
+ def noHelp = (helpFormatStr.format("", "")).length == s.length
+ val str2 = if (noHelp) str else " (" + str + ")"
+
+ s + str2
+ }
+ def addHelpDefault(f: () => String) = mapHelp { s =>
+ val str = "(default: %s)" format f()
+
+ if (s.length + str.length < MaxLine) s + " " + str
+ else defaultFormatStr.format(s, str)
+ }
+ def addHelpEnvDefault(name: String) = mapHelp { s =>
+ val line1 = "%s (default: %s)".format(s, name)
+ val envNow = envOrNone(name) map ("'" + _ + "'") getOrElse "unset"
+ val line2 = defaultFormatStr.format("Currently " + envNow)
+
+ line1 + "\n" + line2
+ }
+
+ lazy val unary = (_unary ++ _expand.keys).distinct
+ lazy val binary = _binary.distinct
+ lazy val all = unary ++ binary
+ lazy val expansionMap = _expand
+ lazy val helpMsg = _help map (f => f() + "\n") mkString
+ lazy val longestArg = all map (_.length) max
+ }
+}