📄 scalac.scala
字号:
/** Set the <code>addparams</code> info attribute. * @param input The value for <code>addparams</code>. */ def setAddparams(input: String) { addParams = input } /** Set the <code>deprecation</code> info attribute. * @param input One of the flags <code>yes/no</code> or <code>on/off</code>. */ def setDeprecation(input: String) { if (Flag.isPermissible(input)) deprecation = Some("yes" == input || "on" == input) else error("Unknown deprecation flag '" + input + "'") } /** Set the <code>optimise</code> info attribute. * @param input One of the flags <code>yes/no</code> or <code>on/off</code>. */ def setOptimise(input: String) { if (Flag.isPermissible(input)) optimise = Some("yes" == input || "on" == input) else error("Unknown optimisation flag '" + input + "'") } /** Set the <code>unchecked</code> info attribute. * @param input One of the flags <code>yes/no</code> or <code>on/off</code>. */ def setUnchecked(input: String) { if (Flag.isPermissible(input)) unchecked = Some("yes" == input || "on" == input) else error("Unknown unchecked flag '" + input + "'") } /** Sets the <code>force</code> attribute. Used by Ant. * @param input The value for <code>force</code>. */ def setFailonerror(input: Boolean) { failonerror = input } /** Set the <code>scalacdebugging</code> info attribute. * @param input The specified flag */ def setScalacdebugging(input: Boolean) { scalacDebugging = input } def setAssemname(input: String) { assemname = Some(input) } def setAssemrefs(input: String) { assemrefs = Some(input) }/*============================================================================*\** Properties getters **\*============================================================================*/ /** Gets the value of the <code>classpath</code> attribute in a * Scala-friendly form. * @return The class path as a list of files. */ protected def getClasspath: List[File] = if (classpath.isEmpty) error("Member 'classpath' is empty.") else List.fromArray(classpath.get.list()).map(nameToFile) /** Gets the value of the <code>origin</code> attribute in a * Scala-friendly form. * @return The origin path as a list of files. */ protected def getOrigin: List[File] = if (origin.isEmpty) error("Member 'origin' is empty.") else List.fromArray(origin.get.list()).map(nameToFile) /** Gets the value of the <code>destination</code> attribute in a * Scala-friendly form. * @return The destination as a file. */ protected def getDestination: File = if (destination.isEmpty) error("Member 'destination' is empty.") else existing(getProject().resolveFile(destination.get.toString)) /** Gets the value of the <code>sourcepath</code> attribute in a * Scala-friendly form. * @return The source path as a list of files. */ protected def getSourcepath: List[File] = if (sourcepath.isEmpty) error("Member 'sourcepath' is empty.") else List.fromArray(sourcepath.get.list()).map(nameToFile) /** Gets the value of the <code>bootclasspath</code> attribute in a * Scala-friendly form. * @return The boot class path as a list of files. */ protected def getBootclasspath: List[File] = if (bootclasspath.isEmpty) error("Member 'bootclasspath' is empty.") else List.fromArray(bootclasspath.get.list()).map(nameToFile) /** Gets the value of the <code>extdirs</code> attribute in a * Scala-friendly form. * @return The extensions path as a list of files. */ protected def getExtdirs: List[File] = if (extdirs.isEmpty) error("Member 'extdirs' is empty.") else List.fromArray(extdirs.get.list()).map(nameToFile)/*============================================================================*\** Compilation and support methods **\*============================================================================*/ /** This is forwarding method to circumvent bug #281 in Scala 2. Remove when * bug has been corrected. */ override protected def getDirectoryScanner(baseDir: File) = super.getDirectoryScanner(baseDir) /** Transforms a string name into a file relative to the provided base * directory. * @param base A file pointing to the location relative to which the name * will be resolved. * @param name A relative or absolute path to the file as a string. * @return A file created from the name and the base file. */ protected def nameToFile(base: File)(name: String): File = existing(fileUtils.resolveFile(base, name)) /** Transforms a string name into a file relative to the build root * directory. * @param name A relative or absolute path to the file as a string. * @return A file created from the name. */ protected def nameToFile(name: String): File = existing(getProject().resolveFile(name)) /** Tests if a file exists and prints a warning in case it doesn't. Always * returns the file, even if it doesn't exist. * @param file A file to test for existance. * @return The same file. */ protected def existing(file: File): File = { if (!file.exists()) log("Element '" + file.toString + "' does not exist.", Project.MSG_WARN) file } /** Transforms a path into a Scalac-readable string. * @param path A path to convert. * @return A string-representation of the path like <code>a.jar:b.jar</code>. */ protected def asString(path: List[File]): String = path.map(asString).mkString(File.pathSeparator) /** Transforms a file into a Scalac-readable string. * @param path A file to convert. * @return A string-representation of the file like <code>/x/k/a.scala</code>. */ protected def asString(file: File): String = file.getAbsolutePath() /** Generates a build error. Error location will be the current task in the * ant file. * @param message A message describing the error. * @throws BuildException A build error exception thrown in every case. */ protected def error(message: String): Nothing = throw new BuildException(message, getLocation())/*============================================================================*\** Hooks for variants of Scala **\*============================================================================*/ protected val sourceEnding = ".scala" protected def newSettings(error: String=>Unit): Settings = new Settings(error) protected def newGlobal(settings: Settings, reporter: Reporter) = new Global(settings, reporter)/*============================================================================*\** The big execute method **\*============================================================================*/ /** Initializes settings and source files */ protected def initialize: (Settings, List[File]) = { // Tests if all mandatory attributes are set and valid. if (origin.isEmpty) error("Attribute 'srcdir' is not set.") if (getOrigin.isEmpty) error("Attribute 'srcdir' is not set.") if (!destination.isEmpty && !destination.get.isDirectory()) error("Attribute 'destdir' does not refer to an existing directory.") if (destination.isEmpty) destination = Some(getOrigin.head) val mapper = new GlobPatternMapper() mapper.setTo("*.class") mapper.setFrom("*" + sourceEnding) // Scans source directories to build up a compile lists. // If force is false, only files were the .class file in destination is // older than the .scala file will be used. val sourceFiles: List[File] = for { val originDir <- getOrigin val originFile <- { var includedFiles = getDirectoryScanner(originDir).getIncludedFiles() if (!force) { includedFiles = new SourceFileScanner(this). restrict(includedFiles, originDir, destination.get, mapper) } val list = List.fromArray(includedFiles) if (scalacDebugging && list.length > 0) log( list.mkString( "Compiling source file" + (if (list.length > 1) "s: " else ": "), ", ", " " ) + "to " + getDestination.toString ) else if (list.length > 0) log( "Compiling " + list.length + " source file" + (if (list.length > 1) "s" else "") + (" to " + getDestination.toString) ) else log("No files selected for compilation", Project.MSG_VERBOSE) list } } yield { log(originFile, Project.MSG_DEBUG) nameToFile(originDir)(originFile) } // Builds-up the compilation settings for Scalac with the existing Ant // parameters. val settings = newSettings(error) settings.outdir.value = asString(destination.get) if (!classpath.isEmpty) settings.classpath.value = asString(getClasspath) if (!sourcepath.isEmpty) settings.sourcepath.value = asString(getSourcepath) else if (origin.get.size() > 0) settings.sourcepath.value = origin.get.list()(0) if (!bootclasspath.isEmpty) settings.bootclasspath.value = asString(getBootclasspath) if (!extdirs.isEmpty) settings.extdirs.value = asString(getExtdirs) if (!encoding.isEmpty) settings.encoding.value = encoding.get if (!backend.isEmpty) settings.target.value = backend.get if (!logging.isEmpty && logging.get == "verbose") settings.verbose.value = true else if (!logging.isEmpty && logging.get == "debug") { settings.verbose.value = true settings.debug.value = true } if (!logPhase.isEmpty) settings.log.value = logPhase if (!debugInfo.isEmpty) settings.debuginfo.value = debugInfo.get if (!deprecation.isEmpty) settings.deprecation.value = deprecation.get if (!optimise.isEmpty) settings.XO.value = optimise.get if (!unchecked.isEmpty) settings.unchecked.value = unchecked.get if (!assemname.isEmpty) settings.assemname.value = assemname.get if (!assemrefs.isEmpty) settings.assemrefs.value = assemrefs.get log("Scalac params = '" + addParams + "'", Project.MSG_DEBUG) var args = if (addParams.trim() == "") Nil else List.fromArray(addParams.trim().split(" ")).map(_.trim()) while (!args.isEmpty) { val argsBuf = args if (args.head startsWith "-") { for (setting <- settings.allSettings) args = setting.tryToSet(args); } else error("Parameter '" + args.head + "' does not start with '-'.") if (argsBuf eq args) error("Parameter '" + args.head + "' is not recognised by Scalac.") } (settings, sourceFiles) } /** Performs the compilation. */ override def execute() { val (settings, sourceFiles) = initialize if (sourceFiles.isEmpty) { return } val reporter = new ConsoleReporter(settings) // Compiles the actual code val compiler = newGlobal(settings, reporter) try { (new compiler.Run).compile(sourceFiles.map (_.toString)) } catch { case exception: Throwable if (exception.getMessage ne null) => exception.printStackTrace() error("Compile failed because of an internal compiler error (" + exception.getMessage + "); see the error output for details.") case exception => exception.printStackTrace() error("Compile failed because of an internal compiler error " + "(no error message provided); see the error output for details.") } reporter.printSummary() if (reporter.hasErrors) { val msg = "Compile failed with " + reporter.ERROR.count + " error" + (if (reporter.ERROR.count > 1) "s" else "") + "; see the compiler error output for details." if (failonerror) error(msg) else log(msg) } else if (reporter.WARNING.count > 0) log( "Compile suceeded with " + reporter.WARNING.count + " warning" + (if (reporter.WARNING.count > 1) "s" else "") + "; see the compiler output for details.") }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -