
scala.tools.nsc.settings.AbsSettings.scala Maven / Gradle / Ivy
/*
* Scala (https://www.scala-lang.org)
*
* Copyright EPFL and Lightbend, Inc.
*
* Licensed under Apache License 2.0
* (http://www.apache.org/licenses/LICENSE-2.0).
*
* See the NOTICE file distributed with this work for
* additional information regarding copyright ownership.
*/
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: scala.collection.Map[String, Setting]
// settings minus internal usage settings
def visibleSettings: List[Setting] = allSettings.valuesIterator.filterNot(_.isInternalOnly).toList
// only settings which differ from default
def userSetSettings: List[Setting] = visibleSettings.filterNot(_.isDefault)
// an argument list which (should) be usable to recreate the Settings
def recreateArgs: List[String] = userSetSettings flatMap (_.unparse)
// checks both name and any available abbreviations
def lookupSetting(cmd: String): Option[Setting] = allSettings.valuesIterator 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() = {
val uss = userSetSettings
val indent = if (uss.nonEmpty) " " * 2 else ""
uss.mkString(f"Settings {%n$indent", f"%n$indent", f"%n}%n")
}
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
}
})
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 scala/bug#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
}
/** Issue error and return the value. */
def errorAndValue[A](msg: String, x: A): A = { errorFn(msg) ; x }
/** If this method returns true, print the [[help]] message and exit. */
def isHelping: Boolean = false
/** The help message to be printed if [[isHelping]]. */
def help: String = ""
/** 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"'$name' does not accept multiple arguments", None)
/** Attempt to set from a properties file style property value.
* Currently used by Eclipse SDT only.
* !!! Needs test.
*/
def tryToSetFromPropertyValue(s: String): Unit = tryToSet(s :: Nil)
/** Standard options are shown on the `-help` output,
* advanced on `-X`, private on `-Y`, warning on `-W`, verbose on `-V`.
*
* The single char options themselves, including `-P`, are explained on `-help`.
* Additionally, `-Werror` is on `-help` and `-Xlint` on `-W`.
*/
def isAdvanced = name.startsWith("-X") && name != "-X"
def isPrivate = name.startsWith("-Y") && name != "-Y"
def isVerbose = name.startsWith("-V") && name != "-V"
def isWarning = name.startsWith("-W") && name != "-W" || name == "-Xlint"
def isStandard = !isAdvanced && !isPrivate && !isWarning && !isVerbose || name == "-Werror"
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 + " = " + (if (value == "") "\"\"" else value)
}
trait InternalSetting extends AbsSetting {
override def isInternalOnly = true
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy