From bc8fd0ac290d4f67afd21f9dbef1a87317827ca0 Mon Sep 17 00:00:00 2001 From: Artem Chikin Date: Thu, 30 Oct 2025 10:11:25 -0700 Subject: [PATCH] [SwiftWarningControl] Keep track of enabled diagnostic group identifiers And add public API on `WarningControlRegionTree` to query them: `getEnabledDiagnosticGroups`. This is intended to be used by clients (the compiler) to be able to query whether a given diagnostic group has been enabled in a given source file. --- .../WarningControlRegions.swift | 12 ++++++- .../WarningControlTests.swift | 34 +++++++++++++++++++ 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/Sources/SwiftWarningControl/WarningControlRegions.swift b/Sources/SwiftWarningControl/WarningControlRegions.swift index 54c035daa3e..5e045a160e7 100644 --- a/Sources/SwiftWarningControl/WarningControlRegions.swift +++ b/Sources/SwiftWarningControl/WarningControlRegions.swift @@ -103,8 +103,14 @@ public struct WarningControlRegionTree { /// Root region representing top-level (file) scope private var rootRegionNode: WarningControlRegionNode + /// All of the diagnostic group identifiers contained in this tree + /// which have at least one occurence with a non-`ignored` behavior + /// specifier + @_spi(ExperimentalLanguageFeatures) + public private(set) var enabledGroups: Set = [] + /// Inheritance tree among diagnostic group identifiers - let groupInheritanceTree: DiagnosticGroupInheritanceTree + private let groupInheritanceTree: DiagnosticGroupInheritanceTree init( range: Range, @@ -130,6 +136,10 @@ public struct WarningControlRegionTree { let groupIdentifier = groups.removeFirst() processedGroups.insert(groupIdentifier) newNode.addWarningGroupControl(for: groupIdentifier, control: control) + if control != .ignored { + enabledGroups.insert(diagnosticGroupIdentifier) + } + let newSubGroups = groupInheritanceTree.subgroups(of: groupIdentifier).filter { !processedGroups.contains($0) } // Ensure we add a corresponding control to each direct and // transitive sub-group of the one specified on this control. diff --git a/Tests/SwiftWarningControlTest/WarningControlTests.swift b/Tests/SwiftWarningControlTest/WarningControlTests.swift index ee07d4a5e5d..5ff48dd9594 100644 --- a/Tests/SwiftWarningControlTest/WarningControlTests.swift +++ b/Tests/SwiftWarningControlTest/WarningControlTests.swift @@ -75,6 +75,40 @@ public class WarningGroupControlTests: XCTestCase { ) } + func testEnabledGroupIdentifiers() throws { + let source = + """ + @warn(Group1, as: warning) + @warn(Group2, as: error) + @warn(Group3, as: ignored) + func foo() { + @warn(Group4, as: warning) + func bar() { + @warn(Group5, as: ignored) + @warn(Group6, as: ignored) + func baz() {} + @warn(Group7, as: error) + func qux() { + @warn(Group8, as: warning) + func corge() {} + } + } + } + """ + var parser = Parser(source) + let parseTree = SourceFileSyntax.parse(from: &parser) + let warningControlTree = parseTree.warningGroupControlRegionTree() + let enabledDiagnosticGroups = warningControlTree.enabledGroups + XCTAssertTrue(enabledDiagnosticGroups.contains("Group1")) + XCTAssertTrue(enabledDiagnosticGroups.contains("Group2")) + XCTAssertFalse(enabledDiagnosticGroups.contains("Group3")) + XCTAssertTrue(enabledDiagnosticGroups.contains("Group4")) + XCTAssertFalse(enabledDiagnosticGroups.contains("Group5")) + XCTAssertFalse(enabledDiagnosticGroups.contains("Group6")) + XCTAssertTrue(enabledDiagnosticGroups.contains("Group7")) + XCTAssertTrue(enabledDiagnosticGroups.contains("Group8")) + } + func testNominalDeclWarningGroupControl() throws { try assertWarningGroupControl( """