@@ -29,11 +29,11 @@ object TpolecatPlugin extends AutoPlugin {
29
29
object autoImport {
30
30
object ScalacOptions extends ScalacOptions
31
31
32
- def scalacOptionsFor (
32
+ private [ TpolecatPlugin ] def supportedOptionsFor (
33
33
version : String ,
34
34
modeScalacOptions : Set [ScalacOption ]
35
- ): Seq [ String ] = {
36
- val supportedOptions = (CrossVersion .partialVersion(version), version.split('.' )) match {
35
+ ): Set [ ScalacOption ] = {
36
+ (CrossVersion .partialVersion(version), version.split('.' )) match {
37
37
case (Some ((0 , _)), _) => // dotty prereleases use 0 as major version
38
38
modeScalacOptions
39
39
.filter(_.isSupported(V3_0_0 )) // treat dotty prereleases as 3.0.0
@@ -47,8 +47,13 @@ object TpolecatPlugin extends AutoPlugin {
47
47
case (None , _) =>
48
48
Set .empty[ScalacOption ]
49
49
}
50
+ }
50
51
51
- supportedOptions.toList.flatMap(opt => opt.option :: opt.args)
52
+ def scalacOptionsFor (
53
+ version : String ,
54
+ modeScalacOptions : Set [ScalacOption ]
55
+ ): Seq [String ] = {
56
+ supportedOptionsFor(version, modeScalacOptions).toList.flatMap(opt => opt.option :: opt.args)
52
57
}
53
58
54
59
val tpolecatDefaultOptionsMode = settingKey[OptionsMode ](
@@ -90,6 +95,14 @@ object TpolecatPlugin extends AutoPlugin {
90
95
val tpolecatExcludeOptions = settingKey[Set [ScalacOption ]](
91
96
" The set of scalac options that will be excluded."
92
97
)
98
+
99
+ val tpolecatEffectiveScalacOptions = settingKey[Set [ScalacOption ]](
100
+ " The set of scalac options that will effectively be applied by the sbt-tpolecat. For internal use only."
101
+ ).withRank(sbt.KeyRanks .Invisible )
102
+
103
+ val tpolecatManagedScalacOptions = settingKey[Set [ScalacOption ]](
104
+ " The set of scalac options that sbt-tpolecat owns and manages. Defaults to anything it ever adds in any scope delegation chain."
105
+ ).withRank(sbt.KeyRanks .DSetting )
93
106
}
94
107
95
108
import autoImport ._
@@ -122,13 +135,60 @@ object TpolecatPlugin extends AutoPlugin {
122
135
tpolecatDevModeOptions := ScalacOptions .default
123
136
) ++ commandAliases
124
137
138
+ private def removeOption (options : List [String ], optionToRemove : ScalacOption ): List [String ] = {
139
+ val option = optionToRemove.option
140
+ val args = optionToRemove.args
141
+
142
+ if (args.isEmpty) {
143
+ // fast path
144
+ options.filterNot(_ == option)
145
+ } else {
146
+ def loop (options : List [String ]): List [String ] = options match {
147
+ case Nil => Nil
148
+ case `option` :: tail if tail.startsWith(args) => loop(tail.drop(args.size))
149
+ case head :: tail => head :: loop(tail)
150
+ }
151
+ loop(options)
152
+ }
153
+ }
154
+
155
+ private def addOption (options : List [String ], optionToAdd : ScalacOption ): List [String ] = {
156
+ val option = optionToAdd.option
157
+ val args = optionToAdd.args
158
+
159
+ if (args.isEmpty) {
160
+ // fast path
161
+ if (options.contains(option)) options
162
+ else options ::: option :: Nil
163
+ } else {
164
+ if (options.containsSlice(option :: args)) options
165
+ else options ::: option :: args
166
+ }
167
+ }
168
+
125
169
override def projectSettings : Seq [Setting [_]] = Seq (
126
170
Def .derive(
127
171
scalacOptions := {
172
+ val prevOptions = scalacOptions.value.toList
173
+ val managedOptions = tpolecatManagedScalacOptions.value
174
+ val effectiveOptions = tpolecatEffectiveScalacOptions.value
175
+
176
+ val optionsToRemove = managedOptions.diff(effectiveOptions)
177
+ val optionsToAdd = effectiveOptions
178
+
179
+ val optionsWithRemovals = optionsToRemove.foldLeft(prevOptions)(removeOption(_, _))
180
+ optionsToAdd.foldLeft(optionsWithRemovals)(addOption(_, _))
181
+ }
182
+ ),
183
+ Def .derive(
184
+ tpolecatManagedScalacOptions ++= tpolecatEffectiveScalacOptions.value
185
+ ),
186
+ Def .derive(
187
+ tpolecatEffectiveScalacOptions := {
128
188
val pluginOptions = tpolecatScalacOptions.value
129
189
val pluginExcludes = tpolecatExcludeOptions.value
130
190
val selectedOptions = pluginOptions.diff(pluginExcludes)
131
- scalacOptionsFor (scalaVersion.value, selectedOptions)
191
+ supportedOptionsFor (scalaVersion.value, selectedOptions)
132
192
}
133
193
),
134
194
Def .derive(
@@ -149,6 +209,7 @@ object TpolecatPlugin extends AutoPlugin {
149
209
)
150
210
151
211
override def globalSettings : Seq [Def .Setting [_]] = Seq (
212
+ tpolecatManagedScalacOptions := Set .empty,
152
213
tpolecatExcludeOptions := Set .empty
153
214
)
154
215
}
0 commit comments