From 746fab8a55000093c34266fa662523d6dbb705ac Mon Sep 17 00:00:00 2001 From: Alex Hoppen Date: Tue, 31 Oct 2023 13:10:31 -0700 Subject: [PATCH 01/12] Throw an error if types conforming to `MemberMacro` implement no `expansion` method MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When adding a new type that conforms to `MemberMacro`, no `expansion` function is required to be implemented. It’s necessary to do it this way because: - `expansion(of:providingMembersOf:in:)` needs to exist as a protocol requirement to keep Swift 5.9 macros that implement this method compiling - `expansion(of:providingMembersOf:in:)` needs to be defaulted so that macros implementing `expansion(of:providingMembersOf:conformingTo:in:)` don’t need to also provide an implementation for the legacy version that doesn’t have `conformingTo:` - `expansion(of:providingMembersOf:conformingTo:in:)` obviously needs to exist since it’s the new dedicated entry point - `expansion(of:providingMembersOf:conformingTo:in:)` needs to have a default implementation that calls `expansion(of:providingMembersOf:in:)` so that 5.9 macros continue to work - We can’t mark `expansion(of:providingMembersOf:in:)` as deprecated because it’s called by the default implementation of `expansion(of:providingMembersOf:conformingTo:in:)` and we want to keep swift-syntax building without warnings. At the moment, we provide default implementations for both `expansion` functions that call each other, which causes an infinite recursion, that makes it non-obvious to see what’s going wrong. With this change, the default implementation of the legacy `expansion(of:providingMembersOf:in:)` method throws an error saying that you need to implement either of the two expansion methods. That way you get the following behavior: - If you don’t implement either expansion function, the error gets thrown - If a macro implements the legacy `expansion(of:providingMembersOf:in:)` function, then it overrides the throwing version and the macro works. - If a macro implements the new `expansion(of:providingMembersOf:conformingTo:in:)` method, then the compiler calls into that method directly and the legacy `expansion(of:providingMembersOf:in:)` never gets invoked by the compiler. The only possible issue I can think of is if a library is calling `expansion(of:providingMembersOf:in:)` but the macro only implements `expansion(of:providingMembersOf:conformingTo:in:)`. In this case an error would get thrown where it currently isn’t. But since I don’t see any reason why anyone would be calling `expansion(of:providingMembersOf:in:)` directly, I think this is fine. --- .../MacroProtocols/MemberMacro.swift | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/Sources/SwiftSyntaxMacros/MacroProtocols/MemberMacro.swift b/Sources/SwiftSyntaxMacros/MacroProtocols/MemberMacro.swift index e5673bacc35..9a345ec6159 100644 --- a/Sources/SwiftSyntaxMacros/MacroProtocols/MemberMacro.swift +++ b/Sources/SwiftSyntaxMacros/MacroProtocols/MemberMacro.swift @@ -23,7 +23,9 @@ public protocol MemberMacro: AttachedMacro { /// /// - Returns: the set of member declarations introduced by this macro, which /// are nested inside the `attachedTo` declaration. - @available(*, deprecated, message: "Use expansion(of:providingMembersOf:conformingTo:in:") + /// + /// - Warning: This is the legacy `expansion` function of `MemberMacro` that is provided for backwards-compatiblity. + /// Use ``expansion(of:providingMembersOf:conformingTo:in:)-1sxoe`` instead. static func expansion( of node: AttributeSyntax, providingMembersOf declaration: some DeclGroupSyntax, @@ -54,6 +56,16 @@ public protocol MemberMacro: AttachedMacro { ) throws -> [DeclSyntax] } +private struct UnimplementedExpansionMethodError: Error, CustomStringConvertible { + var description: String { + """ + Types conforming to `MemberMacro` must implement either \ + expansion(of:providingMembersOf:in:) or \ + expansion(of:providingMembersOf:conformingTo:in:) + """ + } +} + public extension MemberMacro { /// Default implementation supplies no conformances. static func expansion( @@ -61,7 +73,7 @@ public extension MemberMacro { providingMembersOf declaration: some DeclGroupSyntax, in context: some MacroExpansionContext ) throws -> [DeclSyntax] { - return try expansion(of: node, providingMembersOf: declaration, conformingTo: [], in: context) + throw UnimplementedExpansionMethodError() } /// Default implementation that ignores the unhandled conformances. From c0f6bc5ab62af954f7699b3917c32b49b9541fe1 Mon Sep 17 00:00:00 2001 From: Ziyang Huang Date: Sun, 8 Oct 2023 21:23:04 +0800 Subject: [PATCH 02/12] Move `swift-parser-cli` to its own package # Conflicts: # Package.swift --- Package.swift | 21 --------- .../SwiftBasicFormat.docc/FilingBugReports.md | 4 +- .../SwiftParser.docc/FilingBugReports.md | 2 +- SwiftParserCLI/Package.swift | 47 +++++++++++++++++++ SwiftParserCLI/README.md | 14 ++++++ .../include/InstructionsExecuted.h | 17 +++++++ .../src/InstructionsExecuted.c | 38 +++++++++++++++ .../swift-parser-cli/BasicFormat.swift | 0 .../Commands/PerformanceTest.swift | 0 .../Commands/PrintDiags.swift | 0 .../swift-parser-cli/Commands/PrintTree.swift | 0 .../swift-parser-cli/Commands/Reduce.swift | 0 .../Commands/VerifyRoundTrip.swift | 0 .../swift-parser-cli/ParseCommand.swift | 0 .../swift-parser-cli/SyntaxUtils.swift | 0 .../swift-parser-cli/TerminalUtils.swift | 0 .../Sources}/swift-parser-cli/Utils.swift | 0 .../swift-parser-cli/swift-parser-cli.swift | 0 18 files changed, 119 insertions(+), 24 deletions(-) create mode 100644 SwiftParserCLI/Package.swift create mode 100644 SwiftParserCLI/README.md create mode 100644 SwiftParserCLI/Sources/_InstructionCounter/include/InstructionsExecuted.h create mode 100644 SwiftParserCLI/Sources/_InstructionCounter/src/InstructionsExecuted.c rename {Sources => SwiftParserCLI/Sources}/swift-parser-cli/BasicFormat.swift (100%) rename {Sources => SwiftParserCLI/Sources}/swift-parser-cli/Commands/PerformanceTest.swift (100%) rename {Sources => SwiftParserCLI/Sources}/swift-parser-cli/Commands/PrintDiags.swift (100%) rename {Sources => SwiftParserCLI/Sources}/swift-parser-cli/Commands/PrintTree.swift (100%) rename {Sources => SwiftParserCLI/Sources}/swift-parser-cli/Commands/Reduce.swift (100%) rename {Sources => SwiftParserCLI/Sources}/swift-parser-cli/Commands/VerifyRoundTrip.swift (100%) rename {Sources => SwiftParserCLI/Sources}/swift-parser-cli/ParseCommand.swift (100%) rename {Sources => SwiftParserCLI/Sources}/swift-parser-cli/SyntaxUtils.swift (100%) rename {Sources => SwiftParserCLI/Sources}/swift-parser-cli/TerminalUtils.swift (100%) rename {Sources => SwiftParserCLI/Sources}/swift-parser-cli/Utils.swift (100%) rename {Sources => SwiftParserCLI/Sources}/swift-parser-cli/swift-parser-cli.swift (100%) diff --git a/Package.swift b/Package.swift index f6d3efe5c16..86d810ba5b7 100644 --- a/Package.swift +++ b/Package.swift @@ -269,16 +269,6 @@ let package = Package( dependencies: ["_SwiftSyntaxTestSupport", "SwiftRefactor"] ), - // MARK: - Executable targets - - .executableTarget( - name: "swift-parser-cli", - dependencies: [ - "_InstructionCounter", "SwiftBasicFormat", "SwiftDiagnostics", "SwiftOperators", "SwiftParser", "SwiftParserDiagnostics", "SwiftSyntax", - .product(name: "ArgumentParser", package: "swift-argument-parser"), - ] - ), - // MARK: - Deprecated targets // MARK: PerformanceTest @@ -307,14 +297,3 @@ package.targets.append( } ) ) - -if ProcessInfo.processInfo.environment["SWIFTCI_USE_LOCAL_DEPS"] == nil { - // Building standalone. - package.dependencies += [ - .package(url: "https://github.com/apple/swift-argument-parser.git", from: "1.2.2") - ] -} else { - package.dependencies += [ - .package(path: "../swift-argument-parser") - ] -} diff --git a/Sources/SwiftBasicFormat/SwiftBasicFormat.docc/FilingBugReports.md b/Sources/SwiftBasicFormat/SwiftBasicFormat.docc/FilingBugReports.md index e28c69a6d3a..3c6179ab246 100644 --- a/Sources/SwiftBasicFormat/SwiftBasicFormat.docc/FilingBugReports.md +++ b/Sources/SwiftBasicFormat/SwiftBasicFormat.docc/FilingBugReports.md @@ -6,9 +6,9 @@ Guide to provide steps for filing actionable bug reports for `BasicFormat` failu Reducing a failure requires the `swift-parser-cli` utility that you can build by checking out `swift-syntax` and running ``` -swift build --product swift-parser-cli +swift build --package-path SwiftParserCLI ``` -or building the `swift-parser-cli` target in Xcode. +or openning `SwiftParserCLI` package and building the `swift-parser-cli` target in Xcode. 1. After you have built `swift-parse-cli`, you can format a single source file using BasicFormat by running the following command. If you are only experiencing the issue while formatting a single node, e.g. while creating an `AccessorDeclSyntax` inside a macro, you can additionally pass the type of the node as `--node-type AccessorDeclSyntax` ``` diff --git a/Sources/SwiftParser/SwiftParser.docc/FilingBugReports.md b/Sources/SwiftParser/SwiftParser.docc/FilingBugReports.md index 794e966c103..915afc1ab19 100644 --- a/Sources/SwiftParser/SwiftParser.docc/FilingBugReports.md +++ b/Sources/SwiftParser/SwiftParser.docc/FilingBugReports.md @@ -2,7 +2,7 @@ Guide to provide steps for filing actionable bug reports for parser failures. -Reducing a test case requires the `swift-parser-cli` utility that you can build by checking out `swift-syntax` and running `swift build --product swift-parser-cli` or building the `swift-parser-cli` target in Xcode. +Reducing a test case requires the `swift-parser-cli` utility that you can build by checking out `swift-syntax` and running `swift build --package-path SwiftParserCLI` or openning the `SwiftParserCLI` package and building the `swift-parser-cli` target in Xcode. ## Round-Trip Failure or Parser Crash diff --git a/SwiftParserCLI/Package.swift b/SwiftParserCLI/Package.swift new file mode 100644 index 00000000000..7828ed95d2e --- /dev/null +++ b/SwiftParserCLI/Package.swift @@ -0,0 +1,47 @@ +// swift-tools-version:5.7 + +import PackageDescription +import Foundation + +let package = Package( + name: "SwiftParserCLI", + platforms: [ + .macOS(.v10_15) + ], + products: [ + .executable(name: "swift-parser-cli", targets: ["swift-parser-cli"]) + ], + dependencies: [ + .package(path: "..") + ], + targets: [ + .target( + name: "_InstructionCounter" + ), + + .executableTarget( + name: "swift-parser-cli", + dependencies: [ + "_InstructionCounter", + .product(name: "SwiftBasicFormat", package: "swift-syntax"), + .product(name: "SwiftDiagnostics", package: "swift-syntax"), + .product(name: "SwiftOperators", package: "swift-syntax"), + .product(name: "SwiftParser", package: "swift-syntax"), + .product(name: "SwiftParserDiagnostics", package: "swift-syntax"), + .product(name: "SwiftSyntax", package: "swift-syntax"), + .product(name: "ArgumentParser", package: "swift-argument-parser"), + ] + ), + ] +) + +if ProcessInfo.processInfo.environment["SWIFTCI_USE_LOCAL_DEPS"] == nil { + // Building standalone. + package.dependencies += [ + .package(url: "https://github.com/apple/swift-argument-parser.git", from: "1.2.2") + ] +} else { + package.dependencies += [ + .package(path: "../../swift-argument-parser") + ] +} diff --git a/SwiftParserCLI/README.md b/SwiftParserCLI/README.md new file mode 100644 index 00000000000..f42dbdd7a12 --- /dev/null +++ b/SwiftParserCLI/README.md @@ -0,0 +1,14 @@ +# SwiftParserCLI + +This directory contains the source files of the `swift-parser-cli` program. + +You can build `swift-parser-cli` by checking out `swift-syntax` and running +``` +swift build --package-path SwiftParserCLI +``` +or entering this directory and running +``` +swift build +``` + +You can also open the `SwiftParserCLI` package and building the `swift-parser-cli` target in Xcode. diff --git a/SwiftParserCLI/Sources/_InstructionCounter/include/InstructionsExecuted.h b/SwiftParserCLI/Sources/_InstructionCounter/include/InstructionsExecuted.h new file mode 100644 index 00000000000..af9d9a4157b --- /dev/null +++ b/SwiftParserCLI/Sources/_InstructionCounter/include/InstructionsExecuted.h @@ -0,0 +1,17 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include + +/// On macOS returns the number of instructions the process has executed since +/// it was launched, on all other platforms returns 0. +uint64_t getInstructionsExecuted(); diff --git a/SwiftParserCLI/Sources/_InstructionCounter/src/InstructionsExecuted.c b/SwiftParserCLI/Sources/_InstructionCounter/src/InstructionsExecuted.c new file mode 100644 index 00000000000..4df6fa632f2 --- /dev/null +++ b/SwiftParserCLI/Sources/_InstructionCounter/src/InstructionsExecuted.c @@ -0,0 +1,38 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#if __APPLE__ +#include +#if TARGET_OS_MAC && !TARGET_OS_IPHONE +#define TARGET_IS_MACOS 1 +#endif +#endif + +#include "InstructionsExecuted.h" + +#ifdef TARGET_IS_MACOS +#include +#include +#include + +uint64_t getInstructionsExecuted() { + struct rusage_info_v4 ru; + if (proc_pid_rusage(getpid(), RUSAGE_INFO_V4, (rusage_info_t *)&ru) == 0) { + return ru.ri_instructions; + } + return 0; +} +#else +uint64_t getInstructionsExecuted() { + return 0; +} +#endif diff --git a/Sources/swift-parser-cli/BasicFormat.swift b/SwiftParserCLI/Sources/swift-parser-cli/BasicFormat.swift similarity index 100% rename from Sources/swift-parser-cli/BasicFormat.swift rename to SwiftParserCLI/Sources/swift-parser-cli/BasicFormat.swift diff --git a/Sources/swift-parser-cli/Commands/PerformanceTest.swift b/SwiftParserCLI/Sources/swift-parser-cli/Commands/PerformanceTest.swift similarity index 100% rename from Sources/swift-parser-cli/Commands/PerformanceTest.swift rename to SwiftParserCLI/Sources/swift-parser-cli/Commands/PerformanceTest.swift diff --git a/Sources/swift-parser-cli/Commands/PrintDiags.swift b/SwiftParserCLI/Sources/swift-parser-cli/Commands/PrintDiags.swift similarity index 100% rename from Sources/swift-parser-cli/Commands/PrintDiags.swift rename to SwiftParserCLI/Sources/swift-parser-cli/Commands/PrintDiags.swift diff --git a/Sources/swift-parser-cli/Commands/PrintTree.swift b/SwiftParserCLI/Sources/swift-parser-cli/Commands/PrintTree.swift similarity index 100% rename from Sources/swift-parser-cli/Commands/PrintTree.swift rename to SwiftParserCLI/Sources/swift-parser-cli/Commands/PrintTree.swift diff --git a/Sources/swift-parser-cli/Commands/Reduce.swift b/SwiftParserCLI/Sources/swift-parser-cli/Commands/Reduce.swift similarity index 100% rename from Sources/swift-parser-cli/Commands/Reduce.swift rename to SwiftParserCLI/Sources/swift-parser-cli/Commands/Reduce.swift diff --git a/Sources/swift-parser-cli/Commands/VerifyRoundTrip.swift b/SwiftParserCLI/Sources/swift-parser-cli/Commands/VerifyRoundTrip.swift similarity index 100% rename from Sources/swift-parser-cli/Commands/VerifyRoundTrip.swift rename to SwiftParserCLI/Sources/swift-parser-cli/Commands/VerifyRoundTrip.swift diff --git a/Sources/swift-parser-cli/ParseCommand.swift b/SwiftParserCLI/Sources/swift-parser-cli/ParseCommand.swift similarity index 100% rename from Sources/swift-parser-cli/ParseCommand.swift rename to SwiftParserCLI/Sources/swift-parser-cli/ParseCommand.swift diff --git a/Sources/swift-parser-cli/SyntaxUtils.swift b/SwiftParserCLI/Sources/swift-parser-cli/SyntaxUtils.swift similarity index 100% rename from Sources/swift-parser-cli/SyntaxUtils.swift rename to SwiftParserCLI/Sources/swift-parser-cli/SyntaxUtils.swift diff --git a/Sources/swift-parser-cli/TerminalUtils.swift b/SwiftParserCLI/Sources/swift-parser-cli/TerminalUtils.swift similarity index 100% rename from Sources/swift-parser-cli/TerminalUtils.swift rename to SwiftParserCLI/Sources/swift-parser-cli/TerminalUtils.swift diff --git a/Sources/swift-parser-cli/Utils.swift b/SwiftParserCLI/Sources/swift-parser-cli/Utils.swift similarity index 100% rename from Sources/swift-parser-cli/Utils.swift rename to SwiftParserCLI/Sources/swift-parser-cli/Utils.swift diff --git a/Sources/swift-parser-cli/swift-parser-cli.swift b/SwiftParserCLI/Sources/swift-parser-cli/swift-parser-cli.swift similarity index 100% rename from Sources/swift-parser-cli/swift-parser-cli.swift rename to SwiftParserCLI/Sources/swift-parser-cli/swift-parser-cli.swift From 6e32c273011bd8cb535b0f5b80e5e0767363b569 Mon Sep 17 00:00:00 2001 From: Ziyang Huang Date: Tue, 22 Aug 2023 22:10:28 +0800 Subject: [PATCH 03/12] Make CI build `SwiftParserCLI` --- .../Sources/swift-syntax-dev-utils/commands/Build.swift | 1 + .../Sources/swift-syntax-dev-utils/common/Paths.swift | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/SwiftSyntaxDevUtils/Sources/swift-syntax-dev-utils/commands/Build.swift b/SwiftSyntaxDevUtils/Sources/swift-syntax-dev-utils/commands/Build.swift index 171a6274dc9..ae884a7c02d 100644 --- a/SwiftSyntaxDevUtils/Sources/swift-syntax-dev-utils/commands/Build.swift +++ b/SwiftSyntaxDevUtils/Sources/swift-syntax-dev-utils/commands/Build.swift @@ -26,6 +26,7 @@ struct Build: ParsableCommand, BuildCommand { func run() throws { try buildTarget(packageDir: Paths.packageDir, targetName: "SwiftSyntax-all") try buildTarget(packageDir: Paths.examplesDir, targetName: "Examples-all") + try buildTarget(packageDir: Paths.swiftParserCliDir, targetName: "swift-parser-cli") try buildEditorExtension() } diff --git a/SwiftSyntaxDevUtils/Sources/swift-syntax-dev-utils/common/Paths.swift b/SwiftSyntaxDevUtils/Sources/swift-syntax-dev-utils/common/Paths.swift index 48a42e5e42f..693314275d4 100644 --- a/SwiftSyntaxDevUtils/Sources/swift-syntax-dev-utils/common/Paths.swift +++ b/SwiftSyntaxDevUtils/Sources/swift-syntax-dev-utils/common/Paths.swift @@ -32,6 +32,11 @@ enum Paths { .appendingPathComponent("Examples") } + static var swiftParserCliDir: URL { + packageDir + .appendingPathComponent("SwiftParserCLI") + } + static var codeGenerationDir: URL { packageDir .appendingPathComponent("CodeGeneration") From 9b3c7c236667202192acc772320de182e97e26a7 Mon Sep 17 00:00:00 2001 From: Ziyang Huang Date: Sun, 8 Oct 2023 21:26:48 +0800 Subject: [PATCH 04/12] Rename `_InstructionCounter` in `SwiftParserCLI` to `InstructionCounter` --- SwiftParserCLI/Package.swift | 4 ++-- .../include/InstructionsExecuted.h | 0 .../src/InstructionsExecuted.c | 0 .../Sources/swift-parser-cli/Commands/PerformanceTest.swift | 2 +- .../Sources/swift-parser-cli/swift-parser-cli.swift | 2 +- 5 files changed, 4 insertions(+), 4 deletions(-) rename SwiftParserCLI/Sources/{_InstructionCounter => InstructionCounter}/include/InstructionsExecuted.h (100%) rename SwiftParserCLI/Sources/{_InstructionCounter => InstructionCounter}/src/InstructionsExecuted.c (100%) diff --git a/SwiftParserCLI/Package.swift b/SwiftParserCLI/Package.swift index 7828ed95d2e..eae45c5d3a8 100644 --- a/SwiftParserCLI/Package.swift +++ b/SwiftParserCLI/Package.swift @@ -16,13 +16,13 @@ let package = Package( ], targets: [ .target( - name: "_InstructionCounter" + name: "InstructionCounter" ), .executableTarget( name: "swift-parser-cli", dependencies: [ - "_InstructionCounter", + "InstructionCounter", .product(name: "SwiftBasicFormat", package: "swift-syntax"), .product(name: "SwiftDiagnostics", package: "swift-syntax"), .product(name: "SwiftOperators", package: "swift-syntax"), diff --git a/SwiftParserCLI/Sources/_InstructionCounter/include/InstructionsExecuted.h b/SwiftParserCLI/Sources/InstructionCounter/include/InstructionsExecuted.h similarity index 100% rename from SwiftParserCLI/Sources/_InstructionCounter/include/InstructionsExecuted.h rename to SwiftParserCLI/Sources/InstructionCounter/include/InstructionsExecuted.h diff --git a/SwiftParserCLI/Sources/_InstructionCounter/src/InstructionsExecuted.c b/SwiftParserCLI/Sources/InstructionCounter/src/InstructionsExecuted.c similarity index 100% rename from SwiftParserCLI/Sources/_InstructionCounter/src/InstructionsExecuted.c rename to SwiftParserCLI/Sources/InstructionCounter/src/InstructionsExecuted.c diff --git a/SwiftParserCLI/Sources/swift-parser-cli/Commands/PerformanceTest.swift b/SwiftParserCLI/Sources/swift-parser-cli/Commands/PerformanceTest.swift index 300b175cbd0..ac60ea3da9d 100644 --- a/SwiftParserCLI/Sources/swift-parser-cli/Commands/PerformanceTest.swift +++ b/SwiftParserCLI/Sources/swift-parser-cli/Commands/PerformanceTest.swift @@ -10,11 +10,11 @@ // //===----------------------------------------------------------------------===// +import InstructionCounter import ArgumentParser import Foundation import SwiftParser import SwiftSyntax -import _InstructionCounter struct PerformanceTest: ParsableCommand { static var configuration = CommandConfiguration( diff --git a/SwiftParserCLI/Sources/swift-parser-cli/swift-parser-cli.swift b/SwiftParserCLI/Sources/swift-parser-cli/swift-parser-cli.swift index d2b51ead174..21f02d924c0 100644 --- a/SwiftParserCLI/Sources/swift-parser-cli/swift-parser-cli.swift +++ b/SwiftParserCLI/Sources/swift-parser-cli/swift-parser-cli.swift @@ -12,12 +12,12 @@ import ArgumentParser import Foundation +import InstructionCounter import SwiftDiagnostics import SwiftOperators import SwiftParser import SwiftParserDiagnostics import SwiftSyntax -import _InstructionCounter #if os(Windows) import WinSDK From e52b0d9b1aa987a3ab5f99f2f6a1c5537c3b669d Mon Sep 17 00:00:00 2001 From: Ziyang Huang Date: Tue, 10 Oct 2023 22:57:45 +0800 Subject: [PATCH 05/12] Run `swift-format` to format codes --- SwiftParserCLI/Package.swift | 2 +- .../Sources/swift-parser-cli/Commands/PerformanceTest.swift | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/SwiftParserCLI/Package.swift b/SwiftParserCLI/Package.swift index eae45c5d3a8..c59ec321d32 100644 --- a/SwiftParserCLI/Package.swift +++ b/SwiftParserCLI/Package.swift @@ -1,7 +1,7 @@ // swift-tools-version:5.7 -import PackageDescription import Foundation +import PackageDescription let package = Package( name: "SwiftParserCLI", diff --git a/SwiftParserCLI/Sources/swift-parser-cli/Commands/PerformanceTest.swift b/SwiftParserCLI/Sources/swift-parser-cli/Commands/PerformanceTest.swift index ac60ea3da9d..4b8d545ee28 100644 --- a/SwiftParserCLI/Sources/swift-parser-cli/Commands/PerformanceTest.swift +++ b/SwiftParserCLI/Sources/swift-parser-cli/Commands/PerformanceTest.swift @@ -10,9 +10,9 @@ // //===----------------------------------------------------------------------===// -import InstructionCounter import ArgumentParser import Foundation +import InstructionCounter import SwiftParser import SwiftSyntax From 99f91bc34cd49127aaa2e30e57ef498d3eda8abe Mon Sep 17 00:00:00 2001 From: Rauhul Varma Date: Mon, 16 Oct 2023 11:37:43 -0700 Subject: [PATCH 06/12] Fix missing space in LabeledExprSyntax init Updates LabeledExprSyntax convenience initializer to include a trailing space trivia after the colon if an argument label is specified. This ensures the rendered description is 'arg: value' instead of 'arg:value'. --- .../ConvenienceInitializers.swift | 2 +- Tests/SwiftSyntaxBuilderTest/Assertions.swift | 5 ++++- .../LabeledExprSyntaxTests.swift | 22 +++++++++++++++++++ 3 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 Tests/SwiftSyntaxBuilderTest/LabeledExprSyntaxTests.swift diff --git a/Sources/SwiftSyntaxBuilder/ConvenienceInitializers.swift b/Sources/SwiftSyntaxBuilder/ConvenienceInitializers.swift index 6c4c3a302b9..7b2d8b77964 100644 --- a/Sources/SwiftSyntaxBuilder/ConvenienceInitializers.swift +++ b/Sources/SwiftSyntaxBuilder/ConvenienceInitializers.swift @@ -346,7 +346,7 @@ extension LabeledExprSyntax { public init(label: String? = nil, expression: some ExprSyntaxProtocol) { self.init( label: label.map { .identifier($0) }, - colon: label == nil ? nil : .colonToken(), + colon: label == nil ? nil : .colonToken(trailingTrivia: .space), expression: expression ) } diff --git a/Tests/SwiftSyntaxBuilderTest/Assertions.swift b/Tests/SwiftSyntaxBuilderTest/Assertions.swift index da1af7c6eb8..9e3a8d7d9cd 100644 --- a/Tests/SwiftSyntaxBuilderTest/Assertions.swift +++ b/Tests/SwiftSyntaxBuilderTest/Assertions.swift @@ -19,10 +19,13 @@ func assertBuildResult( _ buildable: T, _ expectedResult: String, trimTrailingWhitespace: Bool = true, + format: Bool = true, file: StaticString = #file, line: UInt = #line ) { - var buildableDescription = buildable.formatted().description + var buildableDescription = format + ? buildable.formatted().description + : buildable.description var expectedResult = expectedResult if trimTrailingWhitespace { buildableDescription = buildableDescription.trimmingTrailingWhitespace() diff --git a/Tests/SwiftSyntaxBuilderTest/LabeledExprSyntaxTests.swift b/Tests/SwiftSyntaxBuilderTest/LabeledExprSyntaxTests.swift new file mode 100644 index 00000000000..64075f57c07 --- /dev/null +++ b/Tests/SwiftSyntaxBuilderTest/LabeledExprSyntaxTests.swift @@ -0,0 +1,22 @@ +//===----------------------------------------------------------------------===// +// +// 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 +import SwiftSyntaxBuilder +import XCTest + +final class LabeledExprSyntaxTests: XCTestCase { + func testLabeledExprSyntax() { + let syntax = LabeledExprSyntax(label: "arg", expression: NilLiteralExprSyntax()) + assertBuildResult(syntax, "arg: nil", format: false) + } +} From 3bc85d8d78084fd9828fc815a032fd32c5c719e2 Mon Sep 17 00:00:00 2001 From: Rauhul Varma Date: Mon, 16 Oct 2023 14:00:06 -0700 Subject: [PATCH 07/12] fix formatting --- Tests/SwiftSyntaxBuilderTest/Assertions.swift | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Tests/SwiftSyntaxBuilderTest/Assertions.swift b/Tests/SwiftSyntaxBuilderTest/Assertions.swift index 9e3a8d7d9cd..5e9d2afc4a5 100644 --- a/Tests/SwiftSyntaxBuilderTest/Assertions.swift +++ b/Tests/SwiftSyntaxBuilderTest/Assertions.swift @@ -23,7 +23,8 @@ func assertBuildResult( file: StaticString = #file, line: UInt = #line ) { - var buildableDescription = format + var buildableDescription = + format ? buildable.formatted().description : buildable.description var expectedResult = expectedResult From 07394b588f711fae8c40f99b5056325ba1e759c3 Mon Sep 17 00:00:00 2001 From: Alex Hoppen Date: Mon, 16 Oct 2023 11:32:38 -0700 Subject: [PATCH 08/12] Update the interpolation failure message When a user is getting the interpolation `os_log` failure message but actually supports parsing invalid source code, offer them an alternative parses the source code without checking for errors. --- .../SyntaxParsable+ExpressibleByStringInterpolation.swift | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Sources/SwiftSyntaxBuilder/SyntaxParsable+ExpressibleByStringInterpolation.swift b/Sources/SwiftSyntaxBuilder/SyntaxParsable+ExpressibleByStringInterpolation.swift index 741d26bb0ba..9b124cd5217 100644 --- a/Sources/SwiftSyntaxBuilder/SyntaxParsable+ExpressibleByStringInterpolation.swift +++ b/Sources/SwiftSyntaxBuilder/SyntaxParsable+ExpressibleByStringInterpolation.swift @@ -48,10 +48,14 @@ extension SyntaxParseable { { let diagnostics = ParseDiagnosticsGenerator.diagnostics(for: self) let formattedDiagnostics = DiagnosticsFormatter().annotatedSource(tree: self, diags: diagnostics) - Logger(subsystem: "SwiftSyntax", category: "ParseError").fault( + Logger(subsystem: "org.swift.swift-syntax", category: "ParseError").fault( """ Parsing a `\(Self.self)` node from string interpolation produced the following parsing errors. Set a breakpoint in `SyntaxParseable.logStringInterpolationParsingError()` to debug the failure. + + To explicitly support parsing of invalid source code, import SwiftParser and invoke the parser as follows + var parser = Parser(source) + \(Self.self).parse(from: &parser) \(formattedDiagnostics, privacy: .private) """ ) @@ -61,7 +65,7 @@ extension SyntaxParseable { /// Initialize the syntax node from a string interpolation. /// - /// - Important: This asssumes that the string interpolation produces a valid + /// - Important: This assumes that the string interpolation produces a valid /// syntax tree. If the syntax tree is not valid, a fault will /// be logged using OSLog on Darwin platforms. public init(stringInterpolation: SyntaxStringInterpolation) { From 88ae8050125ebae93591b95bf8cd9da918ee761f Mon Sep 17 00:00:00 2001 From: Kim de Vos Date: Thu, 5 Oct 2023 21:23:24 +0200 Subject: [PATCH 09/12] Rename `NoteMessage.fixItID` to `noteID` --- Release Notes/510.md | 4 ++++ Sources/SwiftDiagnostics/Note.swift | 9 ++++++++- .../ParserDiagnosticMessages.swift | 13 +++++++++---- 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/Release Notes/510.md b/Release Notes/510.md index 9adf09c29ce..8ae0439576b 100644 --- a/Release Notes/510.md +++ b/Release Notes/510.md @@ -42,6 +42,10 @@ ## API-Incompatible Changes +- `NoteMessage.fixItID` renamed to `noteID` + - Description: This was an error that it was named `fixItID` and should have been named `noteID` instead. Accesses to `fixItID` are deprecated and forward to `noteID`. Any types that conform `NoteMessage` it will need to be updated to provide a `noteID` instead of a `fixItID`. + - Issue: https://github.com/apple/swift-syntax/issues/2261 + - Pull Request: https://github.com/apple/swift-syntax/pull/2264 ## Template diff --git a/Sources/SwiftDiagnostics/Note.swift b/Sources/SwiftDiagnostics/Note.swift index fecbe1a056a..5a868da2ae5 100644 --- a/Sources/SwiftDiagnostics/Note.swift +++ b/Sources/SwiftDiagnostics/Note.swift @@ -20,7 +20,14 @@ public protocol NoteMessage { var message: String { get } /// See ``MessageID``. - var fixItID: MessageID { get } + var noteID: MessageID { get } +} + +extension NoteMessage { + @available(*, deprecated, message: "Use noteID instead.", renamed: "noteID") + public var fixItID: MessageID { + return noteID + } } /// A note that points to another node that's relevant for a Diagnostic. diff --git a/Sources/SwiftParserDiagnostics/ParserDiagnosticMessages.swift b/Sources/SwiftParserDiagnostics/ParserDiagnosticMessages.swift index 8d210bd5be6..6b755497154 100644 --- a/Sources/SwiftParserDiagnostics/ParserDiagnosticMessages.swift +++ b/Sources/SwiftParserDiagnostics/ParserDiagnosticMessages.swift @@ -36,16 +36,21 @@ public extension ParserError { } public protocol ParserNote: NoteMessage { - var fixItID: MessageID { get } + var noteID: MessageID { get } } public extension ParserNote { + @available(*, deprecated, message: "Use noteID instead.", renamed: "noteID") static var fixItID: MessageID { + return Self.noteID + } + + static var noteID: MessageID { return MessageID(domain: diagnosticDomain, id: "\(self)") } - var fixItID: MessageID { - return Self.fixItID + var noteID: MessageID { + return Self.noteID } } @@ -573,7 +578,7 @@ public struct StaticParserNote: NoteMessage { self.messageID = messageID } - public var fixItID: MessageID { + public var noteID: MessageID { MessageID(domain: diagnosticDomain, id: "\(type(of: self)).\(messageID)") } } From e91826fc2af8a89810a4c65fbbd320957f56b126 Mon Sep 17 00:00:00 2001 From: JP Simard Date: Wed, 1 Nov 2023 09:46:57 -0400 Subject: [PATCH 10/12] Mark `SyntaxChildrenIndex` as `Sendable` Otherwise consumers of SwiftSyntax may encounter warnings when compiling with `-strict-concurrency=complete`. For example: ```swift extension DeclModifierListSyntax { var fileprivateModifierIndex: DeclModifierListSyntax.Index? { firstIndex(where: { $0.name.tokenKind == .keyword(.fileprivate) }) } var fileprivateModifier: DeclModifierSyntax? { fileprivateModifierIndex.flatMap { self[$0] } } func replacing(fileprivateModifierIndex: DeclModifierListSyntax.Index) -> DeclModifierListSyntax { let fileprivateModifier = self[fileprivateModifierIndex] return with( \.[fileprivateModifierIndex], fileprivateModifier.with( \.name, .keyword( .private, leadingTrivia: fileprivateModifier.leadingTrivia, trailingTrivia: fileprivateModifier.trailingTrivia ) ) ) } } ``` Produces the following warning: > cannot form key path that captures non-sendable type > 'DeclModifierListSyntax.Index' (aka 'SyntaxChildrenIndex') --- Sources/SwiftSyntax/SyntaxChildren.swift | 4 ++-- Sources/SwiftSyntax/SyntaxIdentifier.swift | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Sources/SwiftSyntax/SyntaxChildren.swift b/Sources/SwiftSyntax/SyntaxChildren.swift index ffe67a40bdf..893ccb56fe0 100644 --- a/Sources/SwiftSyntax/SyntaxChildren.swift +++ b/Sources/SwiftSyntax/SyntaxChildren.swift @@ -14,7 +14,7 @@ /// The data for an index in a syntax children collection that is not the end /// index. See ``SyntaxChildrenIndex`` for the representation of the end index. -struct SyntaxChildrenIndexData: Hashable, Comparable { +struct SyntaxChildrenIndexData: Hashable, Comparable, Sendable { /// The UTF-8 offset of the item at this index in the source file /// See `AbsoluteSyntaxPosition.offset` let offset: UInt32 @@ -50,7 +50,7 @@ struct SyntaxChildrenIndexData: Hashable, Comparable { } /// An index in a syntax children collection. -public struct SyntaxChildrenIndex: Hashable, Comparable, ExpressibleByNilLiteral { +public struct SyntaxChildrenIndex: Hashable, Comparable, ExpressibleByNilLiteral, Sendable { /// Construct the `endIndex` of a ``SyntaxChildren`` collection. public init(nilLiteral: ()) { self.data = nil diff --git a/Sources/SwiftSyntax/SyntaxIdentifier.swift b/Sources/SwiftSyntax/SyntaxIdentifier.swift index 6886c6bfe3f..8f3c297cf16 100644 --- a/Sources/SwiftSyntax/SyntaxIdentifier.swift +++ b/Sources/SwiftSyntax/SyntaxIdentifier.swift @@ -12,7 +12,7 @@ /// Represents a unique value for a node within its own tree. @_spi(RawSyntax) -public struct SyntaxIndexInTree: Comparable, Hashable { +public struct SyntaxIndexInTree: Comparable, Hashable, Sendable { let indexInTree: UInt32 static var zero: SyntaxIndexInTree = SyntaxIndexInTree(indexInTree: 0) From e9c6e0bddba2eff7987abfa8605d5cc53d92c9b3 Mon Sep 17 00:00:00 2001 From: Stephen Celis Date: Tue, 20 Jun 2023 09:20:26 -0700 Subject: [PATCH 11/12] Conform `MessageID` and `DiagnosticSeverity` to `Sendable` --- Sources/SwiftDiagnostics/Message.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Sources/SwiftDiagnostics/Message.swift b/Sources/SwiftDiagnostics/Message.swift index 6ee0decf630..2bb6a905ced 100644 --- a/Sources/SwiftDiagnostics/Message.swift +++ b/Sources/SwiftDiagnostics/Message.swift @@ -16,7 +16,7 @@ /// Two diagnostics with the same ID don’t need to necessarily have the exact /// same wording. Eg. it’s possible that the message contains more context when /// available. -public struct MessageID: Hashable { +public struct MessageID: Hashable, Sendable { private let domain: String private let id: String @@ -26,7 +26,7 @@ public struct MessageID: Hashable { } } -public enum DiagnosticSeverity { +public enum DiagnosticSeverity: Sendable { case error case warning case note From 58a574e142f2c7a04532bdb1716467db5f761788 Mon Sep 17 00:00:00 2001 From: Ruslan Alikhamov Date: Mon, 23 Oct 2023 22:35:34 +0400 Subject: [PATCH 12/12] Squashed commit of the following: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 4cd97568099ff03aa9edce1cdadf9030336d2931 Author: Ruslan Alikhamov Date: Mon Oct 23 22:17:28 2023 +0400 applied swift-format commit dc59e96cff056f46051777feee220b75bd0a3878 Author: Ruslan Alikhamov Date: Mon Oct 23 22:02:35 2023 +0400 removed redundant variable commit ff953021cb8ee75127b979e33209abb5cd9ea7ba Author: Ruslan Alikhamov Date: Mon Oct 23 22:00:23 2023 +0400 refactored optimization in isValidIdentifierContinuationCodePoint commit 5b94ec9ba640d6e033b6f02976cc86fb7cbee273 Author: Ruslan Alikhamov Date: Mon Oct 23 21:51:48 2023 +0400 fixed a typo; renamed variables commit 7e1f23dca379df7b0421de78910aa5fe42b3da9c Author: Ruslan Alikhamov Date: Mon Oct 23 21:38:08 2023 +0400 renamed variables in slice(of:) commit 3b9c1f88829a83748659744af8002886a24700af Author: Ruslan Alikhamov Date: Sat Oct 21 19:45:34 2023 +0400 removed redundant newline commit 83ad08cb0602bf540ad356c922d1000af59eaa73 Author: Ruslan Alikhamov Date: Sat Oct 21 19:02:13 2023 +0400 optimized isSlice(of other: SyntaxText) -> Bool commit f5d0a3a1ab5b426cf5927f726a2faf33dda4aa3d Author: Ruslan Alikhamov Date: Sat Oct 21 19:02:03 2023 +0400 optimized isValidIdentifierContinuationCodePoint --- .../Lexer/UnicodeScalarExtensions.swift | 98 ++++++++++--------- Sources/SwiftSyntax/SyntaxText.swift | 4 +- 2 files changed, 55 insertions(+), 47 deletions(-) diff --git a/Sources/SwiftParser/Lexer/UnicodeScalarExtensions.swift b/Sources/SwiftParser/Lexer/UnicodeScalarExtensions.swift index 52774807220..03e86252c75 100644 --- a/Sources/SwiftParser/Lexer/UnicodeScalarExtensions.swift +++ b/Sources/SwiftParser/Lexer/UnicodeScalarExtensions.swift @@ -19,52 +19,58 @@ extension Unicode.Scalar { // N1518: Recommendations for extended identifier characters for C and C++ // Proposed Annex X.1: Ranges of characters allowed let c = self.value - return c == 0x00A8 || c == 0x00AA || c == 0x00AD || c == 0x00AF - || (c >= 0x00B2 && c <= 0x00B5) || (c >= 0x00B7 && c <= 0x00BA) - || (c >= 0x00BC && c <= 0x00BE) || (c >= 0x00C0 && c <= 0x00D6) - || (c >= 0x00D8 && c <= 0x00F6) || (c >= 0x00F8 && c <= 0x00FF) - - || (c >= 0x0100 && c <= 0x167F) - || (c >= 0x1681 && c <= 0x180D) - || (c >= 0x180F && c <= 0x1FFF) - - || (c >= 0x200B && c <= 0x200D) - || (c >= 0x202A && c <= 0x202E) - || (c >= 0x203F && c <= 0x2040) - || c == 0x2054 - || (c >= 0x2060 && c <= 0x206F) - - || (c >= 0x2070 && c <= 0x218F) - || (c >= 0x2460 && c <= 0x24FF) - || (c >= 0x2776 && c <= 0x2793) - || (c >= 0x2C00 && c <= 0x2DFF) - || (c >= 0x2E80 && c <= 0x2FFF) - - || (c >= 0x3004 && c <= 0x3007) - || (c >= 0x3021 && c <= 0x302F) - || (c >= 0x3031 && c <= 0x303F) - - || (c >= 0x3040 && c <= 0xD7FF) - - || (c >= 0xF900 && c <= 0xFD3D) - || (c >= 0xFD40 && c <= 0xFDCF) - || (c >= 0xFDF0 && c <= 0xFE44) - || (c >= 0xFE47 && c <= 0xFFF8) - - || (c >= 0x10000 && c <= 0x1FFFD) - || (c >= 0x20000 && c <= 0x2FFFD) - || (c >= 0x30000 && c <= 0x3FFFD) - || (c >= 0x40000 && c <= 0x4FFFD) - || (c >= 0x50000 && c <= 0x5FFFD) - || (c >= 0x60000 && c <= 0x6FFFD) - || (c >= 0x70000 && c <= 0x7FFFD) - || (c >= 0x80000 && c <= 0x8FFFD) - || (c >= 0x90000 && c <= 0x9FFFD) - || (c >= 0xA0000 && c <= 0xAFFFD) - || (c >= 0xB0000 && c <= 0xBFFFD) - || (c >= 0xC0000 && c <= 0xCFFFD) - || (c >= 0xD0000 && c <= 0xDFFFD) - || (c >= 0xE0000 && c <= 0xEFFFD) + return (c == 0x00A8) as Bool + || (c == 0x00AA) as Bool + || (c == 0x00AD) as Bool + || (c == 0x00AF) as Bool + || (c >= 0x00B2 && c <= 0x00B5) as Bool + || (c >= 0x00B7 && c <= 0x00BA) as Bool + || (c >= 0x00BC && c <= 0x00BE) as Bool + || (c >= 0x00C0 && c <= 0x00D6) as Bool + || (c >= 0x00D8 && c <= 0x00F6) as Bool + || (c >= 0x00F8 && c <= 0x00FF) as Bool + + || (c >= 0x0100 && c <= 0x167F) as Bool + || (c >= 0x1681 && c <= 0x180D) as Bool + || (c >= 0x180F && c <= 0x1FFF) as Bool + + || (c >= 0x200B && c <= 0x200D) as Bool + || (c >= 0x202A && c <= 0x202E) as Bool + || (c >= 0x203F && c <= 0x2040) as Bool + || (c == 0x2054) as Bool + || (c >= 0x2060 && c <= 0x206F) as Bool + + || (c >= 0x2070 && c <= 0x218F) as Bool + || (c >= 0x2460 && c <= 0x24FF) as Bool + || (c >= 0x2776 && c <= 0x2793) as Bool + || (c >= 0x2C00 && c <= 0x2DFF) as Bool + || (c >= 0x2E80 && c <= 0x2FFF) as Bool + + || (c >= 0x3004 && c <= 0x3007) as Bool + || (c >= 0x3021 && c <= 0x302F) as Bool + || (c >= 0x3031 && c <= 0x303F) as Bool + + || (c >= 0x3040 && c <= 0xD7FF) as Bool + + || (c >= 0xF900 && c <= 0xFD3D) as Bool + || (c >= 0xFD40 && c <= 0xFDCF) as Bool + || (c >= 0xFDF0 && c <= 0xFE44) as Bool + || (c >= 0xFE47 && c <= 0xFFF8) as Bool + + || (c >= 0x10000 && c <= 0x1FFFD) as Bool + || (c >= 0x20000 && c <= 0x2FFFD) as Bool + || (c >= 0x30000 && c <= 0x3FFFD) as Bool + || (c >= 0x40000 && c <= 0x4FFFD) as Bool + || (c >= 0x50000 && c <= 0x5FFFD) as Bool + || (c >= 0x60000 && c <= 0x6FFFD) as Bool + || (c >= 0x70000 && c <= 0x7FFFD) as Bool + || (c >= 0x80000 && c <= 0x8FFFD) as Bool + || (c >= 0x90000 && c <= 0x9FFFD) as Bool + || (c >= 0xA0000 && c <= 0xAFFFD) as Bool + || (c >= 0xB0000 && c <= 0xBFFFD) as Bool + || (c >= 0xC0000 && c <= 0xCFFFD) as Bool + || (c >= 0xD0000 && c <= 0xDFFFD) as Bool + || (c >= 0xE0000 && c <= 0xEFFFD) as Bool } var isValidIdentifierStartCodePoint: Bool { diff --git a/Sources/SwiftSyntax/SyntaxText.swift b/Sources/SwiftSyntax/SyntaxText.swift index 310bcb22836..c5068a76aa4 100644 --- a/Sources/SwiftSyntax/SyntaxText.swift +++ b/Sources/SwiftSyntax/SyntaxText.swift @@ -100,7 +100,9 @@ public struct SyntaxText { guard !self.isEmpty && !other.isEmpty else { return self.isEmpty && other.isEmpty } - return (other.baseAddress! <= self.baseAddress! && self.baseAddress! + count <= other.baseAddress! + other.count) + let selfEndBound = UnsafePointer(self.baseAddress! + count) + let otherEndBound = UnsafePointer(other.baseAddress! + other.count) + return (other.baseAddress! <= self.baseAddress!) && (selfEndBound <= otherEndBound) } /// Returns `true` if `other` is a substring of this ``SyntaxText``.