diff options
author | Paul Phillips <paulp@improving.org> | 2010-04-21 17:06:59 +0000 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2010-04-21 17:06:59 +0000 |
commit | db0d40b73c92be4a0eb0ef03f6bfb166c8cfb4c0 (patch) | |
tree | 85d1cd1e04654816de8232dae8fc8641839c5974 | |
parent | a17a4dc15730ce004ca8c9495c850dfca1062c24 (diff) | |
download | scala-db0d40b73c92be4a0eb0ef03f6bfb166c8cfb4c0.tar.gz scala-db0d40b73c92be4a0eb0ef03f6bfb166c8cfb4c0.tar.bz2 scala-db0d40b73c92be4a0eb0ef03f6bfb166c8cfb4c0.zip |
Two new command line programs in ~/tools: scmp ...
Two new command line programs in ~/tools: scmp and tokens.
1) scmp: will need a bit more fleshing out to be super useful, but here
is what you can do right now:
// This means run the given command line first with the options
// given to p1 and then without, and show the diff in output.
% tools/scmp --p1 '-no-specialization -nowarn' scalac -Ydebug
src/library/scala/Function1.scala
Upcoming features will involve seeing diffs of such things as the
pickled signatures of generated files and the javap disassembly.
2) tokens: tokenizes all the scala files found under any given paths and
prints one token per line.
Example: the five most frequently used tokens under scala/util.
% tools/tokens src/library/scala/util |sort | uniq -c | sort -r | head
-5 598 ')' 598 '(' 347 ; 294 '=' 278 ,
Good to see those parens are balanced.
Example: number of appearances of an identifier called x:
% tools/tokens src/library/scala/util | grep ^x$ | wc 137
Way to go, x. Review by community.
-rw-r--r-- | src/compiler/scala/tools/cmd/program/Scmp.scala | 59 | ||||
-rw-r--r-- | src/compiler/scala/tools/cmd/program/Tokens.scala | 75 | ||||
-rwxr-xr-x | tools/scmp | 4 | ||||
-rwxr-xr-x | tools/tokens | 4 |
4 files changed, 142 insertions, 0 deletions
diff --git a/src/compiler/scala/tools/cmd/program/Scmp.scala b/src/compiler/scala/tools/cmd/program/Scmp.scala new file mode 100644 index 0000000000..ff4fa11eaf --- /dev/null +++ b/src/compiler/scala/tools/cmd/program/Scmp.scala @@ -0,0 +1,59 @@ +/* NEST (New Scala Test) + * Copyright 2007-2010 LAMP/EPFL + * @author Paul Phillips + */ + +package scala.tools +package cmd +package program + +import nsc.io._ + +object Scmp { + private val scmpUsage = """ + |Usage: scmp [options] <cmd line> + |Example: scmp --p1 '-no-specialization -Ydebug' scalac src/library/scala/Function1.scala + | + |Note: the command line must start with a path to scalac. + |""".stripMargin + private val scmpOptions = List( + "p1" -> "options for the first run only", + "p2" -> "options for the second run only" + ) + private val scmpInfo = Simple.scalaProgramInfo("scmp", scmpUsage) + lazy val ScmpSpec = Simple(scmpInfo, Nil, scmpOptions, x => returning(x)(_.onlyKnownOptions = false)) + + def main(args0: Array[String]): Unit = { + if (args0.isEmpty) + return println(scmpUsage) + + val runner = ScmpSpec instance args0 + import runner._ + + val p1args = parsed.getOrElse("--p1", "") + val p2args = parsed.getOrElse("--p2", "") + + if (p1args.isEmpty && p2args.isEmpty) + return println("At least one of --p1 and --p2 must be given.") + if (residualArgs.isEmpty) + return println("There is no command to run.") + + def createCmd(extras: String) = + fromArgs(residualArgs.patch(1, toArgs(extras), 0)) + + def runCmd(cmd: String) = { + val output = Process(cmd, redirect = true).slurp() + + returning(File.makeTemp())(_ writeAll output) + } + + val cmds = List(p1args, p2args) map createCmd + println(cmds.mkString("Running command lines:\n ", "\n ", "")) + + val files = cmds map runCmd map (_.path) + val diff = Process("diff %s %s".format(files: _*)).slurp() + + if (diff.isEmpty) println("No differences.") + else println(diff) + } +} diff --git a/src/compiler/scala/tools/cmd/program/Tokens.scala b/src/compiler/scala/tools/cmd/program/Tokens.scala new file mode 100644 index 0000000000..30502213f6 --- /dev/null +++ b/src/compiler/scala/tools/cmd/program/Tokens.scala @@ -0,0 +1,75 @@ +/* NSC -- new Scala compiler + * Copyright 2005-2010 LAMP/EPFL + * @author Paul Phillips + */ + +package scala.tools +package cmd +package program + +import nsc._ +import io._ +import ast.parser.Tokens._ + +/** Given paths on the command line, tokenizes any scala files found + * and prints one token per line. + */ +object Tokens { + private val tokensUsage = "Usage: tokens [options] <path1 path2 ...>\n\nOptions:" + private val tokensOptions = List( + "verbose" -> "be more verbose", + "stats" -> "output some stats" + ) + private val tokensInfo = Simple.scalaProgramInfo("tokens", tokensUsage) + private lazy val TokensSpec = Simple(tokensInfo, tokensOptions, Nil, null) + + def main(args0: Array[String]): Unit = { + if (args0.isEmpty) + return println(TokensSpec.helpMsg) + + val runner = TokensSpec instance args0 + import runner._ + + val files = (residualArgs flatMap walk).distinct + if (parsed isSet "verbose") + println("Tokenizing: " + (files map (_.name) mkString " ")) + + if (parsed isSet "stats") + println("Stats not yet implemented.") + + files flatMap fromScalaSource foreach println + } + + /** Given a path, returns all .scala files underneath it. + */ + private def walk(arg: String): List[File] = + Path(arg).walkFilter(x => x.isFile && x.hasExtension("scala")) map (_.toFile) toList + + /** Tokenizes a single scala file. + */ + def fromScalaSource(file: Path): List[Any] = fromScalaSource(file.path) + def fromScalaSource(file: String): List[Any] = { + val global = new Global(new Settings()) + import global._ + import syntaxAnalyzer.{ UnitScanner, token2string } + + val in = new UnitScanner(new CompilationUnit(getSourceFile(file))) + in.init() + + Iterator continually { + val token = in.token match { + case IDENTIFIER | BACKQUOTED_IDENT => in.name + case CHARLIT | INTLIT | LONGLIT => in.intVal + case DOUBLELIT | FLOATLIT => in.floatVal + case STRINGLIT => "\"" + in.strVal + "\"" + case SEMI | NEWLINE => ";" + case NEWLINES => ";;" + case COMMA => "," + case EOF => null + case x => token2string(x) + } + in.nextToken() + token + } takeWhile (_ != null) toList + } +} diff --git a/tools/scmp b/tools/scmp new file mode 100755 index 0000000000..f6acea5ab1 --- /dev/null +++ b/tools/scmp @@ -0,0 +1,4 @@ +#!/bin/sh +# + +scala scala.tools.cmd.program.Scmp "$@" diff --git a/tools/tokens b/tools/tokens new file mode 100755 index 0000000000..b910fb29cc --- /dev/null +++ b/tools/tokens @@ -0,0 +1,4 @@ +#!/bin/sh +# + +scala scala.tools.cmd.program.Tokens "$@" |