Skip to content

Commit 4f40ecd

Browse files
committed
Support src filter in -WConf (Closes #18782)
1 parent c7a0459 commit 4f40ecd

File tree

3 files changed

+115
-1
lines changed

3 files changed

+115
-1
lines changed

Diff for: compiler/src/dotty/tools/dotc/config/ScalaSettings.scala

+4
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,9 @@ private sealed trait WarningSettings:
252252
| - Message name: name=PureExpressionInStatementPosition
253253
| The message name is printed with the warning in verbose warning mode.
254254
|
255+
| - Source location: src=regex
256+
| The regex is evaluated against the full source path.
257+
|
255258
|In verbose warning mode the compiler prints matching filters for warnings.
256259
|Verbose mode can be enabled globally using `-Wconf:any:verbose`, or locally
257260
|using the @nowarn annotation (example: `@nowarn("v") def test = try 1`).
@@ -271,6 +274,7 @@ private sealed trait WarningSettings:
271274
|Examples:
272275
| - change every warning into an error: -Wconf:any:error
273276
| - silence deprecations: -Wconf:cat=deprecation:s
277+
| - silence warnings in src_managed directory: -Wconf:src=src_managed/.*:s
274278
|
275279
|Note: on the command-line you might need to quote configurations containing `*` or `&`
276280
|to prevent the shell from expanding patterns.""".stripMargin,

Diff for: compiler/src/dotty/tools/dotc/reporting/WConf.scala

+14-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ package reporting
55
import scala.language.unsafeNulls
66

77
import dotty.tools.dotc.core.Contexts.*
8-
import dotty.tools.dotc.util.SourcePosition
8+
import dotty.tools.dotc.util.{NoSourcePosition, SourcePosition}
9+
import dotty.tools.dotc.interfaces.SourceFile
10+
import dotty.tools.dotc.reporting.MessageFilter.SourcePattern
911

1012
import java.util.regex.PatternSyntaxException
1113
import scala.annotation.internal.sharable
@@ -21,11 +23,19 @@ enum MessageFilter:
2123
val noHighlight = message.msg.message.replaceAll("\\e\\[[\\d;]*[^\\d;]","")
2224
pattern.findFirstIn(noHighlight).nonEmpty
2325
case MessageID(errorId) => message.msg.errorId == errorId
26+
case SourcePattern(pattern) =>
27+
val source = message.position.orElse(NoSourcePosition).source()
28+
val path = source.jfile()
29+
.map(_.toPath.toAbsolutePath.toUri.normalize().getRawPath)
30+
.orElse(source.path())
31+
pattern.findFirstIn(path).nonEmpty
32+
2433
case None => false
2534

2635
case Any, Deprecated, Feature, Unchecked, None
2736
case MessagePattern(pattern: Regex)
2837
case MessageID(errorId: ErrorMessageID)
38+
case SourcePattern(pattern: Regex)
2939

3040
enum Action:
3141
case Error, Warning, Verbose, Info, Silent
@@ -84,6 +94,9 @@ object WConf:
8494
case "feature" => Right(Feature)
8595
case "unchecked" => Right(Unchecked)
8696
case _ => Left(s"unknown category: $conf")
97+
98+
case "src" => regex(conf).map(SourcePattern.apply)
99+
87100
case _ => Left(s"unknown filter: $filter")
88101
case _ => Left(s"unknown filter: $s")
89102

Diff for: compiler/test/dotty/tools/dotc/config/ScalaSettingsTests.scala

+97
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ import Settings._
77
import org.junit.Test
88
import org.junit.Assert._
99
import core.Decorators.toMessage
10+
import dotty.tools.io.{Path, PlainFile}
11+
12+
import java.net.URI
13+
import java.nio.file.Files
14+
import scala.util.Using
1015

1116
class ScalaSettingsTests:
1217

@@ -96,5 +101,97 @@ class ScalaSettingsTests:
96101
assertEquals(Action.Silent, sut.action(depr))
97102

98103

104+
private def wconfSrcFilterTest(argsStr: String,
105+
expectedOutcome: Either[List[String], reporting.Action],
106+
warning: reporting.Diagnostic.Warning): Unit =
107+
import reporting.Diagnostic
108+
val settings = new ScalaSettings
109+
val args = ArgsSummary(settings.defaultState, List(argsStr), errors = Nil, warnings = Nil)
110+
val proc = settings.processArguments(args, processAll = true, skipped = Nil)
111+
val wconfStr = settings.Wconf.valueIn(proc.sstate)
112+
val wconf = reporting.WConf.fromSettings(wconfStr)
113+
assertEquals(expectedOutcome, wconf.map(_.action(warning)))
114+
115+
@Test def `WConf src filter silences warnings from a matching path for virtual file`: Unit =
116+
wconfSrcFilterTest(
117+
argsStr = "-Wconf:src=path/.*:s",
118+
warning = reporting.Diagnostic.Warning(
119+
"A warning".toMessage,
120+
util.SourcePosition(
121+
source = util.SourceFile.virtual(new URI("file:///some/path/file.scala"), ""),
122+
span = util.Spans.Span(1L)
123+
)
124+
),
125+
expectedOutcome = Right(reporting.Action.Silent)
126+
)
127+
128+
@Test def `WConf src filter doesn't silence warnings from a non-matching path`: Unit =
129+
wconfSrcFilterTest(
130+
argsStr = "-Wconf:src=another/.*:s",
131+
warning = reporting.Diagnostic.Warning(
132+
"A warning".toMessage,
133+
util.SourcePosition(
134+
source = util.SourceFile.virtual(new URI("file:///some/path/file.scala"), ""),
135+
span = util.Spans.Span(1L)
136+
)
137+
),
138+
expectedOutcome = Right(reporting.Action.Warning)
139+
)
140+
141+
@Test def `WConf src filter silences warnings from a matching path for real file`: Unit =
142+
Using.resource(Files.createTempFile("myfile", ".scala").nn) { file =>
143+
wconfSrcFilterTest(
144+
argsStr = "-Wconf:src=myfile.*?\\.scala:s",
145+
warning = reporting.Diagnostic.Warning(
146+
"A warning".toMessage,
147+
util.SourcePosition(
148+
source = util.SourceFile(new PlainFile(Path(file)), "UTF-8"),
149+
span = util.Spans.Span(1L)
150+
)
151+
),
152+
expectedOutcome = Right(reporting.Action.Silent)
153+
)
154+
}(Files.deleteIfExists(_))
155+
156+
@Test def `WConf src filter doesn't silence warnings from a non-matching path for real file`: Unit =
157+
Using.resource(Files.createTempFile("myfile", ".scala").nn) { file =>
158+
wconfSrcFilterTest(
159+
argsStr = "-Wconf:src=another.*?\\.scala:s",
160+
warning = reporting.Diagnostic.Warning(
161+
"A warning".toMessage,
162+
util.SourcePosition(
163+
source = util.SourceFile(new PlainFile(Path(file)), "UTF-8"),
164+
span = util.Spans.Span(1L)
165+
)
166+
),
167+
expectedOutcome = Right(reporting.Action.Warning)
168+
)
169+
}(Files.deleteIfExists(_))
170+
171+
@Test def `WConf src filter reports an error on an invalid regex`: Unit =
172+
wconfSrcFilterTest(
173+
argsStr = """-Wconf:src=\:s""",
174+
warning = reporting.Diagnostic.Warning(
175+
"A warning".toMessage,
176+
util.SourcePosition(
177+
source = util.SourceFile.virtual(new URI("file:///some/path/file.scala"), ""),
178+
span = util.Spans.Span(1L)
179+
)
180+
),
181+
expectedOutcome = Left(List("invalid pattern `\\`: Unescaped trailing backslash near index 1\n\\"))
182+
)
183+
184+
@Test def `WConf src filter can be mixed with other filters with rightmost taking precedence`: Unit =
185+
wconfSrcFilterTest(
186+
argsStr = "-Wconf:src=.*:s,cat=deprecation:e",
187+
warning = reporting.Diagnostic.DeprecationWarning(
188+
"A warning".toMessage,
189+
util.SourcePosition(
190+
source = util.SourceFile.virtual(new URI("file:///some/path/file.scala"), ""),
191+
span = util.Spans.Span(1L)
192+
)
193+
),
194+
expectedOutcome = Right(reporting.Action.Error),
195+
)
99196

100197
end ScalaSettingsTests

0 commit comments

Comments
 (0)