Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SwiftIfConfig: A library to evaluate #if conditionals within a Swift syntax tree. #1816

Merged
merged 42 commits into from
Jul 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
746a64a
[SwiftIfConfig] Add a new library for evaluating `#if` conditions.
DougGregor Jun 5, 2023
719e0da
Add higher-level APIs for querying active code state
DougGregor Jun 5, 2023
cb7123f
Add support for evaluating `swift` and `compiler` conditionals
DougGregor Jun 13, 2023
979ebc0
Implement support for archaic `_compiler_version("X.Y.Z.W.V")` check
DougGregor Jun 18, 2023
4987cbc
Add support for `canImport` configuration checks.
DougGregor Jun 18, 2023
89c1f6f
Improve documentation for `#if` configuration functions
DougGregor Jun 19, 2023
5972065
Add `ActiveSyntax(Any)Visitor` visitor classes.
DougGregor Jun 19, 2023
c115be6
Add/cleanup some TODO comments
DougGregor Jun 19, 2023
623ffc7
Add an API to rewrite a syntax tree by removing inactive regions.
DougGregor Jun 19, 2023
2d2021f
Implement inactive clause rewriting support for postfix `#if`
DougGregor Jun 19, 2023
fc41db4
Add overview documentation for the SwiftIfConfig library
DougGregor Jun 20, 2023
f004511
Add CMake build system for SwiftIfConfig
DougGregor Jun 20, 2023
14b6718
Format source
DougGregor Jun 20, 2023
19ed1e8
Improve documentation for BuildConfiguration
DougGregor Jun 22, 2023
15073e8
Improve documentation for internal `IfConfigFunctions`.
DougGregor Jun 22, 2023
431fe8a
Address a number of review comments (thanks, Alex!)
DougGregor Jun 22, 2023
f35c9e8
[Build configuration] Drop optionality from protocol requirement resu…
DougGregor Jun 25, 2023
b6502e5
Simplify `isActive(in:)` using Alex Hoppen's suggestion
DougGregor Jun 25, 2023
a21bb5e
Use preconditionFailure
DougGregor Jun 25, 2023
39961b0
Use editor placeholder for placeholder expression
DougGregor Jun 25, 2023
3ef7aa3
Minor cleanups
DougGregor Jun 25, 2023
83f3824
Minor cleanups to the #if rewriter
DougGregor Jun 25, 2023
7ce4981
Rework use of deprecated APIs
DougGregor Aug 6, 2023
f5e3540
Teach active-clause visitors to handle diagnostics
DougGregor Aug 11, 2023
2590ebb
Add SwiftIfConfig to the set of documentation targets
DougGregor Jul 4, 2024
1b0f44a
Fix typo in the release notes
DougGregor Jul 4, 2024
00fb7a0
Adapt to optionality changes on main
DougGregor Jul 4, 2024
5428bbc
Add a method `Error.asDiagnostics(at:)` to unpack errors into diagnos…
DougGregor Jul 4, 2024
65fd3b9
Handle errors while removing inactive regions
DougGregor Jul 4, 2024
7cb5189
Handle diagnostics through #if condition evaluation
DougGregor Jul 5, 2024
96569a7
Teach #if condition evaluation to reason about "versioned" checks
DougGregor Jul 5, 2024
e649799
Rework `isActive(in: configuration)` to distinguish inactive vs. unpa…
DougGregor Jul 5, 2024
e1e67f1
NFC: Split out IfConfigError and the VersionTuple parsing into their …
DougGregor Jul 5, 2024
b7e9a4d
Clarify documentation a little bit
DougGregor Jul 5, 2024
d8dcb82
Update CMake build for SwiftIfConfig changes
DougGregor Jul 5, 2024
b6c8a1b
Add a new API to compute the "configured regions" of a syntax tree
DougGregor Jul 5, 2024
e07f68a
DocC cleanups
DougGregor Jul 5, 2024
abe00a8
Test active code regions with postfix #if
DougGregor Jul 6, 2024
0b0ac13
Rename IfConfigState -> ConfiguredRegionState
DougGregor Jul 6, 2024
bccddb4
Handle invalid `#if` conditions as "unparsed" regions consistently
DougGregor Jul 7, 2024
aa97fbd
Reshuffle and rename some source files in SwiftIfConfig
DougGregor Jul 7, 2024
8779074
Add support for _hasAtomicBitWidth to evaluation
DougGregor Jul 7, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .spi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ builder:
- SwiftCompilerPlugin
- SwiftDiagnostics
- SwiftIDEUtils
- SwiftIfConfig
- SwiftLexicalLookup
- SwiftOperators
- SwiftParser
Expand Down
19 changes: 19 additions & 0 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ let package = Package(
.library(name: "SwiftCompilerPlugin", targets: ["SwiftCompilerPlugin"]),
.library(name: "SwiftDiagnostics", targets: ["SwiftDiagnostics"]),
.library(name: "SwiftIDEUtils", targets: ["SwiftIDEUtils"]),
.library(name: "SwiftIfConfig", targets: ["SwiftIfConfig"]),
.library(name: "SwiftLexicalLookup", targets: ["SwiftLexicalLookup"]),
.library(name: "SwiftOperators", targets: ["SwiftOperators"]),
.library(name: "SwiftParser", targets: ["SwiftParser"]),
Expand Down Expand Up @@ -138,6 +139,24 @@ let package = Package(
dependencies: ["_SwiftSyntaxTestSupport", "SwiftIDEUtils", "SwiftParser", "SwiftSyntax"]
),

// MARK: SwiftIfConfig

.target(
name: "SwiftIfConfig",
dependencies: ["SwiftSyntax", "SwiftOperators"],
DougGregor marked this conversation as resolved.
Show resolved Hide resolved
exclude: ["CMakeLists.txt"]
),

.testTarget(
name: "SwiftIfConfigTest",
dependencies: [
"_SwiftSyntaxTestSupport",
"SwiftIfConfig",
"SwiftParser",
"SwiftSyntaxMacrosGenericTestSupport",
]
),

// MARK: SwiftLexicalLookup

.target(
Expand Down
2 changes: 1 addition & 1 deletion Release Notes/600.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@
- Pull request: https://github.com/swiftlang/swift-syntax/pull/2433

- `CanImportExprSyntax` and `CanImportVersionInfoSyntax`
- Description: Instead of parsing `canImport` inside `#if` directives as a special expression node, parse it as a functionc call expression. This is in-line with how the `swift(>=6.0)` and `compiler(>=6.0)` directives are parsed.
- Description: Instead of parsing `canImport` inside `#if` directives as a special expression node, parse it as a function call expression. This is in-line with how the `swift(>=6.0)` and `compiler(>=6.0)` directives are parsed.
- Pull request: https://github.com/swiftlang/swift-syntax/pull/2025

- `SyntaxClassifiedRange.offset`, `length` and `endOffset`
Expand Down
4 changes: 4 additions & 0 deletions Release Notes/601.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@
- Description: Returns the node or the first ancestor that satisfies `condition`.
- Pull Request: https://github.com/swiftlang/swift-syntax/pull/2696

- `Error` protocol now has an `asDiagnostics(at:)` method.
- Description: This method translates an error into one or more diagnostics, recognizing `DiagnosticsError` and `DiagnosticMessage` instances or providing its own `Diagnostic` as needed.
- Pull Request: https://github.com/swiftlang/swift-syntax/pull/1816

DougGregor marked this conversation as resolved.
Show resolved Hide resolved
## API Behavior Changes

- `SyntaxProtocol.trimmed` detaches the node
Expand Down
1 change: 1 addition & 0 deletions Sources/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ add_subdirectory(SwiftParser)
add_subdirectory(SwiftParserDiagnostics)
add_subdirectory(SwiftRefactor)
add_subdirectory(SwiftOperators)
add_subdirectory(SwiftIfConfig)
add_subdirectory(SwiftSyntaxBuilder)
add_subdirectory(SwiftSyntaxMacros)
add_subdirectory(SwiftSyntaxMacroExpansion)
Expand Down
35 changes: 35 additions & 0 deletions Sources/SwiftDiagnostics/Diagnostic.swift
Original file line number Diff line number Diff line change
Expand Up @@ -92,3 +92,38 @@ public struct DiagnosticsError: Error, Sendable {
)
}
}

/// Diagnostic message used for thrown errors.
private struct DiagnosticFromError: DiagnosticMessage {
let error: Error
let severity: DiagnosticSeverity = .error

var message: String {
return String(describing: error)
}

var diagnosticID: MessageID {
.init(domain: "SwiftDiagnostics", id: "\(type(of: error))")
}
}

extension Error {
/// Given an error, produce an array of diagnostics reporting the error,
/// using the given syntax node as the location if it wasn't otherwise known.
///
/// This operation will look for diagnostics of known type, such as
/// `DiagnosticsError` and `DiagnosticMessage` to retain information. If
/// none of those apply, it will produce an `error` diagnostic whose message
/// comes from rendering the error as a string.
public func asDiagnostics(at node: some SyntaxProtocol) -> [Diagnostic] {
if let diagnosticsError = self as? DiagnosticsError {
return diagnosticsError.diagnostics
}

if let message = self as? DiagnosticMessage {
return [Diagnostic(node: Syntax(node), message: message)]
}

return [Diagnostic(node: Syntax(node), message: DiagnosticFromError(error: self))]
}
}
Loading