如何在不执行脚本和生成任何类文件的情况下语法检查Scala脚本?

时间:2011-03-05 15:49:44

标签: scala scripting

可以在Scala中编写脚本。所以你可以将它放入Hello.scala

#!/bin/sh
exec scala $0 $@
!#

println("You supplied " + args.length + " arguments!")

并通过

使其在Unix中可执行
chmod u+x Hello.scala

然后你可以通过

简单地运行脚本
./Hello.scala

如果没有语法错误,则编译脚本并运行它。但是,当我只想在没有执行脚本的情况下进行语法检查时,这不会考虑这种情况。我不想修改脚本(即删除#!指令),我不希望生成任何* .class文件。

如何对Scala脚本进行语法检查?

2 个答案:

答案 0 :(得分:24)

我希望你真的想要的不仅仅是检查正确的语法......大概你想要知道的是,如果你真的编译它,你的文件会正确编译。这涉及类型检查以及语法检查。

对于Scala源文件(即非脚本),您可以指定-Ystop:refchecks命令行参数,以使编译器在开始代码生成之前停止(如果您真的只对语法正确性感兴趣,则可以指定-Ystop :解析器)。如果有错误,它们将以完全相同的方式显示在控制台上。

对于Scala脚本,您还可以指定-Ystop:refchecks参数。如果您这样做,那么您将看到控制台上报告的编译错误,或者如果脚本中没有错误,您将看到以下内容,

$ scala -Ystop:refchecks Hello.scala 
java.lang.ClassNotFoundException: Main

ClassNotFoundException,指示尚未生成任何类文件,并且您的脚本尚未执行。

答案 1 :(得分:0)

如果要剪切文件中的线条以传递给解释器,可以创建一个名为CutScala.scala的脚本(或您喜欢的任何内容):

#!/bin/sh
exec scala $0 $@
!#

import scala.collection.JavaConversions._
import java.io._

val p = new ProcessBuilder(
  List(
    "scala",
    "-e",
    io.Source.fromFile(args(1)).getLines().drop(args(0).toInt).mkString("\n")
  ) :::
  args.drop(2).toList
).start()

p.waitFor

val output = List(p.getInputStream,p.getErrorStream).map(
  x => new BufferedReader(new InputStreamReader(x))
)

println("Exit code = " + p.exitValue)
for ((reader,title) <- (output zip List("Output:","Errors:"))) {
  println(title);
  Iterator.continually(reader.readLine).takeWhile(_!=null).foreach(println)
  println
}

然后将其称为

./CutScala.scala 4 Hello.scala a b c

删除前4行并解析其余部分。 Miles的回答告诉你如何做其他(更难)的一半不产生任何输出而不运行任何东西。