### Correct Swift Syntax Example Source: https://github.com/swiftlang/swift-syntax/blob/main/Sources/SwiftSyntax/Documentation.docc/RawSyntaxValidation.md This example shows the correct way to specify a keyword in SwiftSyntax, which is necessary when raw syntax validation is enabled. ```swift let asyncSpecifier: TokenSyntax = .keyword(.async) ``` -------------------------------- ### Inspect Syntax Tree with EnumSubset Macro Source: https://github.com/swiftlang/swift-syntax/blob/main/Sources/SwiftSyntaxMacros/SwiftSyntaxMacros.docc/SwiftSyntaxMacros.md Example code to paste into the Swift AST Explorer to visualize the syntax tree for a generic parameter macro. ```swift @EnumSubset ``` -------------------------------- ### Example of Expression Macro Usage Source: https://github.com/swiftlang/swift-syntax/blob/main/Sources/SwiftSyntaxMacros/SwiftSyntaxMacros.docc/SwiftSyntaxMacros.md Demonstrates the usage of a freestanding expression macro, indicated by the '#' prefix. The compiler expands this at build time. ```swift let (result, code) = #stringify(a + b) ``` -------------------------------- ### Testing Macros with assertMacroExpansion Source: https://github.com/swiftlang/swift-syntax/blob/main/Sources/SwiftSyntaxMacros/SwiftSyntaxMacros.docc/SwiftSyntaxMacros.md A unit test example using the SwiftSyntaxMacrosTestSupport module to verify macro expansion output. ```swift func testStringifyMacro() { assertMacroExpansion( """ #stringify(a + b) """, expandedSource: """ (a + b, "a + b") """, macros: ["stringify": StringifyMacro.self] ) } ``` -------------------------------- ### Missing Declaration Syntax Example Source: https://github.com/swiftlang/swift-syntax/blob/main/Contributor Documentation/Parser Recovery.md Example of attributes and modifiers without a following declaration, resulting in a MissingDeclSyntax node. ```swift @inlinable public /*missing function*/ ``` -------------------------------- ### Missing Token Recovery Example Source: https://github.com/swiftlang/swift-syntax/blob/main/Contributor Documentation/Parser Recovery.md Example of a function declaration missing an identifier, resulting in the synthesis of a missing identifier node. ```swift func () { } ``` -------------------------------- ### Missing Statement Syntax Example Source: https://github.com/swiftlang/swift-syntax/blob/main/Contributor Documentation/Parser Recovery.md Example of a labeled statement missing its associated statement, resulting in a LabeledStmtSyntax containing a MissingStmtSyntax. ```swift label: struct Foo {} ``` -------------------------------- ### Configure SwiftSyntaxCShims Library in CMake Source: https://github.com/swiftlang/swift-syntax/blob/main/Sources/_SwiftSyntaxCShims/CMakeLists.txt Defines the static library target and sets up include directories and installation exports. ```cmake set(target ${SWIFTSYNTAX_TARGET_NAMESPACE}_SwiftSyntaxCShims) add_library(${target} STATIC PlatformMutex.c ) target_include_directories(${target} PUBLIC "include") set_property(GLOBAL APPEND PROPERTY SWIFT_EXPORTS ${target}) install(TARGETS ${target} EXPORT SwiftSyntaxTargets) ``` -------------------------------- ### Unexpected Syntax Recovery Example Source: https://github.com/swiftlang/swift-syntax/blob/main/Contributor Documentation/Parser Recovery.md Example of a for-in loop with an unexpected identifier where the parser recovers by looking ahead for the 'in' keyword. ```swift for x ys in { } ``` -------------------------------- ### Incorrect Swift Syntax Example Source: https://github.com/swiftlang/swift-syntax/blob/main/Sources/SwiftSyntax/Documentation.docc/RawSyntaxValidation.md This example demonstrates incorrect syntax where an identifier is used instead of a keyword. This can be caught when raw syntax validation is enabled. ```swift let asyncSpecifier: TokenSyntax = "async" ``` -------------------------------- ### Example of @warn attribute usage in Swift Source: https://github.com/swiftlang/swift-syntax/blob/main/Sources/SwiftWarningControl/SwiftWarningControl.md Demonstrates the nested application of @warn attributes on function declarations. ```swift @warn(Deprecate, as: error) func foo() { ... @warn(Deprecate, as: warning) func bar() { ... @warn("Deprecate", as: ignored, reason: "Foo") func baz() { ... } } } ``` -------------------------------- ### Identify error handling locations Source: https://github.com/swiftlang/swift-syntax/blob/main/Sources/SwiftLexicalLookup/SwiftLexicalLookup.docc/SwiftLexicalLookup.md Example demonstrating how error handling is associated with specific syntax constructs like try! and do-catch blocks. ```swift func foo() throws { try! f() // <-- Error handled by `try!` do { try f() // <-- Error handled by `do ... catch` } catch { throw f() // <-- Error handled by the throwing function } } ``` -------------------------------- ### Implement ExpressionMacro for Stringification Source: https://context7.com/swiftlang/swift-syntax/llms.txt Provides an example of an `ExpressionMacro` that stringifies a given expression, returning both the evaluated value and its source code representation. Requires SwiftSyntax, SwiftSyntaxMacros, and SwiftSyntaxBuilder imports. ```swift import SwiftSyntax import SwiftSyntaxMacros import SwiftSyntaxBuilder // Macro that stringifies an expression and returns both value and source public enum StringifyMacro: ExpressionMacro { public static func expansion( of node: some FreestandingMacroExpansionSyntax, in context: some MacroExpansionContext ) -> ExprSyntax { guard let argument = node.arguments.first?.expression else { fatalError("compiler bug: stringify requires an argument") } return "(\(argument), \(literal: argument.description))" } } ``` -------------------------------- ### Define Swift Operators Source: https://github.com/swiftlang/swift-syntax/blob/main/Sources/SwiftOperators/SwiftOperators.docc/SwiftOperators.md Examples of Swift operator declarations as defined in the standard library. ```swift infix operator +: AdditionPrecedence infix operator *: MultiplicationPrecedence ``` -------------------------------- ### Define a Swift Syntax Node Source: https://github.com/swiftlang/swift-syntax/blob/main/Contributor Documentation/Changing Swift Syntax.md Example of a Node definition for a source file, including its kind, base kind, name for diagnostics, parser function, traits, and child nodes. This structure is used in SyntaxSupport files. ```swift Node( kind: .sourceFile, base: .syntax, nameForDiagnostics: "source file", parserFunction: "parseSourceFile", traits: ["WithStatements"], children: [ Child( name: "Statements", kind: .collection(kind: .codeBlockItemList, collectionElementName: "Statement") ), Child( name: "EndOfFileToken", deprecatedName: "EOFToken", kind: .token(choices: [.token(tokenKind: "EndOfFileToken")]) ), ] ) ``` -------------------------------- ### Generate SwiftSyntax Source Code Source: https://github.com/swiftlang/swift-syntax/blob/main/CodeGeneration/README.md Run this command to regenerate SwiftSyntax source files after making changes to the CodeGeneration utilities. Ensure the path to swift-syntax-dev-utils is correct for your setup. ```bash path/to/swift-syntax/swift-syntax-dev-utils generate-source-code ``` -------------------------------- ### Representing missing syntax Source: https://github.com/swiftlang/swift-syntax/blob/main/Sources/SwiftSyntax/Documentation.docc/Working with SwiftSyntax.md Example of how the parser identifies missing identifiers in a function definition. ```text func (uhoh: Void) {} ^ Missing identifier ``` -------------------------------- ### Representing unexpected syntax Source: https://github.com/swiftlang/swift-syntax/blob/main/Sources/SwiftSyntax/Documentation.docc/Working with SwiftSyntax.md Example of how the parser identifies superfluous text encountered during parsing. ```text func four score and seven years ago(uhoh: Void) {} ^~~~~~~~~~~~~~~~~~~~~~~~~ Unexpected text ``` -------------------------------- ### Define Precedence Groups Source: https://github.com/swiftlang/swift-syntax/blob/main/Sources/SwiftOperators/SwiftOperators.docc/SwiftOperators.md Examples of precedence group declarations defining associativity and relative precedence. ```swift precedencegroup AdditionPrecedence { associativity: left } precedencegroup MultiplicationPrecedence { associativity: left higherThan: AdditionPrecedence } ``` -------------------------------- ### Perform unqualified name lookup Source: https://github.com/swiftlang/swift-syntax/blob/main/Sources/SwiftLexicalLookup/SwiftLexicalLookup.docc/SwiftLexicalLookup.md Example illustrating how names are resolved within nested scopes, including generic parameters, member variables, and function parameters. ```swift struct Foo { let a = A() let b = B() func bar(b: B) { // <-- `B` refers to the generic parameter `B` let a: A = a // <-- `a` refers to the member `a` let b: B = b // <-- `b` refers to the function parameter `b` print(self) // <-- `self` refers to the `struct` declaration } } ``` -------------------------------- ### Build SwiftParserCLI from directory Source: https://github.com/swiftlang/swift-syntax/blob/main/SwiftParserCLI/README.md Build the CLI tool after navigating into the SwiftParserCLI directory. ```bash swift build ``` -------------------------------- ### Format swift-syntax code Source: https://github.com/swiftlang/swift-syntax/blob/main/CONTRIBUTING.md Apply swift-format to the repository to ensure consistent styling. ```bash swift format --in-place --parallel --recursive . # Or alternatively swift format -ipr . ``` -------------------------------- ### ClosureCaptureSyntax.init() Source: https://github.com/swiftlang/swift-syntax/blob/main/Release Notes/510.md Convenience initializer for ClosureCaptureSyntax. ```APIDOC ## ClosureCaptureSyntax.init() ### Description Provides a convenience initializer for ClosureCaptureSyntax that takes a concrete name argument and automatically adds equal = TokenSyntax.equalToken() to it. ``` -------------------------------- ### EnumCaseParameterSyntax.init() Source: https://github.com/swiftlang/swift-syntax/blob/main/Release Notes/510.md Convenience initializer for EnumCaseParameterSyntax. ```APIDOC ## EnumCaseParameterSyntax.init() ### Description Provides a convenience initializer for EnumCaseParameterSyntax that takes a concrete firstName value and adds colon = TokenSyntax.colonToken() automatically to it. ``` -------------------------------- ### Generate source code Source: https://github.com/swiftlang/swift-syntax/blob/main/CONTRIBUTING.md Run the development utility to regenerate source files. ```bash ./swift-syntax-dev-utils generate-source-code ``` -------------------------------- ### Migrating SyntaxVisitor to Class Source: https://github.com/swiftlang/swift-syntax/blob/main/Changelog.md SyntaxVisitor and SyntaxAnyVisitor are now classes; implementations must use override and remove mutating keywords. ```swift // Before struct Visitor: SyntaxVisitor { mutating func visit(_ node: EnumDeclSyntax) -> SyntaxVisitorContinueKind { /* ... */ } } // Now class Visitor: SyntaxVisitor { override func visit(_ node: EnumDeclSyntax) -> SyntaxVisitorContinueKind { /* ... */ } } ``` -------------------------------- ### Add Swift Syntax as Bazel Dependency (WORKSPACE) Source: https://github.com/swiftlang/swift-syntax/blob/main/README.md This method uses http_archive in WORKSPACE to pull the source archive. Note that using MODULE.bazel is preferred. Ensure the sha256 and URL match the desired release tag. ```python3 http_archive( name = "SwiftSyntax", sha256 = "f070fd44db9b33f430fd5b5d2700f1e2001c0028711859600e80cc975074fab0", strip_prefix = "swift-syntax-509.1.0", url = "https://github.com/apple/swift-syntax/archive/refs/tags/509.1.0.tar.gz", ) ``` -------------------------------- ### Configure git pre-commit hook for formatting Source: https://github.com/swiftlang/swift-syntax/blob/main/CONTRIBUTING.md Create a pre-commit hook to automatically lint code before commits. ```bash #!/usr/bin/env bash set -e SOURCE_DIR=$(realpath "$(dirname $0)/../..") swift format lint --strict --parallel --recursive $SOURCE_DIR ``` -------------------------------- ### Add Swift Syntax Library Source: https://github.com/swiftlang/swift-syntax/blob/main/Sources/SwiftOperators/CMakeLists.txt Use this command to add a Swift Syntax library to your build. Specify the library name and its source files. ```cmake add_swift_syntax_library(SwiftOperators Operator.swift OperatorError+Diagnostics.swift OperatorError.swift OperatorTable+Defaults.swift OperatorTable+Folding.swift OperatorTable+Semantics.swift OperatorTable.swift PrecedenceGraph.swift PrecedenceGroup.swift SyntaxSynthesis.swift ) ``` -------------------------------- ### Build SwiftParserCLI Source: https://github.com/swiftlang/swift-syntax/blob/main/Contributor Documentation/Filing Parser Bug Reports.md Build the CLI utility required for reducing test cases. ```bash swift build --package-path SwiftParserCLI ``` -------------------------------- ### Parse Swift Source Code Source: https://context7.com/swiftlang/swift-syntax/llms.txt Demonstrates parsing source code from a string and performing incremental parsing for efficient updates. ```swift import SwiftParser import SwiftSyntax // Parse a source file from a string let source = """ func greet(name: String) -> String { return "Hello, \(name)!" } """ let sourceFile: SourceFileSyntax = Parser.parse(source: source) print(sourceFile.description) // Output: func greet(name: String) -> String { // return "Hello, \(name)!" // } // Parse with incremental support for efficient re-parsing after edits let initialResult = Parser.parseIncrementally(source: source, parseTransition: nil) let tree = initialResult.tree let lookaheadRanges = initialResult.lookaheadRanges // After making edits, create a transition for incremental parsing let editedSource = source.replacingOccurrences(of: "Hello", with: "Hi") let transition = IncrementalParseTransition( previousIncrementalParseResult: initialResult, edits: ConcurrentEdits([/* your edits */]) ) let newResult = Parser.parseIncrementally(source: editedSource, parseTransition: transition) ``` -------------------------------- ### Example of #if conditional compilation in Swift Source: https://github.com/swiftlang/swift-syntax/blob/main/Sources/SwiftIfConfig/SwiftIfConfig.docc/SwiftIfConfig.md This snippet illustrates the structure of #if directives within Swift source code, which are represented as IfConfigDeclSyntax nodes in the syntax tree. ```swift func f() { #if DEBUG log("called f") #endif #if os(Linux) // use Linux API #elseif os(iOS) || os(macOS) // use iOS/macOS API #else #error("unsupported platform") #endif } ``` -------------------------------- ### Raw Syntax Validation Error Message Source: https://github.com/swiftlang/swift-syntax/blob/main/Sources/SwiftSyntax/Documentation.docc/RawSyntaxValidation.md An example of a fatal error message produced by SwiftSyntax when raw syntax validation is enabled and incorrect syntax is detected. ```text Fatal error: Error validating child at index 1 of typeEffectSpecifiers: Expected token with one of [keyword('async')] but received identifier with text 'async' ``` -------------------------------- ### Macro Lexical Context APIs Source: https://github.com/swiftlang/swift-syntax/blob/main/Release Notes/600.md New APIs `SyntaxProtocol.asMacroLexicalContext()` and `allMacroLexicalContexts(enclosingSyntax:)` are introduced to provide lexical context for macro expansion. ```APIDOC ## Macro Lexical Context APIs ### Description APIs to produce the lexical context for a given syntax node or the entire stack of enclosing lexical contexts, used for macro expansion. ### Methods - **`SyntaxProtocol.asMacroLexicalContext()`**: Produces the lexical context for the syntax node if it has one. - **`allMacroLexicalContexts(enclosingSyntax:)`**: Returns the entire stack of lexical contexts enclosing a syntax node. ``` -------------------------------- ### Regenerate Swift Syntax Files Source: https://github.com/swiftlang/swift-syntax/blob/main/Contributor Documentation/Changing Swift Syntax.md Run this command to regenerate Swift Syntax files after modifying the CodeGeneration package. ```bash swift run --package-path CodeGeneration generate-swift-syntax ``` -------------------------------- ### Format a source file with BasicFormat Source: https://github.com/swiftlang/swift-syntax/blob/main/Sources/SwiftBasicFormat/SwiftBasicFormat.docc/FilingBugReports.md Use the CLI tool to format a specific source file or node type to reproduce formatting issues. ```bash swift-parser-cli basic-format /path/to/file/that/formats/incorrectly.swift ``` -------------------------------- ### Print Syntax Tree Source: https://github.com/swiftlang/swift-syntax/blob/main/Contributor Documentation/Filing Parser Bug Reports.md Output the parsed syntax tree to identify semantic representation issues. ```bash swift-parser-cli print-tree /path/to/file.swift ``` -------------------------------- ### Add Swift Syntax as Bazel Dependency (Bzlmod) Source: https://github.com/swiftlang/swift-syntax/blob/main/README.md Use this in your MODULE.bazel file to add swift-syntax as a dependency when using Bzlmod. This is the preferred method for Bazel integration. ```python3 bazel_dep(name = "swift-syntax", version = "600.0.1") ``` -------------------------------- ### Traverse Syntax Trees with SyntaxVisitor Source: https://context7.com/swiftlang/swift-syntax/llms.txt Uses SyntaxVisitor to walk through a syntax tree and count function declarations. ```swift import SwiftSyntax import SwiftParser class FunctionCounter: SyntaxVisitor { var functionCount = 0 var functionNames: [String] = [] override func visit(_ node: FunctionDeclSyntax) -> SyntaxVisitorContinueKind { functionCount += 1 functionNames.append(node.name.text) return .visitChildren } } let source = """ func foo() { } func bar(x: Int) -> Int { return x * 2 } struct MyStruct { func baz() { } } """ let tree = Parser.parse(source: source) let counter = FunctionCounter(viewMode: .sourceAccurate) counter.walk(tree) print("Found \(counter.functionCount) functions: \(counter.functionNames)") // Output: Found 3 functions: ["foo", "bar", "baz"] ``` -------------------------------- ### Manage Syntax Trivia Source: https://context7.com/swiftlang/swift-syntax/llms.txt Shows how to iterate over tokens to inspect trivia and how to construct and apply custom trivia to syntax nodes. ```swift import SwiftSyntax import SwiftParser let source = """ // This is a comment func example() { let x = 1 // inline comment } """ let tree = Parser.parse(source: source) // Iterate through all tokens and their trivia for token in tree.tokens(viewMode: .sourceAccurate) { if !token.leadingTrivia.isEmpty { print("Leading trivia for '\(token.text)': \(token.leadingTrivia.debugDescription)") } if !token.trailingTrivia.isEmpty { print("Trailing trivia for '\(token.text)': \(token.trailingTrivia.debugDescription)") } } // Create trivia programmatically let docComment = Trivia.docLineComment("/// Documentation") + .newline let indentation = Trivia.spaces(4) let newline = Trivia.newline // Apply trivia to nodes var funcDecl = FunctionDeclSyntax( name: .identifier("documented"), signature: FunctionSignatureSyntax( parameterClause: FunctionParameterClauseSyntax(parameters: []) ), body: CodeBlockSyntax(statements: []) ) funcDecl.leadingTrivia = docComment print(funcDecl.description) // Output: /// Documentation // func documented() { // } ``` -------------------------------- ### Create and Format Compiler Diagnostics Source: https://context7.com/swiftlang/swift-syntax/llms.txt Defines a custom diagnostic message and demonstrates how to attach it to a syntax node and format it for output. ```swift import SwiftSyntax import SwiftDiagnostics import SwiftParser struct MyError: DiagnosticMessage { let message: String let diagnosticID = MessageID(domain: "MyDomain", id: "myError") let severity: DiagnosticSeverity = .error } let source = "let x = " // Incomplete code let tree = Parser.parse(source: source) // Create a diagnostic pointing to a specific node if let lastToken = tree.lastToken(viewMode: .sourceAccurate) { let diagnostic = Diagnostic( node: lastToken, message: MyError(message: "Expected expression after '='") ) // Format diagnostics for display let converter = SourceLocationConverter(fileName: "test.swift", tree: tree) let formatted = DiagnosticsFormatter.annotatedSource(tree: tree, diags: [diagnostic]) print(formatted) } // Create a diagnostic with a fix-it let fixIt = FixIt( message: SimpleFixItMessage(message: "Insert placeholder", fixItID: .init(domain: "MyDomain", id: "fix")), changes: [ .replace( oldNode: Syntax(tree), newNode: Syntax(Parser.parse(source: "let x = <#value#>")) ) ] ) ``` -------------------------------- ### Declare swift-syntax dependency range Source: https://github.com/swiftlang/swift-syntax/blob/main/Sources/SwiftSyntax/Documentation.docc/Macro Versioning.md Specify a range of compatible swift-syntax versions in the package manifest to allow the macro to support multiple major versions. ```swift .package(url: "https://github.com/swiftlang/swift-syntax.git", "509.0.0"..<"511.0.0"), ``` -------------------------------- ### Build Struct with SwiftSyntaxBuilder Source: https://context7.com/swiftlang/swift-syntax/llms.txt Demonstrates building a Swift struct declaration using result builders and string literals with SwiftSyntaxBuilder. Ensure SwiftSyntax and SwiftSyntaxBuilder are imported. ```swift import SwiftSyntax import SwiftSyntaxBuilder // Build a struct with result builders let structDecl = StructDeclSyntax(name: "Person") { DeclSyntax("var name: String") DeclSyntax("var age: Int") DeclSyntax(""" init(name: String, age: Int) { self.name = name self.age = age } """) } print(structDecl.formatted()) ``` -------------------------------- ### Run specific SwiftParser tests Source: https://github.com/swiftlang/swift-syntax/blob/main/CONTRIBUTING.md Execute only the parser tests using the SwiftParserTests product. ```bash swift test --test-product SwiftParserTests ``` -------------------------------- ### Cover New Syntax Cases Source: https://github.com/swiftlang/swift-syntax/blob/main/Release Notes/600.md SyntaxEnum and SyntaxKind now include 'throwsClause'. Update exhaustive switches to cover this new case. ```swift SyntaxEnum.throwsClause ``` ```swift SyntaxKind.throwsClause ``` -------------------------------- ### Manual EnumSubset Implementation Source: https://github.com/swiftlang/swift-syntax/blob/main/Sources/SwiftSyntaxMacros/SwiftSyntaxMacros.docc/SwiftSyntaxMacros.md A repetitive, hand-written implementation of an enum subset that the EnumSubset macro aims to automate. ```swift enum TypeDeclarationKeyword { case `actor` case `class` ... init?(_ keyword: Keyword) { switch keyword { case .actor: self = .actor case .class: self = .class ... default: return nil } } var keyword: Keyword { switch self { case .actor: return .actor case .class: return .class ... } } } ``` -------------------------------- ### assertMacroExpansion with Macro Specifications Source: https://github.com/swiftlang/swift-syntax/blob/main/Release Notes/600.md A new overload for `assertMacroExpansion` is available, accepting a `macroSpecs` argument to specify macro details like conformances. ```APIDOC ## assertMacroExpansion(macroSpecs:) ### Description An overload for `assertMacroExpansion` that allows specifying macro specifications, such as conformances provided by member or extension macros, for macro expansion. ### Parameters - **macroSpecs** (MacroSpecification) - The specifications for the macro. ``` -------------------------------- ### Implement EnumSubsetMacro Source: https://github.com/swiftlang/swift-syntax/blob/main/Sources/SwiftSyntaxMacros/SwiftSyntaxMacros.docc/SwiftSyntaxMacros.md The implementation of the EnumSubsetMacro using the MemberMacro protocol to generate an initializer based on enum cases. ```swift enum EnumSubsetError: CustomStringConvertible, Error { case onlyApplicableToEnum case noGenericParameterName var description: String { switch self { case .onlyApplicableToEnum: return "@EnumSubset can only be applied to an enum" case .noGenericParameterName: return "Missing generic parameter specifying the enum's superset" } } } public enum EnumSubsetMacro: MemberMacro { public static func expansion( of attribute: AttributeSyntax, providingMembersOf declaration: some DeclGroupSyntax, in context: some MacroExpansionContext ) throws -> [DeclSyntax] { guard let enumDecl = declaration.as(EnumDeclSyntax.self) else { throw EnumSubsetError.onlyApplicableToEnum } // Extract the name of the generic parameter. // See section *Inspect the SwiftSyntax Tree* for more details on building this expression. guard let supersetType = attribute, .attributeName.as(SimpleTypeIdentifierSyntax.self)? .genericArgumentClause? .arguments.first? .argumentType else { throw EnumSubsetError.noGenericParameterName } // Extract all the enum elements let members = enumDecl.memberBlock.members let caseDecls = members.compactMap { $0.decl.as(EnumCaseDeclSyntax.self) } let elements = caseDecls.flatMap { $0.elements } // Build the initializer using a result builder let initializer = try InitializerDeclSyntax("init?(_ superset: \(supersetType))") { try SwitchExprSyntax("switch superset") { for element in elements { SwitchCaseSyntax( """ case .\(element.identifier): self = .\(element.identifier) """ ) } SwitchCaseSyntax("default: return nil") } } return [DeclSyntax(initializer)] } } ``` -------------------------------- ### Link Swift Syntax Libraries Source: https://github.com/swiftlang/swift-syntax/blob/main/Sources/SwiftOperators/CMakeLists.txt Link Swift Syntax libraries to your target. Use PUBLIC for headers and interfaces, PRIVATE for implementation details. ```cmake target_link_swift_syntax_libraries(SwiftOperators PUBLIC SwiftSyntax SwiftDiagnostics SwiftParser) ``` -------------------------------- ### Parse Source Text into Syntax Tree Source: https://github.com/swiftlang/swift-syntax/blob/main/Sources/SwiftSyntax/Documentation.docc/Working with SwiftSyntax.md Use SwiftParser to convert source code strings into a SourceFileSyntax node. This is useful when code is provided by users or not known at build time. ```swift import SwiftSyntax import SwiftParser import SwiftSyntaxBuilder // `file` is a source file syntax node containing the parsed value of the // provided text. let file: SourceFileSyntax = """ print("Hello, world!") """ ``` -------------------------------- ### Modify Syntax Nodes Source: https://context7.com/swiftlang/swift-syntax/llms.txt Demonstrates renaming a function, adding modifiers, and adjusting trivia using direct property assignment and the with(_:_:) method. ```swift import SwiftSyntax import SwiftParser let source = "func hello() { }" let tree = Parser.parse(source: source) if var funcDecl = tree.statements.first?.item.as(FunctionDeclSyntax.self) { // Rename the function funcDecl.name = .identifier("greet") // Add a modifier let publicKeyword = DeclModifierSyntax(name: .keyword(.public)) funcDecl.modifiers = DeclModifierListSyntax([publicKeyword]) // Adjust trivia (whitespace/comments) funcDecl.leadingTrivia = .docLineComment("/// Greets the user") + .newline print(funcDecl.description) // Output: /// Greets the user // publicgreet() { } } // Use with() for cleaner chaining let modified = tree.statements.first?.item .as(FunctionDeclSyntax.self)? .with(\.name, .identifier("goodbye")) .with(\.leadingTrivia, .spaces(4)) print(modified?.description ?? "") // Output: func goodbye() { } ``` -------------------------------- ### Print Syntax Tree for Debugging Source: https://github.com/swiftlang/swift-syntax/blob/main/Contributor Documentation/Fixing Bugs.md Use this command to dump the syntax tree of a file to determine if the parser is recovering correctly from invalid source code. ```bash swift-parser-cli print-tree /path/to/file/with/unhelpful/diagnostic.swift ``` -------------------------------- ### assertMacroExpansion with Fix-Its Source: https://github.com/swiftlang/swift-syntax/blob/main/Release Notes/600.md The `assertMacroExpansion` function now accepts `applyFixIts` and `fixedSource` parameters to verify the source code after applying Fix-Its. ```APIDOC ## assertMacroExpansion(applyFixIts:fixedSource:) ### Description Asserts that the source code after applying Fix-Its matches the provided `fixedSource` string. ### Parameters - **applyFixIts** (Bool) - Indicates whether to apply Fix-Its before comparison. - **fixedSource** (String) - The expected source code after applying Fix-Its. ``` -------------------------------- ### Run pre-PR checks Source: https://github.com/swiftlang/swift-syntax/blob/main/CONTRIBUTING.md Execute the automated script to verify changes before submitting a pull request. ```bash ./swift-syntax-dev-utils local-pr-precheck ``` -------------------------------- ### Enable Raw Syntax Validation Source: https://github.com/swiftlang/swift-syntax/blob/main/Sources/SwiftSyntax/Documentation.docc/RawSyntaxValidation.md Enable raw syntax validation by setting the environment variable when running Swift tests. ```sh SWIFTSYNTAX_ENABLE_RAWSYNTAX_VALIDATION=true swift test ``` -------------------------------- ### Updating Syntax Traversal Source: https://github.com/swiftlang/swift-syntax/blob/main/Changelog.md The walk method has moved from the syntax node to the SyntaxVisitor class. ```swift // Before tree.walk(&visitor) // Now visitor.walk(tree) ``` -------------------------------- ### Access Syntax Node Properties Source: https://context7.com/swiftlang/swift-syntax/llms.txt Demonstrates using strongly-typed accessors to extract function names, modifiers, parameters, attributes, and return types from a parsed syntax tree. ```swift import SwiftSyntax import SwiftParser let source = """ @available(iOS 15, *) public func fetchData(url: String, timeout: Int = 30) async throws -> Data { // implementation } """ let tree = Parser.parse(source: source) if let funcDecl = tree.statements.first?.item.as(FunctionDeclSyntax.self) { // Access function name print("Function: \(funcDecl.name.text)") // fetchData // Access modifiers for modifier in funcDecl.modifiers { print("Modifier: \(modifier.name.text)") // public } // Access parameters for param in funcDecl.signature.parameterClause.parameters { let defaultValue = param.defaultValue?.value.description ?? "none" print("Param: \(param.firstName.text): \(param.type), default: \(defaultValue)") } // Output: Param: url: String, default: none // Param: timeout: Int, default: 30 // Access attributes for attr in funcDecl.attributes { if let attrSyntax = attr.as(AttributeSyntax.self) { print("Attribute: @\(attrSyntax.attributeName)") } } // Output: Attribute: @available // Access effect specifiers if let effectSpecifiers = funcDecl.signature.effectSpecifiers { if effectSpecifiers.asyncSpecifier != nil { print("Is async") } if effectSpecifiers.throwsClause != nil { print("Can throw") } } // Access return type if let returnType = funcDecl.signature.returnClause?.type { print("Returns: \(returnType)") // Data } } ``` -------------------------------- ### Implementing an ExpressionMacro Source: https://github.com/swiftlang/swift-syntax/blob/main/Sources/SwiftSyntaxMacros/SwiftSyntaxMacros.docc/SwiftSyntaxMacros.md The expansion function for a macro that returns a tuple containing the original expression and its source code string. ```swift public struct StringifyMacro: ExpressionMacro { public static func expansion( of node: some FreestandingMacroExpansionSyntax, in context: some MacroExpansionContext ) -> ExprSyntax { guard let argument = node.argumentList.first?.expression else { fatalError("compiler bug: the macro does not have any arguments") } return "(\(argument), \(literal: argument.description))" } } ``` -------------------------------- ### Add Swift Syntax Versioned Library (CMake) Source: https://github.com/swiftlang/swift-syntax/blob/main/Sources/VersionMarkerModules/CMakeLists.txt Defines a static library for a specific Swift Syntax version using CMake. This is used to manage different versions of the Swift Syntax library within a project. ```cmake add_library(${SWIFTSYNTAX_TARGET_NAMESPACE}SwiftSyntax509 STATIC SwiftSyntax509/Empty.swift) add_library(${SWIFTSYNTAX_TARGET_NAMESPACE}SwiftSyntax510 STATIC SwiftSyntax510/Empty.swift) add_library(${SWIFTSYNTAX_TARGET_NAMESPACE}SwiftSyntax600 STATIC SwiftSyntax600/Empty.swift) add_library(${SWIFTSYNTAX_TARGET_NAMESPACE}SwiftSyntax601 STATIC SwiftSyntax601/Empty.swift) add_library(${SWIFTSYNTAX_TARGET_NAMESPACE}SwiftSyntax602 STATIC SwiftSyntax602/Empty.swift) add_library(${SWIFTSYNTAX_TARGET_NAMESPACE}SwiftSyntax603 STATIC SwiftSyntax603/Empty.swift) add_library(${SWIFTSYNTAX_TARGET_NAMESPACE}SwiftSyntax604 STATIC SwiftSyntax604/Empty.swift) ``` -------------------------------- ### Implement MemberMacro for Case Detection Source: https://context7.com/swiftlang/swift-syntax/llms.txt Demonstrates a `MemberMacro` that automatically adds computed boolean properties to an enum for detecting each case. This macro requires SwiftSyntax, SwiftSyntaxMacros, and SwiftSyntaxBuilder imports. ```swift import SwiftSyntax import SwiftSyntaxMacros import SwiftSyntaxBuilder // Macro that adds computed properties for each enum case public enum CaseDetectionMacro: MemberMacro { public static func expansion( of node: AttributeSyntax, providingMembersOf declaration: some DeclGroupSyntax, in context: some MacroExpansionContext ) throws -> [DeclSyntax] { guard let enumDecl = declaration.as(EnumDeclSyntax.self) else { return [] } let cases = enumDecl.memberBlock.members.compactMap { member -> String? in guard let caseDecl = member.decl.as(EnumCaseDeclSyntax.self), let element = caseDecl.elements.first else { return nil } return element.name.text } return cases.map { caseName in let propertyName = "is\(caseName.prefix(1).uppercased())\ (caseName.dropFirst())" return """ var \(raw: propertyName): Bool { if case .\(raw: caseName) = self { return true } return false } """ } } } ``` -------------------------------- ### Implement MacroExpansionContext Lexical Context Source: https://github.com/swiftlang/swift-syntax/blob/main/Release Notes/600.md Types conforming to MacroExpansionContext must now implement the lexicalContext property. Update HostToPluginMessage and SyntaxProtocol.expand calls accordingly. ```swift lexicalContext ``` ```swift expand(macros:contextGenerator:indentationWidth:) ``` -------------------------------- ### Upcasting and Downcasting with ExprSyntax Source: https://github.com/swiftlang/swift-syntax/blob/main/Contributor Documentation/When to use protocols in SwiftSyntax.md Demonstrates how to convert specific expression nodes to the ExprSyntax struct and back to concrete types. ```swift ExprSyntax(integerLiteral) expr.as(IntegerLiteralExprSyntax.self) ``` -------------------------------- ### Convert Source Locations Source: https://context7.com/swiftlang/swift-syntax/llms.txt Uses SourceLocationConverter to map between byte offsets and line/column coordinates within a syntax tree. ```swift import SwiftSyntax import SwiftParser let source = """ func hello() { print("Hello, World!") } """ let tree = Parser.parse(source: source) let converter = SourceLocationConverter(fileName: "hello.swift", tree: tree) // Find a specific node and get its location if let printCall = tree.statements.first?.item .as(FunctionDeclSyntax.self)?.body?.statements.first?.item .as(FunctionCallExprSyntax.self) { let location = printCall.startLocation(converter: converter) print("print() call at line \(location.line), column \(location.column)") // Output: print() call at line 2, column 5 let range = printCall.sourceRange(converter: converter) print("Range: \(range.start.line):\(range.start.column) to \(range.end.line):\(range.end.column)") } // Convert line/column back to position let position = converter.position(ofLine: 2, column: 5) if let token = tree.token(at: position) { print("Token at position: \(token.tokenKind)") // Output: Token at position: identifier("print") } ``` -------------------------------- ### Print Parser Diagnostics Source: https://github.com/swiftlang/swift-syntax/blob/main/Contributor Documentation/Filing Parser Bug Reports.md Display diagnostics generated by the parser for a specific source file. ```bash swift-parser-cli print-diags /path/to/file.swift ``` -------------------------------- ### Link Swift Syntax Libraries to Target Source: https://github.com/swiftlang/swift-syntax/blob/main/Sources/SwiftSyntaxMacroExpansion/CMakeLists.txt This function links specified Swift Syntax libraries to a target. Use 'PUBLIC' to make the linked libraries visible to targets that depend on this one. Ensure the listed libraries exist and are correctly defined. ```cmake target_link_swift_syntax_libraries(SwiftSyntaxMacroExpansion PUBLIC SwiftBasicFormat SwiftDiagnostics SwiftOperators SwiftSyntax SwiftSyntaxBuilder SwiftSyntaxMacros ) ``` -------------------------------- ### SyntaxCollection.index(at:) Source: https://github.com/swiftlang/swift-syntax/blob/main/Release Notes/510.md Returns the index of the n-th element in a SyntaxCollection. ```APIDOC ## SyntaxCollection.index(at:) ### Description Returns the index of the n-th element in a SyntaxCollection. This computation is in O(n) and SyntaxCollection is not subscriptable by an integer. ``` -------------------------------- ### SyntaxIdentifier.IndexInTree Source: https://github.com/swiftlang/swift-syntax/blob/main/Release Notes/600.md A tree-agnostic identifier for syntax nodes. ```APIDOC ## SyntaxIdentifier.IndexInTree ### Description Uniquely identifies a syntax node within a tree. This is similar to `SyntaxIdentifier` but does not store the root ID of the tree. It can thus be transferred across trees that are structurally equivalent. The only public functions on this type are `toOpaque` and `init(fromOpaque:)`. ``` -------------------------------- ### Run swift-syntax tests with environment variables Source: https://github.com/swiftlang/swift-syntax/blob/main/CONTRIBUTING.md Set the SKIP_LONG_TESTS environment variable to skip self-parse tests during execution. ```bash SKIP_LONG_TESTS=1 swift test ``` -------------------------------- ### Parse Swift source code Source: https://github.com/swiftlang/swift-syntax/blob/main/Sources/SwiftParser/README.md Use Parser.parse to convert a string of Swift code into a syntax tree. The resulting tree can be inspected or dumped for visualization. ```swift import SwiftParser #if compiler(>=6) internal import SwiftSyntax #else import SwiftSyntax #endif let sourceText = """ func greeting(name: String) { print("Hello, \(name)!") } """ // Parse the source code in sourceText into a syntax tree let sourceFile: SourceFileSyntax = Parser.parse(source: sourceText) // The "description" of the source tree is the source-accurate view of what was parsed. assert(sourceFile.description == sourceText) // Visualize the complete syntax tree. dump(sourceFile) ``` -------------------------------- ### MacroDeclSyntax.expand with genericReplacements Source: https://github.com/swiftlang/swift-syntax/blob/main/Release Notes/600.md The `expand` method of `MacroDeclSyntax` now includes a `genericReplacements` parameter, defaulted to an empty array. ```APIDOC ## MacroDeclSyntax.expand(argumentList:definition:replacements:genericReplacements:) ### Description Expands the macro with the given arguments, definition, and replacements. A new `genericReplacements` parameter has been added. ### Parameters - **argumentList** (ArgumentListSyntax) - The list of arguments for the macro expansion. - **definition** (MacroDeclSyntax) - The macro declaration itself. - **replacements** (MacroExpansion.Replacements) - The replacements for the macro expansion. - **genericReplacements** (Array) - Defaulted to an empty array. Additional generic replacements for the macro expansion. ``` -------------------------------- ### Add Swift Syntax as SwiftPM Dependency Source: https://github.com/swiftlang/swift-syntax/blob/main/README.md To depend on swift-syntax in a SwiftPM package, add this to your Package.swift file. Replace '<#latest swift-syntax tag#>' with the appropriate version tag. ```swift dependencies: [ .package(url: "https://github.com/swiftlang/swift-syntax.git", from: "<#latest swift-syntax tag#>"), ] ``` -------------------------------- ### Debugging Macro Expansion Source: https://github.com/swiftlang/swift-syntax/blob/main/Sources/SwiftSyntaxMacros/SwiftSyntaxMacros.docc/SwiftSyntaxMacros.md Workaround for a debugger limitation in Swift 5.9 when printing parameters declared with 'some'. ```swift public static func expansion(of node: NodeType, ...) ``` -------------------------------- ### DeclGroupSyntax.introducer Source: https://github.com/swiftlang/swift-syntax/blob/main/Release Notes/600.md The `DeclGroupSyntax` trait now includes an `introducer` property to access the keyword that introduces the declaration. ```APIDOC ## DeclGroupSyntax.introducer ### Description The `DeclGroupSyntax` trait has an additional `introducer` property, which represents the keyword that introduces the declaration (e.g., `class`, `struct`, `enum`). ### Type Property ### Returns The introducer keyword syntax. ``` -------------------------------- ### Sequential Scope Lookup Behavior Source: https://github.com/swiftlang/swift-syntax/blob/main/Sources/SwiftLexicalLookup/SwiftLexicalLookup.docc/LookupRules.md Demonstrates how sequential scopes interleave results from nested guard and code block scopes. ```swift func foo(x: Int?) { // Guard scope guard let a = x else { return } // In code block scope let a: Int? = a // Guard scope guard let b = x, let a else { return } // In code block scope let a = b a // <-- lookup here b // <-- lookup here } ``` -------------------------------- ### Configure SwiftSyntaxMacrosGenericTestSupport failure handler Source: https://github.com/swiftlang/swift-syntax/blob/main/Release Notes/600.md Manual failure handler implementation required when using SwiftSyntaxMacrosGenericTestSupport with swift-testing. ```swift Issue.record("\($0.message)", fileID: $0.location.fileID, filePath: $0.location.filePath, line: $0.location.line, column: $0.location.column) ``` -------------------------------- ### Parse a comma-delimited inheritance clause Source: https://github.com/swiftlang/swift-syntax/blob/main/Contributor Documentation/Parsing Basics.md Demonstrates sequence parsing using a loop and conditional consumption to handle delimited elements. ```swift extension Parser { mutating func parseInheritance() -> RawTypeInheritanceClauseSyntax { // Eat the colon character. let colon = self.eat(.colon) // Start parsing a list of inherited types. var elements = [RawInheritedTypeSyntax]() do { var keepGoing: RawTokenSyntax? = nil repeat { let type = self.parseType() keepGoing = self.consume(if: .comma) elements.append(RawInheritedTypeSyntax( typeName: type, trailingComma: keepGoing, arena: self.arena)) } while keepGoing != nil } // Construct the syntax for the list of inherited types. let inheritedTypes = RawInheritedTypeListSyntax( elements: elements, arena: self.arena) return RawTypeInheritanceClauseSyntax( colon: colon, inheritedTypeCollection: inheritedTypes, arena: self.arena) } } ``` -------------------------------- ### SyntaxProtocol.node(at:) Source: https://github.com/swiftlang/swift-syntax/blob/main/Release Notes/600.md Retrieves a syntax node based on its identifier. ```APIDOC ## SyntaxProtocol.node(at:) ### Description Given a `SyntaxIdentifier`, returns the `Syntax` node with that identifier. ```