Skip to content

Conversation

@artemcm
Copy link

@artemcm artemcm commented Oct 20, 2025

This library provides support for a mechanism to control the behavior of specific diagnostic groups for a given declaration's lexical scope with the @warn attribute.

The syntax tree and its parser do not reason about warning group controls. The syntax tree produced by the parser reprsents the @warn attribute in a generic fashion, as it would any other basic attribute on a declaration. The per-declaration nature of the attribute means that for any given declaration's lexical scope, the behavior of a given diagnosic group can be queried by checking for the presence of this attribute in its parent declaration scope.

The SwiftWarningControl library provides a utility to determine, for a given source location and diagnostic group identifier, whether or not its behavior is affected by an @warn attribute of any of its parent declaration scope.

This utility relies on constructing a warning control tree data structure to represent all warning control lexical scopes in a given source file. This data structure all of the @warn diagnostic group behavior controls within the given syntax node, indicating each group's active behavior at a given position.

For example, given code like the following:

1:  @warn(Deprecate, as: error)
2:  func foo() {
3:     let a = dep
4:     @warn(Deprecate, as: warning)
5:     func bar() {
6:         let b = dep
7:         @warn(Deprecate, as: ignored)
8:         func baz() {
9:           let c = dep
10:        }
11:        @warn(Deprecate, as: error)
12:        @warn(OtherGroup, as: ignored)
13:        func qux() {
14:            let d = dep
15:            @warn(SomeOtherGroup, as: warning)
16:            func corge() {
17:              let e = dep
18:            }
19:        }
20:     }
21: }

the result will be:

  - [`Deprecate`:`error`] region within `foo` lexical scope (lines 1-22)
    - [`Deprecate`:`warning`] region within `bar` lexical scope (lines 4-20)
      - [`Deprecate`:`ignored`] region within `baz` lexical scope (lines 7-10)
      - [`Deprecate`:`error`, `OtherGroup`:`ignored`] region within `qux` lexical scope (lines 12-19)
        - [`SomeOtherGroup`:`warning`] region within `corge` lexical scope (lines 15-18)

The data structure represents these regions and their nesting relationships as an interval tree where interval nodes can only be nested or disjoint, and where a given interval corresponds to a diagnostic control region for one or more diagnostic group, with a behavior specifier for each.

Intervals cannot partially overlap, and each node's child intervals are always kept sorted. The tree has a single top-level node (root) representing file-level scope.

Once the tree is computed, lookup of a diagnostic group behavior at a given position is performed by recursively descending into the child node containing the given position (located with a binary search of child nodes of a given parent node). Once the position's depth in the interval tree is reached, we walk back the traversal until we find the first containing region which specifies warning behavior control for the given diagnostic group id.

@artemcm artemcm marked this pull request as ready for review October 20, 2025 15:59
@artemcm artemcm force-pushed the WarningControlScopes branch 2 times, most recently from becf8ff to 463a525 Compare October 20, 2025 17:01
@artemcm artemcm requested a review from DougGregor October 20, 2025 17:47
@artemcm artemcm force-pushed the WarningControlScopes branch from 463a525 to 150b44d Compare October 20, 2025 18:14
@artemcm
Copy link
Author

artemcm commented Oct 20, 2025

@swift-ci test

@artemcm
Copy link
Author

artemcm commented Oct 20, 2025

@swift-ci test Windows platform

@artemcm artemcm force-pushed the WarningControlScopes branch 2 times, most recently from 6a783d7 to 8d6686c Compare October 21, 2025 18:13
@artemcm
Copy link
Author

artemcm commented Oct 21, 2025

Thanks for the detailed feedback so far, @ahoppen !

@artemcm artemcm force-pushed the WarningControlScopes branch from 8d6686c to 21ebbba Compare October 21, 2025 18:26
@artemcm
Copy link
Author

artemcm commented Oct 21, 2025

@swift-ci test

1 similar comment
@artemcm
Copy link
Author

artemcm commented Oct 21, 2025

@swift-ci test

@artemcm artemcm force-pushed the WarningControlScopes branch 5 times, most recently from f67dccb to 89d0342 Compare October 22, 2025 18:29
Copy link
Member

@ahoppen ahoppen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just two small comment

…oup behavior settings

This library provides support for a mechanism to control the behavior of specific diagnostic groups for a given declaration's lexical scope with the `@warn` attribute.

The syntax tree and its parser do not reason about warning group controls. The syntax tree produced by the parser reprsents the `@warn` attribute in a generic fashion, as it would any other basic attribute on a declaration. The per-declaration nature of the attribute means that for any given declaration's lexical scope, the behavior of a given diagnosic group can be queried by checking for the presence of this attribute in its parent declaration scope.

The `SwiftWarningControl` library provides a utility to determine, for a given source location and diagnostic group identifier, whether or not its behavior is affected by an `@warn` attribute of any of its parent declaration scope.

This utility relies on constructing a warning control tree data structure to represent all warning control lexical scopes in a given source file. This data structure all of the `@warn` diagnostic group behavior controls within the given syntax node, indicating each group's active behavior at a given position.

For example, given code like the following:
```
1:  @warn(Deprecate, as: error)
2:  func foo() {
3:     let a = dep
4:     @warn(Deprecate, as: warning)
5:     func bar() {
6:         let b = dep
7:         @warn(Deprecate, as: ignored)
8:         func baz() {
9:           let c = dep
10:        }
11:        @warn(Deprecate, as: error)
12:        @warn(OtherGroup, as: ignored)
13:        func qux() {
14:            let d = dep
15:            @warn(SomeOtherGroup, as: warning)
16:            func corge() {
17:              let e = dep
18:            }
19:        }
20:     }
21: }
22: func grault() {
23:   let f = dep
24: }
```
the result will be:
```
  - [`Deprecate`:`error`] region within `foo` lexical scope (lines 1-22)
    - [`Deprecate`:`warning`] region within `bar` lexical scope (lines 4-20)
      - [`Deprecate`:`ignored`] region within `baz` lexical scope (lines 7-10)
      - [`Deprecate`:`error`, `OtherGroup`:`ignored`] region within `qux` lexical scope (lines 12-19)
        - [`SomeOtherGroup`:`warning`] region within `corge` lexical scope (lines 15-18)
```

The data structure represents these regions and their nesting relationships as an interval tree where interval nodes can only be nested or disjoint, and where a given interval corresponds to a diagnostic control region for one or more diagnostic group, with a behavior specifier for each.

Intervals cannot partially overlap, and each node's child intervals are always kept sorted. The tree has multiple top-level nodes (roots) representing file-level warning control regions.

Once the tree is computed, lookup of a diagnostic group behavior at a given position is performed by recursively descending into the child node containing the given position (located with a binary search of child nodes of a given parent node). Once the position's depth in the interval tree is reached, we walk back the traversal until we find the first containing region which specifies warning behavior control for the given diagnostic group id.
@artemcm artemcm force-pushed the WarningControlScopes branch from 89d0342 to a92c94c Compare October 23, 2025 20:07
@artemcm
Copy link
Author

artemcm commented Oct 23, 2025

@swift-ci test

@artemcm
Copy link
Author

artemcm commented Oct 23, 2025

@swift-ci test Windows platform

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants