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
|
/* NSC -- new Scala compiler
* Copyright 2005-2012 LAMP/EPFL
* @author Paul Phillips
*/
package scala.tools.nsc
package settings
/** A Settings abstraction boiled out of the original highly mutable Settings
* class with the intention of creating an ImmutableSettings which can be used
* interchangeably. Except of course without the mutants.
*/
trait AbsSettings extends scala.reflect.internal.settings.AbsSettings {
type Setting <: AbsSetting // Fix to the concrete Setting type
type ResultOfTryToSet // List[String] in mutable, (Settings, List[String]) in immutable
def errorFn: String => Unit
protected def allSettings: collection.Set[Setting]
// settings minus internal usage settings
def visibleSettings = allSettings filterNot (_.isInternalOnly)
// only settings which differ from default
def userSetSettings = visibleSettings filterNot (_.isDefault)
// an argument list which (should) be usable to recreate the Settings
def recreateArgs = userSetSettings.toList flatMap (_.unparse)
// checks both name and any available abbreviations
def lookupSetting(cmd: String): Option[Setting] = allSettings find (_ respondsTo cmd)
// two AbsSettings objects are equal if their visible settings are equal.
override def hashCode() = visibleSettings.size // going for cheap
override def equals(that: Any) = that match {
case s: AbsSettings => this.userSetSettings == s.userSetSettings
case _ => false
}
override def toString() = "Settings {\n%s}\n" format (userSetSettings map (" " + _ + "\n")).mkString
def toConciseString = userSetSettings.mkString("(", " ", ")")
def checkDependencies =
visibleSettings filterNot (_.isDefault) forall (setting => setting.dependencies forall {
case (dep, value) =>
(Option(dep.value) exists (_.toString == value)) || {
errorFn("incomplete option %s (requires %s)".format(setting.name, dep.name))
false
}
})
implicit lazy val SettingOrdering: Ordering[Setting] = Ordering.ordered
trait AbsSetting extends Ordered[Setting] with AbsSettingValue {
def name: String
def helpDescription: String
def unparse: List[String] // A list of Strings which can recreate this setting.
/* For tools which need to populate lists of available choices */
def choices : List[String] = Nil
/** In mutable Settings, these return the same object with a var set.
* In immutable, of course they will return a new object, which means
* we can't use "this.type", at least not in a non-casty manner, which
* is unfortunate because we lose type information without it.
*
* ...but now they're this.type because of #3462. The immutable
* side doesn't exist yet anyway.
*/
def withAbbreviation(name: String): this.type
def withHelpSyntax(help: String): this.type
def withDeprecationMessage(msg: String): this.type
def helpSyntax: String = name
def deprecationMessage: Option[String] = None
def abbreviations: List[String] = Nil
def dependencies: List[(Setting, String)] = Nil
def respondsTo(label: String) = (name == label) || (abbreviations contains label)
/** If the setting should not appear in help output, etc. */
private var internalSetting = false
def isInternalOnly = internalSetting
def internalOnly(): this.type = {
internalSetting = true
this
}
/** If the appearance of the setting should halt argument processing. */
private var isTerminatorSetting = false
def shouldStopProcessing = isTerminatorSetting
def stopProcessing(): this.type = {
isTerminatorSetting = true
this
}
/** Issue error and return */
def errorAndValue[T](msg: String, x: T): T = { errorFn(msg) ; x }
/** After correct Setting has been selected, tryToSet is called with the
* remainder of the command line. It consumes any applicable arguments and
* returns the unconsumed ones.
*/
protected[nsc] def tryToSet(args: List[String]): Option[ResultOfTryToSet]
/** Commands which can take lists of arguments in form -Xfoo:bar,baz override
* this method and accept them as a list. It returns List[String] for
* consistency with tryToSet, and should return its incoming arguments
* unmodified on failure, and Nil on success.
*/
protected[nsc] def tryToSetColon(args: List[String]): Option[ResultOfTryToSet] =
errorAndValue("'%s' does not accept multiple arguments" format name, None)
/** Attempt to set from a properties file style property value.
* Currently used by Eclipse SDT only.
*/
def tryToSetFromPropertyValue(s: String): Unit = tryToSet(s :: Nil)
/** These categorizations are so the help output shows -X and -P among
* the standard options and -Y among the advanced options.
*/
def isAdvanced = name match { case "-Y" => true ; case "-X" => false ; case _ => name startsWith "-X" }
def isPrivate = name match { case "-Y" => false ; case _ => name startsWith "-Y" }
def isStandard = !isAdvanced && !isPrivate
def isForDebug = name endsWith "-debug" // by convention, i.e. -Ytyper-debug
def isDeprecated = deprecationMessage.isDefined
def compare(that: Setting): Int = name compare that.name
/** Equality tries to sidestep all the drama and define it simply and
* in one place: two AbsSetting objects are equal if their names and
* values compare equal.
*/
override def equals(that: Any) = that match {
case x: AbsSettings#AbsSetting => (name == x.name) && (value == x.value)
case _ => false
}
override def hashCode() = name.hashCode + value.hashCode
override def toString() = name + " = " + value
}
trait InternalSetting extends AbsSetting {
override def isInternalOnly = true
}
}
|