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

Open
wants to merge 22 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
5e320a3
[SwiftIfConfig] Add a new library for evaluating `#if` conditions.
DougGregor Jun 5, 2023
c4dd56f
Add higher-level APIs for querying active code state
DougGregor Jun 5, 2023
f1c3775
Add support for evaluating `swift` and `compiler` conditionals
DougGregor Jun 13, 2023
f0d8d01
Implement support for archaic `_compiler_version("X.Y.Z.W.V")` check
DougGregor Jun 18, 2023
f6671ff
Add support for `canImport` configuration checks.
DougGregor Jun 18, 2023
49feafc
Improve documentation for `#if` configuration functions
DougGregor Jun 19, 2023
2ac9fbf
Add `ActiveSyntax(Any)Visitor` visitor classes.
DougGregor Jun 19, 2023
9c3f4cd
Add/cleanup some TODO comments
DougGregor Jun 19, 2023
4aad17b
Add an API to rewrite a syntax tree by removing inactive regions.
DougGregor Jun 19, 2023
96e6a8d
Implement inactive clause rewriting support for postfix `#if`
DougGregor Jun 19, 2023
1404f6b
Add overview documentation for the SwiftIfConfig library
DougGregor Jun 20, 2023
a0bbe00
Add CMake build system for SwiftIfConfig
DougGregor Jun 20, 2023
be1c27a
Format source
DougGregor Jun 20, 2023
6712ea0
Improve documentation for BuildConfiguration
DougGregor Jun 22, 2023
884d4ff
Improve documentation for internal `IfConfigFunctions`.
DougGregor Jun 22, 2023
54d1c43
Address a number of review comments (thanks, Alex!)
DougGregor Jun 22, 2023
46c082c
[Build configuration] Drop optionality from protocol requirement resu…
DougGregor Jun 25, 2023
817228e
Simplify `isActive(in:)` using Alex Hoppen's suggestion
DougGregor Jun 25, 2023
e14e0c7
Use preconditionFailure
DougGregor Jun 25, 2023
e19032b
Use editor placeholder for placeholder expression
DougGregor Jun 25, 2023
23c6b8b
Minor cleanups
DougGregor Jun 25, 2023
7425d30
Minor cleanups to the #if rewriter
DougGregor Jun 25, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
14 changes: 14 additions & 0 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ let package = Package(
.library(name: "SwiftCompilerPluginMessageHandling", targets: ["SwiftCompilerPluginMessageHandling"]),
.library(name: "SwiftDiagnostics", targets: ["SwiftDiagnostics"]),
.library(name: "SwiftIDEUtils", targets: ["SwiftIDEUtils"]),
.library(name: "SwiftIfConfig", targets: ["SwiftIfConfig"]),
.library(name: "SwiftOperators", targets: ["SwiftOperators"]),
.library(name: "SwiftParser", targets: ["SwiftParser"]),
.library(name: "SwiftParserDiagnostics", targets: ["SwiftParserDiagnostics"]),
Expand Down Expand Up @@ -144,6 +145,19 @@ let package = Package(
dependencies: ["_SwiftSyntaxTestSupport", "SwiftIDEUtils", "SwiftParser", "SwiftSyntax"]
),

// MARK: SwiftIfConfig

.target(
name: "SwiftIfConfig",
dependencies: ["SwiftSyntax", "SwiftOperators"],
exclude: ["CMakeLists.txt"]
),

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

// MARK: SwiftSyntax

.target(
Expand Down
1 change: 1 addition & 0 deletions Sources/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ add_subdirectory(SwiftDiagnostics)
add_subdirectory(SwiftParser)
add_subdirectory(SwiftParserDiagnostics)
add_subdirectory(SwiftOperators)
add_subdirectory(SwiftIfConfig)
add_subdirectory(SwiftSyntaxBuilder)
add_subdirectory(SwiftSyntaxMacros)
add_subdirectory(SwiftSyntaxMacroExpansion)
Expand Down
92 changes: 92 additions & 0 deletions Sources/SwiftIfConfig/BuildConfiguration.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2023 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
import SwiftSyntax

public enum Endianness: String {
case little
case big
}

/// Describes the requested version of a module
public enum CanImportVersion {
/// Any version of the module will suffice.
case unversioned

/// Only modules with the given version or higher will match.
case version(VersionTuple)

/// Only modules where the underlying Clang module has the given version or
/// higher will match.
case underlyingVersion(VersionTuple)
}

/// Captures information about the build configuration that can be
/// queried in a `#if` expression, including OS, compiler version,
/// enabled language features, and available modules.
///
/// Providing complete build configuration information effectively requires
/// a Swift compiler, because (for example) determining whether a module can
/// be imported is a complicated task only implemented in the Swift compiler.
/// Therefore, many of the queries return `Bool?`, where `nil` indicates
/// that the answer is not known. Clients that don't have a lot of context
/// (such as an IDE that does not have access to the compiler command line)
/// can return `nil`.
DougGregor marked this conversation as resolved.
Show resolved Hide resolved
public protocol BuildConfiguration {
/// Determine whether a given custom build condition has been set.
///
/// Custom build conditions can be set by the `-D` command line option to
/// the Swift compiler. For example, `-DDEBUG` sets the custom condition
/// named `DEBUG`.
func isCustomConditionSet(name: String, syntax: ExprSyntax) -> Bool?
DougGregor marked this conversation as resolved.
Show resolved Hide resolved

/// Determine whether the given feature is enabled.
///
/// Features are determined by the Swift compiler, language mode, and other
/// options such as `--enable-upcoming-feature`.
func hasFeature(name: String, syntax: ExprSyntax) -> Bool?

/// Determine whether the given attribute is available.
///
/// Attributes are determined by the Swift compiler.
func hasAttribute(name: String, syntax: ExprSyntax) -> Bool?

/// Determine whether a module with the given import path can be imported,
/// with additional version information.
func canImport(importPath: [String], version: CanImportVersion, syntax: ExprSyntax) -> Bool?

/// Determine whether the given name is the active target OS (e.g., Linux, iOS).
func isActiveTargetOS(name: String, syntax: ExprSyntax) -> Bool?

/// Determine whether the given name is the active target architecture (e.g., x86_64, arm64)
func isActiveTargetArchitecture(name: String, syntax: ExprSyntax) -> Bool?

/// Determine whether the given name is the active target environment (e.g., simulator)
func isActiveTargetEnvironment(name: String, syntax: ExprSyntax) -> Bool?

/// Determine whether the given name is the active target runtime (e.g., _ObjC vs. _Native)
func isActiveTargetRuntime(name: String, syntax: ExprSyntax) -> Bool?

/// Determine whether the given name is the active target pointer authentication scheme (e.g., arm64e).
func isActiveTargetPointerAuthentication(name: String, syntax: ExprSyntax) -> Bool?

/// The bit width of a data pointer for the target architecture.
var targetPointerBitWidth: Int? { get }

/// The endianness of the target architecture.
var endianness: Endianness? { get }

/// The effective language version, which can be set by the user (e.g., 5.0).
var languageVersion: VersionTuple? { get }

/// The version of the compiler (e.g., 5.9).
var compilerVersion: VersionTuple? { get }
}
24 changes: 24 additions & 0 deletions Sources/SwiftIfConfig/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# This source file is part of the Swift.org open source project
#
# Copyright (c) 2014 - 2023 Apple Inc. and the Swift project authors
# Licensed under Apache License v2.0 with Runtime Library Exception
#
# See http://swift.org/LICENSE.txt for license information
# See http://swift.org/CONTRIBUTORS.txt for Swift project authors

add_swift_host_library(SwiftIfConfig
BuildConfiguration.swift
IfConfigEvaluation.swift
IfConfigFunctions.swift
IfConfigRewriter.swift
IfConfigState.swift
IfConfigVisitor.swift
SyntaxLiteralUtils.swift
VersionTuple.swift
)

target_link_libraries(SwiftIfConfig PUBLIC
SwiftSyntax
SwiftDiagnostics
SwiftOperators
SwiftParser)