11package dotty .tools .dotc
22package config
33
4- import collection .mutable .ArrayBuffer
5- import scala .util .{ Success , Failure }
6- import reflect .ClassTag
74import core .Contexts ._
8- import scala .annotation .tailrec
9- import dotty .tools .io .{ AbstractFile , Directory , JarArchive , PlainDirectory }
105
11- // import annotation.unchecked
12- // Dotty deviation: Imports take precedence over definitions in enclosing package
13- // (Note that @unchecked is in scala, not annotation, so annotation.unchecked gives
14- // us a package, which is not what was intended anyway).
6+ import dotty . tools . io .{ AbstractFile , Directory , JarArchive , PlainDirectory }
7+
8+ import annotation . tailrec
9+ import collection . mutable . ArrayBuffer
1510import language .existentials
11+ import reflect .ClassTag
12+ import scala .util .{Success , Failure }
1613
1714object Settings {
1815
@@ -25,7 +22,7 @@ object Settings {
2522 val OutputTag : ClassTag [AbstractFile ] = ClassTag (classOf [AbstractFile ])
2623
2724 class SettingsState (initialValues : Seq [Any ]) {
28- private var values = ArrayBuffer (initialValues : _* )
25+ private val values = ArrayBuffer (initialValues : _* )
2926 private var _wasRead : Boolean = false
3027
3128 override def toString : String = s " SettingsState(values: ${values.toList}) "
@@ -91,38 +88,46 @@ object Settings {
9188
9289 def isDefaultIn (state : SettingsState ): Boolean = valueIn(state) == default
9390
91+ def isMultivalue : Boolean = implicitly[ClassTag [T ]] == ListTag
92+
9493 def legalChoices : String =
95- if ( choices.isEmpty) " "
96- else choices match {
97- case r : Range => s " ${r.head}.. ${r.last}"
98- case xs : List [? ] => xs.mkString( " , " )
94+ choices match {
95+ case xs if xs.isEmpty => " "
96+ case r : Range => s " ${r.head}.. ${r.last}"
97+ case xs : List [? ] => xs.toString
9998 }
10099
101100 def isLegal (arg : Any ): Boolean =
102- if ( choices.isEmpty)
103- arg match {
104- case _ : T => true
105- case _ => false
106- }
107- else choices match {
101+ choices match {
102+ case xs if xs.isEmpty =>
103+ arg match {
104+ case _ : T => true
105+ case _ => false
106+ }
108107 case r : Range =>
109108 arg match {
110109 case x : Int => r.head <= x && x <= r.last
111110 case _ => false
112111 }
113112 case xs : List [? ] =>
114- xs contains arg
113+ xs. contains( arg)
115114 }
116115
117116 def tryToSet (state : ArgsSummary ): ArgsSummary = {
118117 val ArgsSummary (sstate, arg :: args, errors, warnings) = state
119118 def update (value : Any , args : List [String ]) =
120- if (changed)
121- ArgsSummary (updateIn(sstate, value), args, errors, warnings :+ s " Flag $name set repeatedly " )
122- else {
123- changed = true
124- ArgsSummary (updateIn(sstate, value), args, errors, warnings)
125- }
119+ var dangers = warnings
120+ val value1 =
121+ if changed && isMultivalue then
122+ val value0 = value.asInstanceOf [List [String ]]
123+ val current = valueIn(sstate).asInstanceOf [List [String ]]
124+ value0.filter(current.contains).foreach(s => dangers :+= s " Setting $name set to $s redundantly " )
125+ current ++ value0
126+ else
127+ if changed then dangers :+= s " Flag $name set repeatedly "
128+ value
129+ changed = true
130+ ArgsSummary (updateIn(sstate, value1), args, errors, dangers)
126131 def fail (msg : String , args : List [String ]) =
127132 ArgsSummary (sstate, args, errors :+ msg, warnings)
128133 def missingArg =
@@ -229,7 +234,7 @@ object Settings {
229234 *
230235 * to get their arguments.
231236 */
232- protected def processArguments (state : ArgsSummary , processAll : Boolean , skipped : List [String ]): ArgsSummary = {
237+ protected [config] def processArguments (state : ArgsSummary , processAll : Boolean , skipped : List [String ]): ArgsSummary = {
233238 def stateWithArgs (args : List [String ]) = ArgsSummary (state.sstate, args, state.errors, state.warnings)
234239 state.arguments match {
235240 case Nil =>
0 commit comments