1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
|
/* NSC -- new Scala compiler
* Copyright 2005-2007 LAMP/EPFL
* @author Martin Odersky
*/
// $Id$
package scala.tools.nsc
import java.lang.System
import java.io.File
class Settings(error: String => unit) {
private var allsettings: List[Setting] = List()
private def getProperty(name: String): String =
if (System.getProperty(name) != "")
System.getProperty(name)
else null
private val classpathDefault =
if (System.getProperty("env.classpath") ne null)
alternatePath(
getProperty("env.classpath"),
".")
else getProperty("java.class.path")
private val bootclasspathDefault =
alternatePath(
concatPath(
getProperty("sun.boot.class.path"),
guessedScalaBootClassPath),
"")
private val extdirsDefault =
alternatePath(
concatPath(
getProperty("java.ext.dirs"),
guessedScalaExtDirs),
"")
private def alternatePath(p1: String, p2: => String) =
if (p1 ne null) p1 else p2
private def concatPath(p1: String, p2: String) =
if ((p1 ne null) && (p2 ne null)) p1 + File.pathSeparator + p2
else if (p1 ne null) p1
else p2
private def guessedScalaBootClassPath = {
val scalaHome = System.getProperty("scala.home")
if (scalaHome ne null) {
val guessJar = new File(new File(new File(scalaHome), "lib"), "scala-library.jar")
if (guessJar.exists()) guessJar.getPath()
else {
val guessDir = new File(new File(new File(scalaHome), "lib"), "library")
if (guessDir.exists()) guessDir.getPath() else null
}
} else null
}
private def guessedScalaExtDirs = {
val scalaHome = System.getProperty("scala.home")
if (scalaHome ne null) {
val guess = new File(new File(scalaHome), "lib")
if (guess.exists()) guess.getPath else null
} else null
}
private val encodingDefault =
//java.nio.charset.Charset.defaultCharset.name() // bq: this exists only in Java1.5 :-(
new java.io.OutputStreamWriter(
new java.io.ByteArrayOutputStream()).getEncoding
private val windowtitleDefault = "Scala Library Documentation"
private val documenttitleDefault = "Scala 2"
val doc = new BooleanSetting("-doc", "Generate documentation") { override def hiddenToIDE = true }
val debuginfo = new DebugSetting("-g", "Generate debugging info", List("none", "source", "line", "vars", "notc"), "vars", "vars")
val nowarnings = BooleanSetting("-nowarn", "Generate no warnings")
val noassertions = BooleanSetting("-noassert", "Generate no assertions and assumptions")
val verbose = BooleanSetting("-verbose", "Output messages about what the compiler is doing")
val classpath = StringSetting ("-classpath", "path", "Specify where to find user class files", classpathDefault)
classpath.abbreviation = "-cp"
val sourcepath = StringSetting ("-sourcepath", "path", "Specify where to find input source files", "")
val bootclasspath = StringSetting ("-bootclasspath", "path", "Override location of bootstrap class files", bootclasspathDefault)
val extdirs = StringSetting ("-extdirs", "dirs", "Override location of installed extensions", extdirsDefault)
val outdir = StringSetting ("-d", "directory", "Specify where to place generated class files", ".")
val encoding = new StringSetting ("-encoding", "encoding", "Specify character encoding used by source files", encodingDefault) { override def hiddenToIDE = false }
val windowtitle = StringSetting ("-windowtitle", "windowtitle", "Specify window title of generated HTML documentation", windowtitleDefault)
val documenttitle = StringSetting ("-documenttitle", "documenttitle", "Specify document title of generated HTML documentation", documenttitleDefault)
val target = ChoiceSetting ("-target", "Specify which backend to use", List("jvm-1.5", "jvm-1.4", "msil", "cldc"), "jvm-1.4")
val migrate = BooleanSetting("-migrate", "Assist in migrating from Scala version 1.0")
val debug = new BooleanSetting("-debug", "Output debugging messages") { override def hiddenToIDE = true }
val deprecation = BooleanSetting ("-deprecation", "enable detailed deprecation warnings")
val unchecked = BooleanSetting ("-unchecked", "enable detailed unchecked warnings")
val statistics = new BooleanSetting("-statistics", "Print compiler statistics") { override def hiddenToIDE = true }
val explaintypes = BooleanSetting("-explaintypes", "Explain type errors in more detail")
val resident = new BooleanSetting("-resident", "Compiler stays resident, files to compile are read from standard input") { override def hiddenToIDE = true }
val uniqid = BooleanSetting("-uniqid", "Print identifiers with unique names (debugging option)")
val printtypes = new BooleanSetting("-printtypes", "Print tree types (debugging option)") { override def hiddenToIDE = true }
val prompt = new BooleanSetting("-prompt", "Display a prompt after each error (debugging option)") { override def hiddenToIDE = true }
val noimports = BooleanSetting("-noimports", "Compile without any implicit imports")
val nopredefs = BooleanSetting("-nopredefs", "Compile without any implicit predefined values")
val skip = PhasesSetting ("-skip", "Skip")
val check = PhasesSetting ("-check", "Check the tree at start of")
val print = PhasesSetting ("-print", "Print out program after")
val printer = ChoiceSetting ("-printer", "Printer to use", List("text", "html"), "text")
val printfile = StringSetting ("-printfile", "file", "Specify file in which to print trees", "-")
val graph = PhasesSetting ("-graph", "Graph the program after")
val browse = PhasesSetting ("-browse", "Browse the abstract syntax tree after")
val stop = PhasesSetting ("-stop", "Stop after phase")
val log = PhasesSetting ("-log", "Log operations in")
val version = new BooleanSetting("-version", "Print product version and exit") { override def hiddenToIDE = true }
val help = new BooleanSetting("-help", "Print a synopsis of standard options") { override def hiddenToIDE = true }
val nouescape = new BooleanSetting("-nouescape", "disables handling of \\u unicode escapes")
// val showPhases = BooleanSetting("-showphases", "Print a synopsis of compiler phases")
val inline = BooleanSetting("-Xinline", "Perform inlining when possible")
val Xcloselim = BooleanSetting("-Xcloselim", "Perform closure elimination")
val Xdce = BooleanSetting("-Xdce", "Perform dead code elimination")
val XbytecodeRead = BooleanSetting("-XbytecodeRead", "Enable bytecode reader.")
val Xdetach = BooleanSetting("-Xdetach", "Perform detaching of remote closures")
val Xshowcls = StringSetting ("-Xshowcls", "class", "Show class info", "")
val Xshowobj = StringSetting ("-Xshowobj", "object", "Show object info", "")
val Xlinearizer = ChoiceSetting ("-Xlinearizer", "Linearizer to use", List("normal", "dfs", "rpo", "dump"), "rpo")
val Xgenerics = BooleanSetting("-Xgenerics", "Use generic Java types")
val Xprintpos = BooleanSetting("-Xprintpos", "Print tree positions (as offsets)")
val Xscript = new BooleanSetting("-Xscript", "compile script file") { override def hiddenToIDE = true }
val Xexperimental = BooleanSetting("-Xexperimental", "enable experimental extensions")
val Xunapply = BooleanSetting("-Xunapply", "enable unapply pattern matching")
Xunapply.value = true
val Xplugtypes = BooleanSetting("-Xplugtypes", "parse but ignore annotations in more locations")
val Xkilloption = BooleanSetting("-Xkilloption", "optimizes option types")
val XprintOuterMatches = BooleanSetting("-XprintOuterMatches", "prints outer-checks caused by pattern matching")
/** A list of all settings */
def allSettings: List[Setting] = allsettings.reverse
/** Disable a setting */
def disable(s: Setting) = {
allsettings = allsettings filter (s !=)
}
/** A base class for settings of all types.
* Subclasses each define a `value' field of the appropriate type.
*/
abstract class Setting(val name: String, descr: String) {
/** If first arg defines this setting, consume it as well as all following
* args needed to define the setting. If this can be done without
* error, set value field and return suffix of args else
* issue error message and return empty.
* If first arg does not define this setting return args unchanged.
*/
def tryToSet(args: List[String]): List[String]
/** The syntax defining this setting in a help string */
def helpSyntax: String = name
/** A description of the purpose of this setting in a help string */
def helpDescription = descr
/** Return a list of strings that can be used to recreate
* the receiver's current setting.
*/
def unparse: List[String]
/** override if option should be hidden from IDE.
*/
def hiddenToIDE : Boolean = false
// initialization
allsettings = this :: allsettings
}
/** A setting represented by a boolean flag (false, unless set) */
case class BooleanSetting(nme: String, descr: String)
extends Setting(nme, descr) {
var value: boolean = false
def tryToSet(args: List[String]): List[String] = args match {
case n :: rest if (n == name) => value = true; rest
case _ => args
}
def unparse: List[String] =
if (value)
List(name)
else
Nil
}
/** A setting represented by a string, (`default' unless set) */
case class StringSetting(nme: String, arg: String, descr: String, default: String)
extends Setting(nme, descr) {
override def hiddenToIDE = true;
var abbreviation: String = null
var value: String = default
def tryToSet(args: List[String]): List[String] = args match {
case n :: rest if (name == n || abbreviation == n) =>
if (rest.isEmpty) {
error("missing argument")
List()
} else {
value = rest.head
rest.tail
}
case _ => args
}
override def helpSyntax = name + " <" + arg + ">"
def unparse: List[String] =
if (value == default)
Nil
else
List(name, value)
}
/** A setting represented by a string in a given set of <code>choices</code>,
* (<code>default</code> unless set).
*/
case class ChoiceSetting(nme: String, descr: String, choices: List[String], default: String)
extends Setting(nme, descr + choices.mkString(" (", ",", ")")) {
protected var v: String = default
def value: String = this.v
def value_=(s: String): Unit = this.v = s;
protected def argument: String = name.substring(1)
def tryToSet(args: List[String]): List[String] = args match {
case n :: rest if (n startsWith (name + ":")) =>
val choice = n.substring(name.length() + 1)
if (!(choices contains choice)) {
error(
if (choice == "") "missing " + argument
else "unknown " + argument + " '" + choice + "'")
args
} else {
value = choice
rest
}
case _ => args
}
override def helpSyntax = name + ":<" + argument + ">"
def unparse: List[String] =
if (value == default)
Nil
else
List(name + ":" + value)
}
/** Same as ChoiceSetting but have a <code>level</code> int which tells the
* index of the selected choice. The <code>defaultEmpty</code> is used when
* this setting is used without specifying any of the available choices.
*/
class DebugSetting(nme: String, descr: String, choices: List[String], default: String, defaultEmpty: String)
extends ChoiceSetting(nme, descr, choices, default) {
def indexOf[a](xs: List[a], e: a): Option[Int] = xs match {
case y :: ys => if (e == y) Some(0) else indexOf(ys, e) match {
case Some(idx) => Some(1 + idx)
case None => None
}
case _ => None
}
var level: Int = indexOf(choices, default).get;
override def value_=(choice: String): Unit = {
this.v = choice
this.level = indexOf(choices, choice).get
}
override def tryToSet(args: List[String]): List[String] = args match {
case n :: rest if (n startsWith (name + ":")) =>
val choice = n.substring(name.length() + 1)
if (!(choices contains choice)) {
error(
if (choice == "") "missing " + argument
else "unknown " + argument + " '" + choice + "'")
args
} else {
value = choice
rest
}
case n :: rest if (n startsWith name) =>
value = defaultEmpty
rest
case _ => args
}
}
/** A setting represented by a list of strings which should be prefixes of
* phase names. This is not checked here, however.
* (the empty list, unless set)
*/
case class PhasesSetting(nme: String, descr: String)
extends Setting(nme, descr + " <phase>") { // (see -showphases)") {
override def hiddenToIDE = true
var value: List[String] = List()
def tryToSet(args: List[String]): List[String] = args match {
case n :: rest if (n startsWith (name + ":")) =>
val phase = n.substring(name.length() + 1)
if (phase == "") {
error("missing phase")
List()
} else {
value = value ::: List(phase)
rest
}
case _ => args
}
override def helpSyntax = name + ":<phase>"
def contains(phasename: String): boolean =
value exists (str => phasename startsWith str)
def unparse: List[String] =
(value.foldLeft[List[String]]
(Nil)
((args, phase) =>
List(name + ":" + phase) ::: args))
}
}
|