diff --git a/CodeGeneration/Sources/SyntaxSupport/AvailabilityNodes.swift b/CodeGeneration/Sources/SyntaxSupport/AvailabilityNodes.swift index 80134e48eb2..9eec1c5ba78 100644 --- a/CodeGeneration/Sources/SyntaxSupport/AvailabilityNodes.swift +++ b/CodeGeneration/Sources/SyntaxSupport/AvailabilityNodes.swift @@ -118,42 +118,51 @@ public let AVAILABILITY_NODES: [Node] = [ ] ), - // version-tuple -> integer-literal - // | float-literal - // | float-literal '.' integer-literal + // version-tuple-element -> '.' integer-literal Node( - name: "VersionTuple", - nameForDiagnostics: "version tuple", - description: "A version number of the form major.minor.patch in which the minor and patch part may be omitted.", + name: "VersionComponent", + nameForDiagnostics: nil, + description: "An element to represent a single component in a version, like `.1`.", kind: "Syntax", children: [ Child( - name: "Major", - kind: .token(choices: [.token(tokenKind: "IntegerLiteralToken")]), - description: "The major version." - ), - Child( - name: "MinorPeriod", + name: "Period", kind: .token(choices: [.token(tokenKind: "PeriodToken")]), - description: "If the version contains a minor number, the period separating the major from the minor number.", - isOptional: true + description: "The period of this version component" ), Child( - name: "Minor", + name: "Number", kind: .token(choices: [.token(tokenKind: "IntegerLiteralToken")]), - description: "The minor version if specified.", - isOptional: true + description: "The version number of this component" ), + ] + ), + + // version-list -> version-tuple-element version-list? + Node( + name: "VersionComponentList", + nameForDiagnostics: nil, + kind: "SyntaxCollection", + element: "VersionComponent", + omitWhenEmpty: true + ), + + // version-tuple -> integer-literal version-list? + Node( + name: "VersionTuple", + nameForDiagnostics: "version tuple", + description: "A version number like `1.2.0`. Only the first version component is required. There might be an arbitrary number of following components.", + kind: "Syntax", + children: [ Child( - name: "PatchPeriod", - kind: .token(choices: [.token(tokenKind: "PeriodToken")]), - description: "If the version contains a patch number, the period separating the minor from the patch number.", - isOptional: true + name: "Major", + kind: .token(choices: [.token(tokenKind: "IntegerLiteralToken")]), + description: "The major version." ), Child( - name: "Patch", - kind: .token(choices: [.token(tokenKind: "IntegerLiteralToken")]), - description: "The patch version if specified.", + name: "Components", + kind: .collection(kind: "VersionComponentList", collectionElementName: "VersionComponent"), + description: "Any version components that are not the major version . For example, for `1.2.0`, this will contain `.2.0`", isOptional: true ), ] diff --git a/CodeGeneration/Sources/SyntaxSupport/Child.swift b/CodeGeneration/Sources/SyntaxSupport/Child.swift index a9a7b343dc3..178f1e355f0 100644 --- a/CodeGeneration/Sources/SyntaxSupport/Child.swift +++ b/CodeGeneration/Sources/SyntaxSupport/Child.swift @@ -161,6 +161,9 @@ public class Child { isIndented: Bool = false, requiresLeadingNewline: Bool = false ) { + if let firstCharInName = name.first { + precondition(firstCharInName.isUppercase == true, "The first letter of a child’s name should be uppercase") + } self.name = name self.kind = kind self.nameForDiagnostics = nameForDiagnostics diff --git a/CodeGeneration/Sources/SyntaxSupport/ExprNodes.swift b/CodeGeneration/Sources/SyntaxSupport/ExprNodes.swift index c4a4ffd8af7..2f3ae245ae7 100644 --- a/CodeGeneration/Sources/SyntaxSupport/ExprNodes.swift +++ b/CodeGeneration/Sources/SyntaxSupport/ExprNodes.swift @@ -185,6 +185,60 @@ public let EXPR_NODES: [Node] = [ ] ), + // the canImport expr in if config expression + Node( + name: "CanImportExpr", + nameForDiagnostics: "'canImport' expression", + kind: "Expr", + children: [ + Child( + name: "CanImportKeyword", + kind: .token(choices: [.keyword(text: "canImport")]) + ), + Child( + name: "LeftParen", + kind: .token(choices: [.token(tokenKind: "LeftParenToken")]) + ), + Child( + name: "ImportPath", + kind: .token(choices: [.token(tokenKind: "IdentifierToken")]) + ), + Child( + name: "VersionInfo", + kind: .node(kind: "CanImportVersionInfo"), + isOptional: true + ), + Child( + name: "RightParen", + kind: .token(choices: [.token(tokenKind: "RightParenToken")]) + ), + ] + ), + + Node( + name: "CanImportVersionInfo", + nameForDiagnostics: nil, + kind: "Expr", + children: [ + Child( + name: "Comma", + kind: .token(choices: [.token(tokenKind: "CommaToken")]) + ), + Child( + name: "Label", + kind: .token(choices: [.keyword(text: "_version"), .keyword(text: "_underlyingVersion")]) + ), + Child( + name: "Colon", + kind: .token(choices: [.token(tokenKind: "ColonToken")]) + ), + Child( + name: "VersionTuple", + kind: .node(kind: "VersionTuple") + ), + ] + ), + // case-item -> pattern where-clause? ','? Node( name: "CaseItem", diff --git a/CodeGeneration/Sources/SyntaxSupport/KeywordSpec.swift b/CodeGeneration/Sources/SyntaxSupport/KeywordSpec.swift index 28a715a4a9f..5588d89608d 100644 --- a/CodeGeneration/Sources/SyntaxSupport/KeywordSpec.swift +++ b/CodeGeneration/Sources/SyntaxSupport/KeywordSpec.swift @@ -82,7 +82,9 @@ public let KEYWORDS: [KeywordSpec] = [ KeywordSpec("_TrivialAtMost"), KeywordSpec("_typeEraser"), KeywordSpec("_unavailableFromAsync"), + KeywordSpec("_underlyingVersion"), KeywordSpec("_UnknownLayout"), + KeywordSpec("_version"), KeywordSpec("actor"), KeywordSpec("addressWithNativeOwner"), KeywordSpec("addressWithOwner"), @@ -102,9 +104,11 @@ public let KEYWORDS: [KeywordSpec] = [ KeywordSpec("block"), KeywordSpec("borrowing"), KeywordSpec("break", isLexerClassified: true, requiresTrailingSpace: true), + KeywordSpec("canImport"), KeywordSpec("case", isLexerClassified: true, requiresTrailingSpace: true), KeywordSpec("catch", isLexerClassified: true, requiresLeadingSpace: true), KeywordSpec("class", isLexerClassified: true, requiresTrailingSpace: true), + KeywordSpec("compiler"), KeywordSpec("consume"), KeywordSpec("consuming"), KeywordSpec("continue", isLexerClassified: true, requiresTrailingSpace: true), diff --git a/Sources/SwiftParser/Availability.swift b/Sources/SwiftParser/Availability.swift index 003b96bf045..df49b20a05d 100644 --- a/Sources/SwiftParser/Availability.swift +++ b/Sources/SwiftParser/Availability.swift @@ -123,7 +123,7 @@ extension Parser { (.obsoleted, let handle)?: let argumentLabel = self.eat(handle) let (unexpectedBeforeColon, colon) = self.expect(.colon) - let version = self.parseVersionTuple() + let version = self.parseVersionTuple(maxComponentCount: 3) entry = .availabilityLabeledArgument( RawAvailabilityLabeledArgumentSyntax( label: argumentLabel, @@ -136,7 +136,7 @@ extension Parser { case (.deprecated, let handle)?: let argumentLabel = self.eat(handle) if let colon = self.consume(if: .colon) { - let version = self.parseVersionTuple() + let version = self.parseVersionTuple(maxComponentCount: 3) entry = .availabilityLabeledArgument( RawAvailabilityLabeledArgumentSyntax( label: argumentLabel, @@ -227,7 +227,7 @@ extension Parser { let version: RawVersionTupleSyntax? if self.at(.integerLiteral, .floatingLiteral) { - version = self.parseVersionTuple() + version = self.parseVersionTuple(maxComponentCount: 3) } else { version = nil } @@ -258,10 +258,10 @@ extension Parser { /// Grammar /// ======= /// - /// platform-version → decimal-digits - /// platform-version → decimal-digits '.' decimal-digits - /// platform-version → decimal-digits '.' decimal-digits '.' decimal-digits - mutating func parseVersionTuple() -> RawVersionTupleSyntax { + /// version-tuple -> integer-literal version-list? + /// version-list -> version-tuple-element version-list? + /// version-tuple-element -> '.' interger-literal + mutating func parseVersionTuple(maxComponentCount: Int) -> RawVersionTupleSyntax { if self.at(.floatingLiteral), let periodIndex = self.currentToken.tokenText.firstIndex(of: UInt8(ascii: ".")), self.currentToken.tokenText[0.. RawExprSyntax { - let head = self.parsePrimaryExpression(pattern: pattern, flavor: flavor) + let head = self.parsePrimaryExpression(pattern: pattern, forDirective: forDirective, flavor: flavor) guard !head.is(RawMissingExprSyntax.self) else { return head } @@ -1151,8 +1151,15 @@ extension Parser { @_spi(RawSyntax) public mutating func parsePrimaryExpression( pattern: PatternContext, + forDirective: Bool, flavor: ExprFlavor ) -> RawExprSyntax { + if forDirective == true, + let directiveExpr = self.parsePrimaryExprForDirective() + { + return RawExprSyntax(directiveExpr) + } + switch self.at(anyIn: PrimaryExpressionStart.self) { case (.integerLiteral, let handle)?: let digits = self.eat(handle) @@ -1316,6 +1323,18 @@ extension Parser { return RawExprSyntax(RawMissingExprSyntax(arena: self.arena)) } } + + // try to parse a primary expression for a directive + mutating func parsePrimaryExprForDirective() -> RawExprSyntax? { + switch self.at(anyIn: CompilationCondition.self) { + case (.canImportKeyword, let handle)?: + return RawExprSyntax(self.parseCanImportExpression(handle)) + + // TODO: add case `swift` and `compiler` here + default: + return nil + } + } } extension Parser { @@ -2569,6 +2588,44 @@ extension Parser { } } +// MARK: Platform Condition +extension Parser { + mutating func parseCanImportExpression(_ handle: TokenConsumptionHandle) -> RawExprSyntax { + let canImportKeyword = self.eat(handle) + + let (unexpectedBeforeLeftParen, leftParen) = self.expect(.leftParen) + + let (unexpectedBeforeImportPath, importPath) = self.expect(.identifier) + + var versionInfo: RawCanImportVersionInfoSyntax? + + if let comma = self.consume(if: .comma) { + let (unexpectedBeforeLabel, label) = self.expect(.keyword(._version), .keyword(._underlyingVersion), default: .keyword(._version)) + let (unexpectedBeforeColon, colon) = self.expect(.colon) + + let version = self.parseVersionTuple(maxComponentCount: 4) + + versionInfo = RawCanImportVersionInfoSyntax(comma: comma, unexpectedBeforeLabel, label: label, unexpectedBeforeColon, colon: colon, versionTuple: version, arena: self.arena) + } + + let (unexpectedBeforeRightParen, rightParen) = self.expect(.rightParen) + + return RawExprSyntax( + RawCanImportExprSyntax( + canImportKeyword: canImportKeyword, + unexpectedBeforeLeftParen, + leftParen: leftParen, + unexpectedBeforeImportPath, + importPath: importPath, + versionInfo: versionInfo, + unexpectedBeforeRightParen, + rightParen: rightParen, + arena: self.arena + ) + ) + } +} + // MARK: Lookahead extension Parser.Lookahead { diff --git a/Sources/SwiftParser/TokenSpecSet.swift b/Sources/SwiftParser/TokenSpecSet.swift index 9b5a1a136d9..ee13f34ac75 100644 --- a/Sources/SwiftParser/TokenSpecSet.swift +++ b/Sources/SwiftParser/TokenSpecSet.swift @@ -132,6 +132,30 @@ enum CanBeStatementStart: TokenSpecSet { } } +enum CompilationCondition: TokenSpecSet { + case swiftKeyword + case compilerKeyword + case canImportKeyword + + init?(lexeme: Lexer.Lexeme) { + switch PrepareForKeywordMatch(lexeme) { + case TokenSpec(.swift): self = .swiftKeyword + case TokenSpec(.compiler): self = .compilerKeyword + case TokenSpec(.canImport): self = .canImportKeyword + default: return nil + } + } + + var spec: TokenSpec { + switch self { + case .swiftKeyword: return .keyword(.swift) + case .compilerKeyword: return .keyword(.compiler) + case .canImportKeyword: return .keyword(.canImport) + } + } + +} + enum ContextualDeclKeyword: TokenSpecSet { case __consuming case _compilerInitialized diff --git a/Sources/SwiftParserDiagnostics/ParseDiagnosticsGenerator.swift b/Sources/SwiftParserDiagnostics/ParseDiagnosticsGenerator.swift index ac7c77833e2..d2082afd076 100644 --- a/Sources/SwiftParserDiagnostics/ParseDiagnosticsGenerator.swift +++ b/Sources/SwiftParserDiagnostics/ParseDiagnosticsGenerator.swift @@ -531,6 +531,50 @@ public class ParseDiagnosticsGenerator: SyntaxAnyVisitor { return .visitChildren } + public override func visit(_ node: CanImportExprSyntax) -> SyntaxVisitorContinueKind { + if shouldSkip(node) { + return .skipChildren + } + + if let versionTuple = node.versionInfo?.versionTuple, + let unexpectedVersionTuple = node.unexpectedBetweenVersionInfoAndRightParen + { + if versionTuple.major.presence == .missing { + addDiagnostic( + versionTuple, + CannotParseVersionTuple(versionTuple: unexpectedVersionTuple), + handledNodes: [versionTuple.id, unexpectedVersionTuple.id] + ) + } else { + addDiagnostic( + unexpectedVersionTuple, + .canImportWrongNumberOfParameter, + handledNodes: [unexpectedVersionTuple.id] + ) + } + } + + return .visitChildren + } + + public override func visit(_ node: CanImportVersionInfoSyntax) -> SyntaxVisitorContinueKind { + if shouldSkip(node) { + return .skipChildren + } + + if node.label.presence == .missing { + addDiagnostic( + node.label, + .canImportWrongSecondParameterLabel, + handledNodes: [node.label.id] + ) + + handledNodes.append(contentsOf: [node.unexpectedBetweenLabelAndColon?.id, node.colon.id, node.versionTuple.id].compactMap { $0 }) + } + + return .visitChildren + } + public override func visit(_ node: ConditionElementSyntax) -> SyntaxVisitorContinueKind { if shouldSkip(node) { return .skipChildren @@ -1495,6 +1539,24 @@ public class ParseDiagnosticsGenerator: SyntaxAnyVisitor { return .visitChildren } + public override func visit(_ node: VersionTupleSyntax) -> SyntaxVisitorContinueKind { + if shouldSkip(node) { + return .skipChildren + } + + if let trailingComponents = node.unexpectedAfterComponents, + let components = node.components + { + addDiagnostic( + trailingComponents, + TrailingVersionAreIgnored(major: node.major, components: components), + handledNodes: [trailingComponents.id] + ) + } + + return .visitChildren + } + public override func visit(_ node: WhileStmtSyntax) -> SyntaxVisitorContinueKind { if shouldSkip(node) { return .skipChildren diff --git a/Sources/SwiftParserDiagnostics/ParserDiagnosticMessages.swift b/Sources/SwiftParserDiagnostics/ParserDiagnosticMessages.swift index 584387359f7..5de101b58f0 100644 --- a/Sources/SwiftParserDiagnostics/ParserDiagnosticMessages.swift +++ b/Sources/SwiftParserDiagnostics/ParserDiagnosticMessages.swift @@ -92,6 +92,12 @@ extension DiagnosticMessage where Self == StaticParserError { public static var associatedTypeCannotUsePack: Self { .init("associated types cannot be variadic") } + public static var canImportWrongSecondParameterLabel: Self { + .init("2nd parameter of canImport should be labeled as _version or _underlyingVersion") + } + public static var canImportWrongNumberOfParameter: Self { + .init("canImport can take only two parameters") + } public static var caseOutsideOfSwitchOrEnum: Self { .init("'case' can only appear inside a 'switch' statement or 'enum' declaration") } @@ -269,6 +275,14 @@ public struct AvailabilityConditionInExpression: ParserError { } } +public struct CannotParseVersionTuple: ParserError { + public let versionTuple: UnexpectedNodesSyntax + + public var message: String { + return "cannot parse version \(versionTuple)" + } +} + public struct DuplicateEffectSpecifiers: ParserError { public let correctSpecifier: TokenSyntax public let unexpectedSpecifier: TokenSyntax @@ -435,6 +449,17 @@ public struct TokensNotAllowedInOperatorName: ParserError { } } +public struct TrailingVersionAreIgnored: ParserError { + public let major: TokenSyntax + public let components: VersionComponentListSyntax + + public var message: String { + return "trailing components of version \(major)\(components) are ignored" + } + + public var severity: DiagnosticSeverity = .warning +} + public struct TryCannotBeUsed: ParserError { public let nextToken: TokenSyntax diff --git a/Sources/SwiftParserDiagnostics/generated/SyntaxKindNameForDiagnostics.swift b/Sources/SwiftParserDiagnostics/generated/SyntaxKindNameForDiagnostics.swift index d0cee23cd41..888fef92959 100644 --- a/Sources/SwiftParserDiagnostics/generated/SyntaxKindNameForDiagnostics.swift +++ b/Sources/SwiftParserDiagnostics/generated/SyntaxKindNameForDiagnostics.swift @@ -69,6 +69,8 @@ extension SyntaxKind { return "'_borrow' expression" case .breakStmt: return "'break' statement" + case .canImportExpr: + return "'canImport' expression" case .catchClauseList: return "'catch' clause" case .catchClause: diff --git a/Sources/SwiftSyntax/Documentation.docc/generated/SwiftSyntax.md b/Sources/SwiftSyntax/Documentation.docc/generated/SwiftSyntax.md index 5a9987700bf..f4a6f34730d 100644 --- a/Sources/SwiftSyntax/Documentation.docc/generated/SwiftSyntax.md +++ b/Sources/SwiftSyntax/Documentation.docc/generated/SwiftSyntax.md @@ -93,6 +93,8 @@ allows Swift tools to parse, inspect, generate, and transform Swift source code. - - - +- +- - - - @@ -279,6 +281,8 @@ allows Swift tools to parse, inspect, generate, and transform Swift source code. - - - +- +- - - diff --git a/Sources/SwiftSyntax/generated/ChildNameForKeyPath.swift b/Sources/SwiftSyntax/generated/ChildNameForKeyPath.swift index a1b06fc3c51..a6809efbdd6 100644 --- a/Sources/SwiftSyntax/generated/ChildNameForKeyPath.swift +++ b/Sources/SwiftSyntax/generated/ChildNameForKeyPath.swift @@ -399,6 +399,46 @@ public func childName(_ keyPath: AnyKeyPath) -> String? { return "label" case \BreakStmtSyntax.unexpectedAfterLabel: return "unexpectedAfterLabel" + case \CanImportExprSyntax.unexpectedBeforeCanImportKeyword: + return "unexpectedBeforeCanImportKeyword" + case \CanImportExprSyntax.canImportKeyword: + return "canImportKeyword" + case \CanImportExprSyntax.unexpectedBetweenCanImportKeywordAndLeftParen: + return "unexpectedBetweenCanImportKeywordAndLeftParen" + case \CanImportExprSyntax.leftParen: + return "leftParen" + case \CanImportExprSyntax.unexpectedBetweenLeftParenAndImportPath: + return "unexpectedBetweenLeftParenAndImportPath" + case \CanImportExprSyntax.importPath: + return "importPath" + case \CanImportExprSyntax.unexpectedBetweenImportPathAndVersionInfo: + return "unexpectedBetweenImportPathAndVersionInfo" + case \CanImportExprSyntax.versionInfo: + return "versionInfo" + case \CanImportExprSyntax.unexpectedBetweenVersionInfoAndRightParen: + return "unexpectedBetweenVersionInfoAndRightParen" + case \CanImportExprSyntax.rightParen: + return "rightParen" + case \CanImportExprSyntax.unexpectedAfterRightParen: + return "unexpectedAfterRightParen" + case \CanImportVersionInfoSyntax.unexpectedBeforeComma: + return "unexpectedBeforeComma" + case \CanImportVersionInfoSyntax.comma: + return "comma" + case \CanImportVersionInfoSyntax.unexpectedBetweenCommaAndLabel: + return "unexpectedBetweenCommaAndLabel" + case \CanImportVersionInfoSyntax.label: + return "label" + case \CanImportVersionInfoSyntax.unexpectedBetweenLabelAndColon: + return "unexpectedBetweenLabelAndColon" + case \CanImportVersionInfoSyntax.colon: + return "colon" + case \CanImportVersionInfoSyntax.unexpectedBetweenColonAndVersionTuple: + return "unexpectedBetweenColonAndVersionTuple" + case \CanImportVersionInfoSyntax.versionTuple: + return "versionTuple" + case \CanImportVersionInfoSyntax.unexpectedAfterVersionTuple: + return "unexpectedAfterVersionTuple" case \CaseItemSyntax.unexpectedBeforePattern: return "unexpectedBeforePattern" case \CaseItemSyntax.pattern: @@ -3283,28 +3323,26 @@ public func childName(_ keyPath: AnyKeyPath) -> String? { return "bindings" case \VariableDeclSyntax.unexpectedAfterBindings: return "unexpectedAfterBindings" + case \VersionComponentSyntax.unexpectedBeforePeriod: + return "unexpectedBeforePeriod" + case \VersionComponentSyntax.period: + return "period" + case \VersionComponentSyntax.unexpectedBetweenPeriodAndNumber: + return "unexpectedBetweenPeriodAndNumber" + case \VersionComponentSyntax.number: + return "number" + case \VersionComponentSyntax.unexpectedAfterNumber: + return "unexpectedAfterNumber" case \VersionTupleSyntax.unexpectedBeforeMajor: return "unexpectedBeforeMajor" case \VersionTupleSyntax.major: return "major" - case \VersionTupleSyntax.unexpectedBetweenMajorAndMinorPeriod: - return "unexpectedBetweenMajorAndMinorPeriod" - case \VersionTupleSyntax.minorPeriod: - return "minorPeriod" - case \VersionTupleSyntax.unexpectedBetweenMinorPeriodAndMinor: - return "unexpectedBetweenMinorPeriodAndMinor" - case \VersionTupleSyntax.minor: - return "minor" - case \VersionTupleSyntax.unexpectedBetweenMinorAndPatchPeriod: - return "unexpectedBetweenMinorAndPatchPeriod" - case \VersionTupleSyntax.patchPeriod: - return "patchPeriod" - case \VersionTupleSyntax.unexpectedBetweenPatchPeriodAndPatch: - return "unexpectedBetweenPatchPeriodAndPatch" - case \VersionTupleSyntax.patch: - return "patch" - case \VersionTupleSyntax.unexpectedAfterPatch: - return "unexpectedAfterPatch" + case \VersionTupleSyntax.unexpectedBetweenMajorAndComponents: + return "unexpectedBetweenMajorAndComponents" + case \VersionTupleSyntax.components: + return "components" + case \VersionTupleSyntax.unexpectedAfterComponents: + return "unexpectedAfterComponents" case \WhereClauseSyntax.unexpectedBeforeWhereKeyword: return "unexpectedBeforeWhereKeyword" case \WhereClauseSyntax.whereKeyword: diff --git a/Sources/SwiftSyntax/generated/Keyword.swift b/Sources/SwiftSyntax/generated/Keyword.swift index 204db5b2936..e183e9ea12d 100644 --- a/Sources/SwiftSyntax/generated/Keyword.swift +++ b/Sources/SwiftSyntax/generated/Keyword.swift @@ -59,7 +59,9 @@ public enum Keyword: UInt8, Hashable { case _TrivialAtMost case _typeEraser case _unavailableFromAsync + case _underlyingVersion case _UnknownLayout + case _version case actor case addressWithNativeOwner case addressWithOwner @@ -79,9 +81,11 @@ public enum Keyword: UInt8, Hashable { case block case borrowing case `break` + case canImport case `case` case `catch` case `class` + case compiler case consume case consuming case `continue` @@ -464,6 +468,10 @@ public enum Keyword: UInt8, Hashable { self = ._private case "_Trivial": self = ._Trivial + case "_version": + self = ._version + case "compiler": + self = .compiler case "continue": self = .`continue` case "escaping": @@ -509,6 +517,8 @@ public enum Keyword: UInt8, Hashable { self = .available case "borrowing": self = .borrowing + case "canImport": + self = .canImport case "consuming": self = .consuming case "extension": @@ -660,6 +670,13 @@ public enum Keyword: UInt8, Hashable { default: return nil } + case 18: + switch text { + case "_underlyingVersion": + self = ._underlyingVersion + default: + return nil + } case 19: switch text { case "_dynamicReplacement": @@ -779,7 +796,9 @@ public enum Keyword: UInt8, Hashable { "_TrivialAtMost", "_typeEraser", "_unavailableFromAsync", + "_underlyingVersion", "_UnknownLayout", + "_version", "actor", "addressWithNativeOwner", "addressWithOwner", @@ -799,9 +818,11 @@ public enum Keyword: UInt8, Hashable { "block", "borrowing", "break", + "canImport", "case", "catch", "class", + "compiler", "consume", "consuming", "continue", diff --git a/Sources/SwiftSyntax/generated/SyntaxAnyVisitor.swift b/Sources/SwiftSyntax/generated/SyntaxAnyVisitor.swift index 783e957d60a..9b222546e5a 100644 --- a/Sources/SwiftSyntax/generated/SyntaxAnyVisitor.swift +++ b/Sources/SwiftSyntax/generated/SyntaxAnyVisitor.swift @@ -317,6 +317,22 @@ open class SyntaxAnyVisitor: SyntaxVisitor { visitAnyPost(node._syntaxNode) } + override open func visit(_ node: CanImportExprSyntax) -> SyntaxVisitorContinueKind { + return visitAny(node._syntaxNode) + } + + override open func visitPost(_ node: CanImportExprSyntax) { + visitAnyPost(node._syntaxNode) + } + + override open func visit(_ node: CanImportVersionInfoSyntax) -> SyntaxVisitorContinueKind { + return visitAny(node._syntaxNode) + } + + override open func visitPost(_ node: CanImportVersionInfoSyntax) { + visitAnyPost(node._syntaxNode) + } + override open func visit(_ node: CaseItemListSyntax) -> SyntaxVisitorContinueKind { return visitAny(node._syntaxNode) } @@ -2141,6 +2157,22 @@ open class SyntaxAnyVisitor: SyntaxVisitor { visitAnyPost(node._syntaxNode) } + override open func visit(_ node: VersionComponentListSyntax) -> SyntaxVisitorContinueKind { + return visitAny(node._syntaxNode) + } + + override open func visitPost(_ node: VersionComponentListSyntax) { + visitAnyPost(node._syntaxNode) + } + + override open func visit(_ node: VersionComponentSyntax) -> SyntaxVisitorContinueKind { + return visitAny(node._syntaxNode) + } + + override open func visitPost(_ node: VersionComponentSyntax) { + visitAnyPost(node._syntaxNode) + } + override open func visit(_ node: VersionTupleSyntax) -> SyntaxVisitorContinueKind { return visitAny(node._syntaxNode) } diff --git a/Sources/SwiftSyntax/generated/SyntaxBaseNodes.swift b/Sources/SwiftSyntax/generated/SyntaxBaseNodes.swift index d1b37a196fa..15949c2c8a6 100644 --- a/Sources/SwiftSyntax/generated/SyntaxBaseNodes.swift +++ b/Sources/SwiftSyntax/generated/SyntaxBaseNodes.swift @@ -206,7 +206,7 @@ public struct ExprSyntax: ExprSyntaxProtocol, SyntaxHashable { public init?(_ node: S) { switch node.raw.kind { - case .arrayExpr, .arrowExpr, .asExpr, .assignmentExpr, .awaitExpr, .binaryOperatorExpr, .booleanLiteralExpr, .borrowExpr, .closureExpr, .dictionaryExpr, .discardAssignmentExpr, .editorPlaceholderExpr, .floatLiteralExpr, .forcedValueExpr, .functionCallExpr, .identifierExpr, .ifExpr, .inOutExpr, .infixOperatorExpr, .integerLiteralExpr, .isExpr, .keyPathExpr, .macroExpansionExpr, .memberAccessExpr, .missingExpr, .moveExpr, .nilLiteralExpr, .optionalChainingExpr, .packElementExpr, .packExpansionExpr, .postfixIfConfigExpr, .postfixUnaryExpr, .prefixOperatorExpr, .regexLiteralExpr, .sequenceExpr, .specializeExpr, .stringLiteralExpr, .subscriptExpr, .superRefExpr, .switchExpr, .ternaryExpr, .tryExpr, .tupleExpr, .typeExpr, .unresolvedAsExpr, .unresolvedIsExpr, .unresolvedPatternExpr, .unresolvedTernaryExpr: + case .arrayExpr, .arrowExpr, .asExpr, .assignmentExpr, .awaitExpr, .binaryOperatorExpr, .booleanLiteralExpr, .borrowExpr, .canImportExpr, .canImportVersionInfo, .closureExpr, .dictionaryExpr, .discardAssignmentExpr, .editorPlaceholderExpr, .floatLiteralExpr, .forcedValueExpr, .functionCallExpr, .identifierExpr, .ifExpr, .inOutExpr, .infixOperatorExpr, .integerLiteralExpr, .isExpr, .keyPathExpr, .macroExpansionExpr, .memberAccessExpr, .missingExpr, .moveExpr, .nilLiteralExpr, .optionalChainingExpr, .packElementExpr, .packExpansionExpr, .postfixIfConfigExpr, .postfixUnaryExpr, .prefixOperatorExpr, .regexLiteralExpr, .sequenceExpr, .specializeExpr, .stringLiteralExpr, .subscriptExpr, .superRefExpr, .switchExpr, .ternaryExpr, .tryExpr, .tupleExpr, .typeExpr, .unresolvedAsExpr, .unresolvedIsExpr, .unresolvedPatternExpr, .unresolvedTernaryExpr: self._syntaxNode = node._syntaxNode default: return nil @@ -218,7 +218,7 @@ public struct ExprSyntax: ExprSyntaxProtocol, SyntaxHashable { /// is undefined. internal init(_ data: SyntaxData) { switch data.raw.kind { - case .arrayExpr, .arrowExpr, .asExpr, .assignmentExpr, .awaitExpr, .binaryOperatorExpr, .booleanLiteralExpr, .borrowExpr, .closureExpr, .dictionaryExpr, .discardAssignmentExpr, .editorPlaceholderExpr, .floatLiteralExpr, .forcedValueExpr, .functionCallExpr, .identifierExpr, .ifExpr, .inOutExpr, .infixOperatorExpr, .integerLiteralExpr, .isExpr, .keyPathExpr, .macroExpansionExpr, .memberAccessExpr, .missingExpr, .moveExpr, .nilLiteralExpr, .optionalChainingExpr, .packElementExpr, .packExpansionExpr, .postfixIfConfigExpr, .postfixUnaryExpr, .prefixOperatorExpr, .regexLiteralExpr, .sequenceExpr, .specializeExpr, .stringLiteralExpr, .subscriptExpr, .superRefExpr, .switchExpr, .ternaryExpr, .tryExpr, .tupleExpr, .typeExpr, .unresolvedAsExpr, .unresolvedIsExpr, .unresolvedPatternExpr, .unresolvedTernaryExpr: + case .arrayExpr, .arrowExpr, .asExpr, .assignmentExpr, .awaitExpr, .binaryOperatorExpr, .booleanLiteralExpr, .borrowExpr, .canImportExpr, .canImportVersionInfo, .closureExpr, .dictionaryExpr, .discardAssignmentExpr, .editorPlaceholderExpr, .floatLiteralExpr, .forcedValueExpr, .functionCallExpr, .identifierExpr, .ifExpr, .inOutExpr, .infixOperatorExpr, .integerLiteralExpr, .isExpr, .keyPathExpr, .macroExpansionExpr, .memberAccessExpr, .missingExpr, .moveExpr, .nilLiteralExpr, .optionalChainingExpr, .packElementExpr, .packExpansionExpr, .postfixIfConfigExpr, .postfixUnaryExpr, .prefixOperatorExpr, .regexLiteralExpr, .sequenceExpr, .specializeExpr, .stringLiteralExpr, .subscriptExpr, .superRefExpr, .switchExpr, .ternaryExpr, .tryExpr, .tupleExpr, .typeExpr, .unresolvedAsExpr, .unresolvedIsExpr, .unresolvedPatternExpr, .unresolvedTernaryExpr: break default: preconditionFailure("Unable to create ExprSyntax from \(data.raw.kind)") @@ -262,6 +262,8 @@ public struct ExprSyntax: ExprSyntaxProtocol, SyntaxHashable { .node(BinaryOperatorExprSyntax.self), .node(BooleanLiteralExprSyntax.self), .node(BorrowExprSyntax.self), + .node(CanImportExprSyntax.self), + .node(CanImportVersionInfoSyntax.self), .node(ClosureExprSyntax.self), .node(DictionaryExprSyntax.self), .node(DiscardAssignmentExprSyntax.self), @@ -717,6 +719,8 @@ extension Syntax { .node(BooleanLiteralExprSyntax.self), .node(BorrowExprSyntax.self), .node(BreakStmtSyntax.self), + .node(CanImportExprSyntax.self), + .node(CanImportVersionInfoSyntax.self), .node(CaseItemListSyntax.self), .node(CaseItemSyntax.self), .node(CatchClauseListSyntax.self), @@ -945,6 +949,8 @@ extension Syntax { .node(UnresolvedTernaryExprSyntax.self), .node(ValueBindingPatternSyntax.self), .node(VariableDeclSyntax.self), + .node(VersionComponentListSyntax.self), + .node(VersionComponentSyntax.self), .node(VersionTupleSyntax.self), .node(WhereClauseSyntax.self), .node(WhileStmtSyntax.self), diff --git a/Sources/SwiftSyntax/generated/SyntaxCollections.swift b/Sources/SwiftSyntax/generated/SyntaxCollections.swift index d6a41e4aecb..fc05283b014 100644 --- a/Sources/SwiftSyntax/generated/SyntaxCollections.swift +++ b/Sources/SwiftSyntax/generated/SyntaxCollections.swift @@ -9873,6 +9873,215 @@ extension UnexpectedNodesSyntax: BidirectionalCollection { } } +/// `VersionComponentListSyntax` represents a collection of one or more +/// `VersionComponent` nodes. VersionComponentListSyntax behaves +/// as a regular Swift collection, and has accessors that return new +/// versions of the collection with different children. +public struct VersionComponentListSyntax: SyntaxCollection, SyntaxHashable { + public typealias Element = VersionComponentSyntax + + public let _syntaxNode: Syntax + + private var layoutView: RawSyntaxLayoutView { + data.raw.layoutView! + } + + public init?(_ node: S) { + guard node.raw.kind == .versionComponentList else { + return nil + } + self._syntaxNode = node._syntaxNode + } + + /// Creates a Syntax node from the provided root and data. This assumes + /// that the `SyntaxData` is of the correct kind. If it is not, the behaviour + /// is undefined. + internal init(_ data: SyntaxData) { + precondition(data.raw.kind == .versionComponentList) + self._syntaxNode = Syntax(data) + } + + public init(_ children: [Element]) { + let data: SyntaxData = withExtendedLifetime(SyntaxArena()) { arena in + let raw = RawSyntax.makeLayout(kind: SyntaxKind.versionComponentList, + from: children.map { + $0.raw + }, arena: arena) + return SyntaxData.forRoot(raw) + } + self.init(data) + } + + /// The number of elements, `present` or `missing`, in this collection. + public var count: Int { + return layoutView.children.count + } + + /// Creates a new `VersionComponentListSyntax` by replacing the underlying layout with + /// a different set of raw syntax nodes. + /// + /// - Parameter layout: The new list of raw syntax nodes underlying this + /// collection. + /// - Returns: A new `VersionComponentListSyntax` with the new layout underlying it. + internal func replacingLayout(_ layout: [RawSyntax?]) -> VersionComponentListSyntax { + let arena = SyntaxArena() + let newRaw = layoutView.replacingLayout(with: layout, arena: arena) + let newData = data.replacingSelf(newRaw, arena: arena) + return VersionComponentListSyntax(newData) + } + + /// Creates a new `VersionComponentListSyntax` by appending the provided syntax element + /// to the children. + /// + /// - Parameter syntax: The element to append. + /// - Returns: A new `VersionComponentListSyntax` with that element appended to the end. + public func appending(_ syntax: Element) -> VersionComponentListSyntax { + var newLayout = layoutView.formLayoutArray() + newLayout.append(syntax.raw) + return replacingLayout(newLayout) + } + + /// Creates a new `VersionComponentListSyntax` by prepending the provided syntax element + /// to the children. + /// + /// - Parameter syntax: The element to prepend. + /// - Returns: A new `VersionComponentListSyntax` with that element prepended to the + /// beginning. + public func prepending(_ syntax: Element) -> VersionComponentListSyntax { + return inserting(syntax, at: 0) + } + + /// Creates a new `VersionComponentListSyntax` by inserting the provided syntax element + /// at the provided index in the children. + /// + /// - Parameters: + /// - syntax: The element to insert. + /// - index: The index at which to insert the element in the collection. + /// + /// - Returns: A new `VersionComponentListSyntax` with that element appended to the end. + public func inserting(_ syntax: Element, at index: Int) -> VersionComponentListSyntax { + var newLayout = layoutView.formLayoutArray() + /// Make sure the index is a valid insertion index (0 to 1 past the end) + precondition((newLayout.startIndex ... newLayout.endIndex).contains(index), + "inserting node at invalid index \(index)") + newLayout.insert(syntax.raw, at: index) + return replacingLayout(newLayout) + } + + /// Creates a new `VersionComponentListSyntax` by replacing the syntax element + /// at the provided index. + /// + /// - Parameters: + /// - index: The index at which to replace the element in the collection. + /// - syntax: The element to replace with. + /// + /// - Returns: A new `VersionComponentListSyntax` with the new element at the provided index. + public func replacing(childAt index: Int, with syntax: Element) -> VersionComponentListSyntax { + var newLayout = layoutView.formLayoutArray() + /// Make sure the index is a valid index for replacing + precondition((newLayout.startIndex ..< newLayout.endIndex).contains(index), + "replacing node at invalid index \(index)") + newLayout[index] = syntax.raw + return replacingLayout(newLayout) + } + + /// Creates a new `VersionComponentListSyntax` by removing the syntax element at the + /// provided index. + /// + /// - Parameter index: The index of the element to remove from the collection. + /// - Returns: A new `VersionComponentListSyntax` with the element at the provided index + /// removed. + public func removing(childAt index: Int) -> VersionComponentListSyntax { + var newLayout = layoutView.formLayoutArray() + newLayout.remove(at: index) + return replacingLayout(newLayout) + } + + /// Creates a new `VersionComponentListSyntax` by removing the first element. + /// + /// - Returns: A new `VersionComponentListSyntax` with the first element removed. + public func removingFirst() -> VersionComponentListSyntax { + var newLayout = layoutView.formLayoutArray() + newLayout.removeFirst() + return replacingLayout(newLayout) + } + + /// Creates a new `VersionComponentListSyntax` by removing the last element. + /// + /// - Returns: A new `VersionComponentListSyntax` with the last element removed. + public func removingLast() -> VersionComponentListSyntax { + var newLayout = layoutView.formLayoutArray() + newLayout.removeLast() + return replacingLayout(newLayout) + } +} + +/// Conformance for `VersionComponentListSyntax` to the `BidirectionalCollection` protocol. +extension VersionComponentListSyntax: BidirectionalCollection { + public typealias Index = SyntaxChildrenIndex + + public struct Iterator: IteratorProtocol { + private let parent: Syntax + + private var iterator: RawSyntaxChildren.Iterator + + + init(parent: Syntax, rawChildren: RawSyntaxChildren) { + self.parent = parent + self.iterator = rawChildren.makeIterator() + } + + + public mutating func next() -> Element? { + guard let (raw, info) = self.iterator.next() else { + return nil + } + let absoluteRaw = AbsoluteRawSyntax(raw: raw!, info: info) + let data = SyntaxData(absoluteRaw, parent: parent) + return Element(data) + } + } + + public func makeIterator() -> Iterator { + return Iterator(parent: Syntax(self), rawChildren: rawChildren) + } + + private var rawChildren: RawSyntaxChildren { + // We know children in a syntax collection cannot be missing. So we can + // use the low-level and faster RawSyntaxChildren collection instead of + // NonNilRawSyntaxChildren. + return RawSyntaxChildren(self.data.absoluteRaw) + } + + public var startIndex: SyntaxChildrenIndex { + return rawChildren.startIndex + } + + public var endIndex: SyntaxChildrenIndex { + return rawChildren.endIndex + } + + public func index(after index: SyntaxChildrenIndex) -> SyntaxChildrenIndex { + return rawChildren.index(after: index) + } + + public func index(before index: SyntaxChildrenIndex) -> SyntaxChildrenIndex { + return rawChildren.index(before: index) + } + + public func distance(from start: SyntaxChildrenIndex, to end: SyntaxChildrenIndex) + -> Int { + return rawChildren.distance(from: start, to: end) + } + + public subscript(position: SyntaxChildrenIndex) -> Element { + let (raw, info) = rawChildren[position] + let absoluteRaw = AbsoluteRawSyntax(raw: raw!, info: info) + let data = SyntaxData(absoluteRaw, parent: Syntax(self)) + return Element(data) + } +} + /// `YieldExprListSyntax` represents a collection of one or more /// `YieldExprListElement` nodes. YieldExprListSyntax behaves /// as a regular Swift collection, and has accessors that return new diff --git a/Sources/SwiftSyntax/generated/SyntaxEnum.swift b/Sources/SwiftSyntax/generated/SyntaxEnum.swift index 390943e141c..4bc04f1de8d 100644 --- a/Sources/SwiftSyntax/generated/SyntaxEnum.swift +++ b/Sources/SwiftSyntax/generated/SyntaxEnum.swift @@ -49,6 +49,8 @@ public enum SyntaxEnum { case booleanLiteralExpr(BooleanLiteralExprSyntax) case borrowExpr(BorrowExprSyntax) case breakStmt(BreakStmtSyntax) + case canImportExpr(CanImportExprSyntax) + case canImportVersionInfo(CanImportVersionInfoSyntax) case caseItemList(CaseItemListSyntax) case caseItem(CaseItemSyntax) case catchClauseList(CatchClauseListSyntax) @@ -277,6 +279,8 @@ public enum SyntaxEnum { case unresolvedTernaryExpr(UnresolvedTernaryExprSyntax) case valueBindingPattern(ValueBindingPatternSyntax) case variableDecl(VariableDeclSyntax) + case versionComponentList(VersionComponentListSyntax) + case versionComponent(VersionComponentSyntax) case versionTuple(VersionTupleSyntax) case whereClause(WhereClauseSyntax) case whileStmt(WhileStmtSyntax) @@ -359,6 +363,10 @@ public extension Syntax { return .borrowExpr(BorrowExprSyntax(self)!) case .breakStmt: return .breakStmt(BreakStmtSyntax(self)!) + case .canImportExpr: + return .canImportExpr(CanImportExprSyntax(self)!) + case .canImportVersionInfo: + return .canImportVersionInfo(CanImportVersionInfoSyntax(self)!) case .caseItemList: return .caseItemList(CaseItemListSyntax(self)!) case .caseItem: @@ -815,6 +823,10 @@ public extension Syntax { return .valueBindingPattern(ValueBindingPatternSyntax(self)!) case .variableDecl: return .variableDecl(VariableDeclSyntax(self)!) + case .versionComponentList: + return .versionComponentList(VersionComponentListSyntax(self)!) + case .versionComponent: + return .versionComponent(VersionComponentSyntax(self)!) case .versionTuple: return .versionTuple(VersionTupleSyntax(self)!) case .whereClause: diff --git a/Sources/SwiftSyntax/generated/SyntaxKind.swift b/Sources/SwiftSyntax/generated/SyntaxKind.swift index aa199255f7b..4911a9880a2 100644 --- a/Sources/SwiftSyntax/generated/SyntaxKind.swift +++ b/Sources/SwiftSyntax/generated/SyntaxKind.swift @@ -49,6 +49,8 @@ public enum SyntaxKind { case booleanLiteralExpr case borrowExpr case breakStmt + case canImportExpr + case canImportVersionInfo case caseItemList case caseItem case catchClauseList @@ -277,6 +279,8 @@ public enum SyntaxKind { case unresolvedTernaryExpr case valueBindingPattern case variableDecl + case versionComponentList + case versionComponent case versionTuple case whereClause case whileStmt @@ -380,6 +384,8 @@ public enum SyntaxKind { return true case .unexpectedNodes: return true + case .versionComponentList: + return true case .yieldExprList: return true default: @@ -474,6 +480,10 @@ public enum SyntaxKind { return BorrowExprSyntax.self case .breakStmt: return BreakStmtSyntax.self + case .canImportExpr: + return CanImportExprSyntax.self + case .canImportVersionInfo: + return CanImportVersionInfoSyntax.self case .caseItemList: return CaseItemListSyntax.self case .caseItem: @@ -930,6 +940,10 @@ public enum SyntaxKind { return ValueBindingPatternSyntax.self case .variableDecl: return VariableDeclSyntax.self + case .versionComponentList: + return VersionComponentListSyntax.self + case .versionComponent: + return VersionComponentSyntax.self case .versionTuple: return VersionTupleSyntax.self case .whereClause: diff --git a/Sources/SwiftSyntax/generated/SyntaxRewriter.swift b/Sources/SwiftSyntax/generated/SyntaxRewriter.swift index 047d4e84ed7..2645218b392 100644 --- a/Sources/SwiftSyntax/generated/SyntaxRewriter.swift +++ b/Sources/SwiftSyntax/generated/SyntaxRewriter.swift @@ -256,6 +256,20 @@ open class SyntaxRewriter { return StmtSyntax(visitChildren(node)) } + /// Visit a `CanImportExprSyntax`. + /// - Parameter node: the node that is being visited + /// - Returns: the rewritten node + open func visit(_ node: CanImportExprSyntax) -> ExprSyntax { + return ExprSyntax(visitChildren(node)) + } + + /// Visit a `CanImportVersionInfoSyntax`. + /// - Parameter node: the node that is being visited + /// - Returns: the rewritten node + open func visit(_ node: CanImportVersionInfoSyntax) -> ExprSyntax { + return ExprSyntax(visitChildren(node)) + } + /// Visit a `CaseItemListSyntax`. /// - Parameter node: the node that is being visited /// - Returns: the rewritten node @@ -1852,6 +1866,20 @@ open class SyntaxRewriter { return DeclSyntax(visitChildren(node)) } + /// Visit a `VersionComponentListSyntax`. + /// - Parameter node: the node that is being visited + /// - Returns: the rewritten node + open func visit(_ node: VersionComponentListSyntax) -> VersionComponentListSyntax { + return Syntax(visitChildren(node)).cast(VersionComponentListSyntax.self) + } + + /// Visit a `VersionComponentSyntax`. + /// - Parameter node: the node that is being visited + /// - Returns: the rewritten node + open func visit(_ node: VersionComponentSyntax) -> VersionComponentSyntax { + return Syntax(visitChildren(node)).cast(VersionComponentSyntax.self) + } + /// Visit a `VersionTupleSyntax`. /// - Parameter node: the node that is being visited /// - Returns: the rewritten node @@ -2444,6 +2472,34 @@ open class SyntaxRewriter { return Syntax(visit(node)) } + /// Implementation detail of visit(_:). Do not call directly. + private func visitImplCanImportExprSyntax(_ data: SyntaxData) -> Syntax { + let node = CanImportExprSyntax(data) + // Accessing _syntaxNode directly is faster than calling Syntax(node) + visitPre(node._syntaxNode) + defer { + visitPost(node._syntaxNode) + } + if let newNode = visitAny(node._syntaxNode) { + return newNode + } + return Syntax(visit(node)) + } + + /// Implementation detail of visit(_:). Do not call directly. + private func visitImplCanImportVersionInfoSyntax(_ data: SyntaxData) -> Syntax { + let node = CanImportVersionInfoSyntax(data) + // Accessing _syntaxNode directly is faster than calling Syntax(node) + visitPre(node._syntaxNode) + defer { + visitPost(node._syntaxNode) + } + if let newNode = visitAny(node._syntaxNode) { + return newNode + } + return Syntax(visit(node)) + } + /// Implementation detail of visit(_:). Do not call directly. private func visitImplCaseItemListSyntax(_ data: SyntaxData) -> Syntax { let node = CaseItemListSyntax(data) @@ -5636,6 +5692,34 @@ open class SyntaxRewriter { return Syntax(visit(node)) } + /// Implementation detail of visit(_:). Do not call directly. + private func visitImplVersionComponentListSyntax(_ data: SyntaxData) -> Syntax { + let node = VersionComponentListSyntax(data) + // Accessing _syntaxNode directly is faster than calling Syntax(node) + visitPre(node._syntaxNode) + defer { + visitPost(node._syntaxNode) + } + if let newNode = visitAny(node._syntaxNode) { + return newNode + } + return Syntax(visit(node)) + } + + /// Implementation detail of visit(_:). Do not call directly. + private func visitImplVersionComponentSyntax(_ data: SyntaxData) -> Syntax { + let node = VersionComponentSyntax(data) + // Accessing _syntaxNode directly is faster than calling Syntax(node) + visitPre(node._syntaxNode) + defer { + visitPost(node._syntaxNode) + } + if let newNode = visitAny(node._syntaxNode) { + return newNode + } + return Syntax(visit(node)) + } + /// Implementation detail of visit(_:). Do not call directly. private func visitImplVersionTupleSyntax(_ data: SyntaxData) -> Syntax { let node = VersionTupleSyntax(data) @@ -5856,6 +5940,10 @@ open class SyntaxRewriter { return visitImplBorrowExprSyntax case .breakStmt: return visitImplBreakStmtSyntax + case .canImportExpr: + return visitImplCanImportExprSyntax + case .canImportVersionInfo: + return visitImplCanImportVersionInfoSyntax case .caseItemList: return visitImplCaseItemListSyntax case .caseItem: @@ -6312,6 +6400,10 @@ open class SyntaxRewriter { return visitImplValueBindingPatternSyntax case .variableDecl: return visitImplVariableDeclSyntax + case .versionComponentList: + return visitImplVersionComponentListSyntax + case .versionComponent: + return visitImplVersionComponentSyntax case .versionTuple: return visitImplVersionTupleSyntax case .whereClause: @@ -6404,6 +6496,10 @@ open class SyntaxRewriter { return visitImplBorrowExprSyntax(data) case .breakStmt: return visitImplBreakStmtSyntax(data) + case .canImportExpr: + return visitImplCanImportExprSyntax(data) + case .canImportVersionInfo: + return visitImplCanImportVersionInfoSyntax(data) case .caseItemList: return visitImplCaseItemListSyntax(data) case .caseItem: @@ -6860,6 +6956,10 @@ open class SyntaxRewriter { return visitImplValueBindingPatternSyntax(data) case .variableDecl: return visitImplVariableDeclSyntax(data) + case .versionComponentList: + return visitImplVersionComponentListSyntax(data) + case .versionComponent: + return visitImplVersionComponentSyntax(data) case .versionTuple: return visitImplVersionTupleSyntax(data) case .whereClause: diff --git a/Sources/SwiftSyntax/generated/SyntaxTransform.swift b/Sources/SwiftSyntax/generated/SyntaxTransform.swift index cbbeb096f34..e8f9379cf06 100644 --- a/Sources/SwiftSyntax/generated/SyntaxTransform.swift +++ b/Sources/SwiftSyntax/generated/SyntaxTransform.swift @@ -184,6 +184,16 @@ public protocol SyntaxTransformVisitor { /// - Returns: the sum of whatever the child visitors return. func visit(_ node: BreakStmtSyntax) -> ResultType + /// Visiting `CanImportExprSyntax` specifically. + /// - Parameter node: the node we are visiting. + /// - Returns: the sum of whatever the child visitors return. + func visit(_ node: CanImportExprSyntax) -> ResultType + + /// Visiting `CanImportVersionInfoSyntax` specifically. + /// - Parameter node: the node we are visiting. + /// - Returns: the sum of whatever the child visitors return. + func visit(_ node: CanImportVersionInfoSyntax) -> ResultType + /// Visiting `CaseItemListSyntax` specifically. /// - Parameter node: the node we are visiting. /// - Returns: the sum of whatever the child visitors return. @@ -1324,6 +1334,16 @@ public protocol SyntaxTransformVisitor { /// - Returns: the sum of whatever the child visitors return. func visit(_ node: VariableDeclSyntax) -> ResultType + /// Visiting `VersionComponentListSyntax` specifically. + /// - Parameter node: the node we are visiting. + /// - Returns: the sum of whatever the child visitors return. + func visit(_ node: VersionComponentListSyntax) -> ResultType + + /// Visiting `VersionComponentSyntax` specifically. + /// - Parameter node: the node we are visiting. + /// - Returns: the sum of whatever the child visitors return. + func visit(_ node: VersionComponentSyntax) -> ResultType + /// Visiting `VersionTupleSyntax` specifically. /// - Parameter node: the node we are visiting. /// - Returns: the sum of whatever the child visitors return. @@ -1601,6 +1621,20 @@ extension SyntaxTransformVisitor { visitAny(Syntax(node)) } + /// Visiting `CanImportExprSyntax` specifically. + /// - Parameter node: the node we are visiting. + /// - Returns: nil by default. + public func visit(_ node: CanImportExprSyntax) -> ResultType { + visitAny(Syntax(node)) + } + + /// Visiting `CanImportVersionInfoSyntax` specifically. + /// - Parameter node: the node we are visiting. + /// - Returns: nil by default. + public func visit(_ node: CanImportVersionInfoSyntax) -> ResultType { + visitAny(Syntax(node)) + } + /// Visiting `CaseItemListSyntax` specifically. /// - Parameter node: the node we are visiting. /// - Returns: nil by default. @@ -3197,6 +3231,20 @@ extension SyntaxTransformVisitor { visitAny(Syntax(node)) } + /// Visiting `VersionComponentListSyntax` specifically. + /// - Parameter node: the node we are visiting. + /// - Returns: nil by default. + public func visit(_ node: VersionComponentListSyntax) -> ResultType { + visitAny(Syntax(node)) + } + + /// Visiting `VersionComponentSyntax` specifically. + /// - Parameter node: the node we are visiting. + /// - Returns: nil by default. + public func visit(_ node: VersionComponentSyntax) -> ResultType { + visitAny(Syntax(node)) + } + /// Visiting `VersionTupleSyntax` specifically. /// - Parameter node: the node we are visiting. /// - Returns: nil by default. @@ -3323,6 +3371,10 @@ extension SyntaxTransformVisitor { return visit(derived) case .breakStmt(let derived): return visit(derived) + case .canImportExpr(let derived): + return visit(derived) + case .canImportVersionInfo(let derived): + return visit(derived) case .caseItemList(let derived): return visit(derived) case .caseItem(let derived): @@ -3779,6 +3831,10 @@ extension SyntaxTransformVisitor { return visit(derived) case .variableDecl(let derived): return visit(derived) + case .versionComponentList(let derived): + return visit(derived) + case .versionComponent(let derived): + return visit(derived) case .versionTuple(let derived): return visit(derived) case .whereClause(let derived): diff --git a/Sources/SwiftSyntax/generated/SyntaxVisitor.swift b/Sources/SwiftSyntax/generated/SyntaxVisitor.swift index b7124bbd68e..1f20eee1f93 100644 --- a/Sources/SwiftSyntax/generated/SyntaxVisitor.swift +++ b/Sources/SwiftSyntax/generated/SyntaxVisitor.swift @@ -430,6 +430,30 @@ open class SyntaxVisitor { open func visitPost(_ node: BreakStmtSyntax) { } + /// Visiting `CanImportExprSyntax` specifically. + /// - Parameter node: the node we are visiting. + /// - Returns: how should we continue visiting. + open func visit(_ node: CanImportExprSyntax) -> SyntaxVisitorContinueKind { + return .visitChildren + } + + /// The function called after visiting `CanImportExprSyntax` and its descendents. + /// - node: the node we just finished visiting. + open func visitPost(_ node: CanImportExprSyntax) { + } + + /// Visiting `CanImportVersionInfoSyntax` specifically. + /// - Parameter node: the node we are visiting. + /// - Returns: how should we continue visiting. + open func visit(_ node: CanImportVersionInfoSyntax) -> SyntaxVisitorContinueKind { + return .visitChildren + } + + /// The function called after visiting `CanImportVersionInfoSyntax` and its descendents. + /// - node: the node we just finished visiting. + open func visitPost(_ node: CanImportVersionInfoSyntax) { + } + /// Visiting `CaseItemListSyntax` specifically. /// - Parameter node: the node we are visiting. /// - Returns: how should we continue visiting. @@ -3166,6 +3190,30 @@ open class SyntaxVisitor { open func visitPost(_ node: VariableDeclSyntax) { } + /// Visiting `VersionComponentListSyntax` specifically. + /// - Parameter node: the node we are visiting. + /// - Returns: how should we continue visiting. + open func visit(_ node: VersionComponentListSyntax) -> SyntaxVisitorContinueKind { + return .visitChildren + } + + /// The function called after visiting `VersionComponentListSyntax` and its descendents. + /// - node: the node we just finished visiting. + open func visitPost(_ node: VersionComponentListSyntax) { + } + + /// Visiting `VersionComponentSyntax` specifically. + /// - Parameter node: the node we are visiting. + /// - Returns: how should we continue visiting. + open func visit(_ node: VersionComponentSyntax) -> SyntaxVisitorContinueKind { + return .visitChildren + } + + /// The function called after visiting `VersionComponentSyntax` and its descendents. + /// - node: the node we just finished visiting. + open func visitPost(_ node: VersionComponentSyntax) { + } + /// Visiting `VersionTupleSyntax` specifically. /// - Parameter node: the node we are visiting. /// - Returns: how should we continue visiting. @@ -3637,6 +3685,28 @@ open class SyntaxVisitor { visitPost(node) } + /// Implementation detail of doVisit(_:_:). Do not call directly. + private func visitImplCanImportExprSyntax(_ data: SyntaxData) { + let node = CanImportExprSyntax(data) + let needsChildren = (visit(node) == .visitChildren) + // Avoid calling into visitChildren if possible. + if needsChildren && !node.raw.layoutView!.children.isEmpty { + visitChildren(node) + } + visitPost(node) + } + + /// Implementation detail of doVisit(_:_:). Do not call directly. + private func visitImplCanImportVersionInfoSyntax(_ data: SyntaxData) { + let node = CanImportVersionInfoSyntax(data) + let needsChildren = (visit(node) == .visitChildren) + // Avoid calling into visitChildren if possible. + if needsChildren && !node.raw.layoutView!.children.isEmpty { + visitChildren(node) + } + visitPost(node) + } + /// Implementation detail of doVisit(_:_:). Do not call directly. private func visitImplCaseItemListSyntax(_ data: SyntaxData) { let node = CaseItemListSyntax(data) @@ -6145,6 +6215,28 @@ open class SyntaxVisitor { visitPost(node) } + /// Implementation detail of doVisit(_:_:). Do not call directly. + private func visitImplVersionComponentListSyntax(_ data: SyntaxData) { + let node = VersionComponentListSyntax(data) + let needsChildren = (visit(node) == .visitChildren) + // Avoid calling into visitChildren if possible. + if needsChildren && !node.raw.layoutView!.children.isEmpty { + visitChildren(node) + } + visitPost(node) + } + + /// Implementation detail of doVisit(_:_:). Do not call directly. + private func visitImplVersionComponentSyntax(_ data: SyntaxData) { + let node = VersionComponentSyntax(data) + let needsChildren = (visit(node) == .visitChildren) + // Avoid calling into visitChildren if possible. + if needsChildren && !node.raw.layoutView!.children.isEmpty { + visitChildren(node) + } + visitPost(node) + } + /// Implementation detail of doVisit(_:_:). Do not call directly. private func visitImplVersionTupleSyntax(_ data: SyntaxData) { let node = VersionTupleSyntax(data) @@ -6306,6 +6398,10 @@ open class SyntaxVisitor { visitImplBorrowExprSyntax(data) case .breakStmt: visitImplBreakStmtSyntax(data) + case .canImportExpr: + visitImplCanImportExprSyntax(data) + case .canImportVersionInfo: + visitImplCanImportVersionInfoSyntax(data) case .caseItemList: visitImplCaseItemListSyntax(data) case .caseItem: @@ -6762,6 +6858,10 @@ open class SyntaxVisitor { visitImplValueBindingPatternSyntax(data) case .variableDecl: visitImplVariableDeclSyntax(data) + case .versionComponentList: + visitImplVersionComponentListSyntax(data) + case .versionComponent: + visitImplVersionComponentSyntax(data) case .versionTuple: visitImplVersionTupleSyntax(data) case .whereClause: diff --git a/Sources/SwiftSyntax/generated/raw/RawSyntaxNodes.swift b/Sources/SwiftSyntax/generated/raw/RawSyntaxNodes.swift index c421bdb1f97..5dfe3f52d76 100644 --- a/Sources/SwiftSyntax/generated/raw/RawSyntaxNodes.swift +++ b/Sources/SwiftSyntax/generated/raw/RawSyntaxNodes.swift @@ -2810,6 +2810,206 @@ public struct RawBreakStmtSyntax: RawStmtSyntaxNodeProtocol { } } +@_spi(RawSyntax) +public struct RawCanImportExprSyntax: RawExprSyntaxNodeProtocol { + @_spi(RawSyntax) + public var layoutView: RawSyntaxLayoutView { + return raw.layoutView! + } + + public static func isKindOf(_ raw: RawSyntax) -> Bool { + return raw.kind == .canImportExpr + } + + public var raw: RawSyntax + + init(raw: RawSyntax) { + precondition(Self.isKindOf(raw)) + self.raw = raw + } + + private init(unchecked raw: RawSyntax) { + self.raw = raw + } + + public init?(_ other: Node) { + guard Self.isKindOf(other.raw) else { + return nil + } + self.init(unchecked: other.raw) + } + + public init( + _ unexpectedBeforeCanImportKeyword: RawUnexpectedNodesSyntax? = nil, + canImportKeyword: RawTokenSyntax, + _ unexpectedBetweenCanImportKeywordAndLeftParen: RawUnexpectedNodesSyntax? = nil, + leftParen: RawTokenSyntax, + _ unexpectedBetweenLeftParenAndImportPath: RawUnexpectedNodesSyntax? = nil, + importPath: RawTokenSyntax, + _ unexpectedBetweenImportPathAndVersionInfo: RawUnexpectedNodesSyntax? = nil, + versionInfo: RawCanImportVersionInfoSyntax?, + _ unexpectedBetweenVersionInfoAndRightParen: RawUnexpectedNodesSyntax? = nil, + rightParen: RawTokenSyntax, + _ unexpectedAfterRightParen: RawUnexpectedNodesSyntax? = nil, + arena: __shared SyntaxArena + ) { + let raw = RawSyntax.makeLayout( + kind: .canImportExpr, uninitializedCount: 11, arena: arena) { layout in + layout.initialize(repeating: nil) + layout[0] = unexpectedBeforeCanImportKeyword?.raw + layout[1] = canImportKeyword.raw + layout[2] = unexpectedBetweenCanImportKeywordAndLeftParen?.raw + layout[3] = leftParen.raw + layout[4] = unexpectedBetweenLeftParenAndImportPath?.raw + layout[5] = importPath.raw + layout[6] = unexpectedBetweenImportPathAndVersionInfo?.raw + layout[7] = versionInfo?.raw + layout[8] = unexpectedBetweenVersionInfoAndRightParen?.raw + layout[9] = rightParen.raw + layout[10] = unexpectedAfterRightParen?.raw + } + self.init(unchecked: raw) + } + + public var unexpectedBeforeCanImportKeyword: RawUnexpectedNodesSyntax? { + layoutView.children[0].map(RawUnexpectedNodesSyntax.init(raw:)) + } + + public var canImportKeyword: RawTokenSyntax { + layoutView.children[1].map(RawTokenSyntax.init(raw:))! + } + + public var unexpectedBetweenCanImportKeywordAndLeftParen: RawUnexpectedNodesSyntax? { + layoutView.children[2].map(RawUnexpectedNodesSyntax.init(raw:)) + } + + public var leftParen: RawTokenSyntax { + layoutView.children[3].map(RawTokenSyntax.init(raw:))! + } + + public var unexpectedBetweenLeftParenAndImportPath: RawUnexpectedNodesSyntax? { + layoutView.children[4].map(RawUnexpectedNodesSyntax.init(raw:)) + } + + public var importPath: RawTokenSyntax { + layoutView.children[5].map(RawTokenSyntax.init(raw:))! + } + + public var unexpectedBetweenImportPathAndVersionInfo: RawUnexpectedNodesSyntax? { + layoutView.children[6].map(RawUnexpectedNodesSyntax.init(raw:)) + } + + public var versionInfo: RawCanImportVersionInfoSyntax? { + layoutView.children[7].map(RawCanImportVersionInfoSyntax.init(raw:)) + } + + public var unexpectedBetweenVersionInfoAndRightParen: RawUnexpectedNodesSyntax? { + layoutView.children[8].map(RawUnexpectedNodesSyntax.init(raw:)) + } + + public var rightParen: RawTokenSyntax { + layoutView.children[9].map(RawTokenSyntax.init(raw:))! + } + + public var unexpectedAfterRightParen: RawUnexpectedNodesSyntax? { + layoutView.children[10].map(RawUnexpectedNodesSyntax.init(raw:)) + } +} + +@_spi(RawSyntax) +public struct RawCanImportVersionInfoSyntax: RawExprSyntaxNodeProtocol { + @_spi(RawSyntax) + public var layoutView: RawSyntaxLayoutView { + return raw.layoutView! + } + + public static func isKindOf(_ raw: RawSyntax) -> Bool { + return raw.kind == .canImportVersionInfo + } + + public var raw: RawSyntax + + init(raw: RawSyntax) { + precondition(Self.isKindOf(raw)) + self.raw = raw + } + + private init(unchecked raw: RawSyntax) { + self.raw = raw + } + + public init?(_ other: Node) { + guard Self.isKindOf(other.raw) else { + return nil + } + self.init(unchecked: other.raw) + } + + public init( + _ unexpectedBeforeComma: RawUnexpectedNodesSyntax? = nil, + comma: RawTokenSyntax, + _ unexpectedBetweenCommaAndLabel: RawUnexpectedNodesSyntax? = nil, + label: RawTokenSyntax, + _ unexpectedBetweenLabelAndColon: RawUnexpectedNodesSyntax? = nil, + colon: RawTokenSyntax, + _ unexpectedBetweenColonAndVersionTuple: RawUnexpectedNodesSyntax? = nil, + versionTuple: RawVersionTupleSyntax, + _ unexpectedAfterVersionTuple: RawUnexpectedNodesSyntax? = nil, + arena: __shared SyntaxArena + ) { + let raw = RawSyntax.makeLayout( + kind: .canImportVersionInfo, uninitializedCount: 9, arena: arena) { layout in + layout.initialize(repeating: nil) + layout[0] = unexpectedBeforeComma?.raw + layout[1] = comma.raw + layout[2] = unexpectedBetweenCommaAndLabel?.raw + layout[3] = label.raw + layout[4] = unexpectedBetweenLabelAndColon?.raw + layout[5] = colon.raw + layout[6] = unexpectedBetweenColonAndVersionTuple?.raw + layout[7] = versionTuple.raw + layout[8] = unexpectedAfterVersionTuple?.raw + } + self.init(unchecked: raw) + } + + public var unexpectedBeforeComma: RawUnexpectedNodesSyntax? { + layoutView.children[0].map(RawUnexpectedNodesSyntax.init(raw:)) + } + + public var comma: RawTokenSyntax { + layoutView.children[1].map(RawTokenSyntax.init(raw:))! + } + + public var unexpectedBetweenCommaAndLabel: RawUnexpectedNodesSyntax? { + layoutView.children[2].map(RawUnexpectedNodesSyntax.init(raw:)) + } + + public var label: RawTokenSyntax { + layoutView.children[3].map(RawTokenSyntax.init(raw:))! + } + + public var unexpectedBetweenLabelAndColon: RawUnexpectedNodesSyntax? { + layoutView.children[4].map(RawUnexpectedNodesSyntax.init(raw:)) + } + + public var colon: RawTokenSyntax { + layoutView.children[5].map(RawTokenSyntax.init(raw:))! + } + + public var unexpectedBetweenColonAndVersionTuple: RawUnexpectedNodesSyntax? { + layoutView.children[6].map(RawUnexpectedNodesSyntax.init(raw:)) + } + + public var versionTuple: RawVersionTupleSyntax { + layoutView.children[7].map(RawVersionTupleSyntax.init(raw:))! + } + + public var unexpectedAfterVersionTuple: RawUnexpectedNodesSyntax? { + layoutView.children[8].map(RawUnexpectedNodesSyntax.init(raw:)) + } +} + @_spi(RawSyntax) public struct RawCaseItemListSyntax: RawSyntaxNodeProtocol { @_spi(RawSyntax) @@ -8375,7 +8575,7 @@ public struct RawExprSyntax: RawExprSyntaxNodeProtocol { public static func isKindOf(_ raw: RawSyntax) -> Bool { switch raw.kind { - case .arrayExpr, .arrowExpr, .asExpr, .assignmentExpr, .awaitExpr, .binaryOperatorExpr, .booleanLiteralExpr, .borrowExpr, .closureExpr, .dictionaryExpr, .discardAssignmentExpr, .editorPlaceholderExpr, .floatLiteralExpr, .forcedValueExpr, .functionCallExpr, .identifierExpr, .ifExpr, .inOutExpr, .infixOperatorExpr, .integerLiteralExpr, .isExpr, .keyPathExpr, .macroExpansionExpr, .memberAccessExpr, .missingExpr, .moveExpr, .nilLiteralExpr, .optionalChainingExpr, .packElementExpr, .packExpansionExpr, .postfixIfConfigExpr, .postfixUnaryExpr, .prefixOperatorExpr, .regexLiteralExpr, .sequenceExpr, .specializeExpr, .stringLiteralExpr, .subscriptExpr, .superRefExpr, .switchExpr, .ternaryExpr, .tryExpr, .tupleExpr, .typeExpr, .unresolvedAsExpr, .unresolvedIsExpr, .unresolvedPatternExpr, .unresolvedTernaryExpr: + case .arrayExpr, .arrowExpr, .asExpr, .assignmentExpr, .awaitExpr, .binaryOperatorExpr, .booleanLiteralExpr, .borrowExpr, .canImportExpr, .canImportVersionInfo, .closureExpr, .dictionaryExpr, .discardAssignmentExpr, .editorPlaceholderExpr, .floatLiteralExpr, .forcedValueExpr, .functionCallExpr, .identifierExpr, .ifExpr, .inOutExpr, .infixOperatorExpr, .integerLiteralExpr, .isExpr, .keyPathExpr, .macroExpansionExpr, .memberAccessExpr, .missingExpr, .moveExpr, .nilLiteralExpr, .optionalChainingExpr, .packElementExpr, .packExpansionExpr, .postfixIfConfigExpr, .postfixUnaryExpr, .prefixOperatorExpr, .regexLiteralExpr, .sequenceExpr, .specializeExpr, .stringLiteralExpr, .subscriptExpr, .superRefExpr, .switchExpr, .ternaryExpr, .tryExpr, .tupleExpr, .typeExpr, .unresolvedAsExpr, .unresolvedIsExpr, .unresolvedPatternExpr, .unresolvedTernaryExpr: return true default: return false @@ -21782,14 +21982,64 @@ public struct RawVariableDeclSyntax: RawDeclSyntaxNodeProtocol { } @_spi(RawSyntax) -public struct RawVersionTupleSyntax: RawSyntaxNodeProtocol { +public struct RawVersionComponentListSyntax: RawSyntaxNodeProtocol { @_spi(RawSyntax) public var layoutView: RawSyntaxLayoutView { return raw.layoutView! } public static func isKindOf(_ raw: RawSyntax) -> Bool { - return raw.kind == .versionTuple + return raw.kind == .versionComponentList + } + + public var raw: RawSyntax + + init(raw: RawSyntax) { + precondition(Self.isKindOf(raw)) + self.raw = raw + } + + private init(unchecked raw: RawSyntax) { + self.raw = raw + } + + public init?(_ other: Node) { + guard Self.isKindOf(other.raw) else { + return nil + } + self.init(unchecked: other.raw) + } + + public init(elements: [RawVersionComponentSyntax], arena: __shared SyntaxArena) { + let raw = RawSyntax.makeLayout( + kind: .versionComponentList, uninitializedCount: elements.count, arena: arena) { layout in + guard var ptr = layout.baseAddress else { + return + } + for elem in elements { + ptr.initialize(to: elem.raw) + ptr += 1 + } + } + self.init(unchecked: raw) + } + + public var elements: [RawVersionComponentSyntax] { + layoutView.children.map { + RawVersionComponentSyntax(raw: $0!) + } + } +} + +@_spi(RawSyntax) +public struct RawVersionComponentSyntax: RawSyntaxNodeProtocol { + @_spi(RawSyntax) + public var layoutView: RawSyntaxLayoutView { + return raw.layoutView! + } + + public static func isKindOf(_ raw: RawSyntax) -> Bool { + return raw.kind == .versionComponent } public var raw: RawSyntax @@ -21811,79 +22061,113 @@ public struct RawVersionTupleSyntax: RawSyntaxNodeProtocol { } public init( - _ unexpectedBeforeMajor: RawUnexpectedNodesSyntax? = nil, - major: RawTokenSyntax, - _ unexpectedBetweenMajorAndMinorPeriod: RawUnexpectedNodesSyntax? = nil, - minorPeriod: RawTokenSyntax?, - _ unexpectedBetweenMinorPeriodAndMinor: RawUnexpectedNodesSyntax? = nil, - minor: RawTokenSyntax?, - _ unexpectedBetweenMinorAndPatchPeriod: RawUnexpectedNodesSyntax? = nil, - patchPeriod: RawTokenSyntax?, - _ unexpectedBetweenPatchPeriodAndPatch: RawUnexpectedNodesSyntax? = nil, - patch: RawTokenSyntax?, - _ unexpectedAfterPatch: RawUnexpectedNodesSyntax? = nil, + _ unexpectedBeforePeriod: RawUnexpectedNodesSyntax? = nil, + period: RawTokenSyntax, + _ unexpectedBetweenPeriodAndNumber: RawUnexpectedNodesSyntax? = nil, + number: RawTokenSyntax, + _ unexpectedAfterNumber: RawUnexpectedNodesSyntax? = nil, arena: __shared SyntaxArena ) { let raw = RawSyntax.makeLayout( - kind: .versionTuple, uninitializedCount: 11, arena: arena) { layout in + kind: .versionComponent, uninitializedCount: 5, arena: arena) { layout in layout.initialize(repeating: nil) - layout[0] = unexpectedBeforeMajor?.raw - layout[1] = major.raw - layout[2] = unexpectedBetweenMajorAndMinorPeriod?.raw - layout[3] = minorPeriod?.raw - layout[4] = unexpectedBetweenMinorPeriodAndMinor?.raw - layout[5] = minor?.raw - layout[6] = unexpectedBetweenMinorAndPatchPeriod?.raw - layout[7] = patchPeriod?.raw - layout[8] = unexpectedBetweenPatchPeriodAndPatch?.raw - layout[9] = patch?.raw - layout[10] = unexpectedAfterPatch?.raw + layout[0] = unexpectedBeforePeriod?.raw + layout[1] = period.raw + layout[2] = unexpectedBetweenPeriodAndNumber?.raw + layout[3] = number.raw + layout[4] = unexpectedAfterNumber?.raw } self.init(unchecked: raw) } - public var unexpectedBeforeMajor: RawUnexpectedNodesSyntax? { + public var unexpectedBeforePeriod: RawUnexpectedNodesSyntax? { layoutView.children[0].map(RawUnexpectedNodesSyntax.init(raw:)) } - public var major: RawTokenSyntax { + public var period: RawTokenSyntax { layoutView.children[1].map(RawTokenSyntax.init(raw:))! } - public var unexpectedBetweenMajorAndMinorPeriod: RawUnexpectedNodesSyntax? { + public var unexpectedBetweenPeriodAndNumber: RawUnexpectedNodesSyntax? { layoutView.children[2].map(RawUnexpectedNodesSyntax.init(raw:)) } - public var minorPeriod: RawTokenSyntax? { - layoutView.children[3].map(RawTokenSyntax.init(raw:)) + public var number: RawTokenSyntax { + layoutView.children[3].map(RawTokenSyntax.init(raw:))! } - public var unexpectedBetweenMinorPeriodAndMinor: RawUnexpectedNodesSyntax? { + public var unexpectedAfterNumber: RawUnexpectedNodesSyntax? { layoutView.children[4].map(RawUnexpectedNodesSyntax.init(raw:)) } +} + +@_spi(RawSyntax) +public struct RawVersionTupleSyntax: RawSyntaxNodeProtocol { + @_spi(RawSyntax) + public var layoutView: RawSyntaxLayoutView { + return raw.layoutView! + } - public var minor: RawTokenSyntax? { - layoutView.children[5].map(RawTokenSyntax.init(raw:)) + public static func isKindOf(_ raw: RawSyntax) -> Bool { + return raw.kind == .versionTuple } - public var unexpectedBetweenMinorAndPatchPeriod: RawUnexpectedNodesSyntax? { - layoutView.children[6].map(RawUnexpectedNodesSyntax.init(raw:)) + public var raw: RawSyntax + + init(raw: RawSyntax) { + precondition(Self.isKindOf(raw)) + self.raw = raw } - public var patchPeriod: RawTokenSyntax? { - layoutView.children[7].map(RawTokenSyntax.init(raw:)) + private init(unchecked raw: RawSyntax) { + self.raw = raw } - public var unexpectedBetweenPatchPeriodAndPatch: RawUnexpectedNodesSyntax? { - layoutView.children[8].map(RawUnexpectedNodesSyntax.init(raw:)) + public init?(_ other: Node) { + guard Self.isKindOf(other.raw) else { + return nil + } + self.init(unchecked: other.raw) } - public var patch: RawTokenSyntax? { - layoutView.children[9].map(RawTokenSyntax.init(raw:)) + public init( + _ unexpectedBeforeMajor: RawUnexpectedNodesSyntax? = nil, + major: RawTokenSyntax, + _ unexpectedBetweenMajorAndComponents: RawUnexpectedNodesSyntax? = nil, + components: RawVersionComponentListSyntax?, + _ unexpectedAfterComponents: RawUnexpectedNodesSyntax? = nil, + arena: __shared SyntaxArena + ) { + let raw = RawSyntax.makeLayout( + kind: .versionTuple, uninitializedCount: 5, arena: arena) { layout in + layout.initialize(repeating: nil) + layout[0] = unexpectedBeforeMajor?.raw + layout[1] = major.raw + layout[2] = unexpectedBetweenMajorAndComponents?.raw + layout[3] = components?.raw + layout[4] = unexpectedAfterComponents?.raw + } + self.init(unchecked: raw) } - public var unexpectedAfterPatch: RawUnexpectedNodesSyntax? { - layoutView.children[10].map(RawUnexpectedNodesSyntax.init(raw:)) + public var unexpectedBeforeMajor: RawUnexpectedNodesSyntax? { + layoutView.children[0].map(RawUnexpectedNodesSyntax.init(raw:)) + } + + public var major: RawTokenSyntax { + layoutView.children[1].map(RawTokenSyntax.init(raw:))! + } + + public var unexpectedBetweenMajorAndComponents: RawUnexpectedNodesSyntax? { + layoutView.children[2].map(RawUnexpectedNodesSyntax.init(raw:)) + } + + public var components: RawVersionComponentListSyntax? { + layoutView.children[3].map(RawVersionComponentListSyntax.init(raw:)) + } + + public var unexpectedAfterComponents: RawUnexpectedNodesSyntax? { + layoutView.children[4].map(RawUnexpectedNodesSyntax.init(raw:)) } } diff --git a/Sources/SwiftSyntax/generated/raw/RawSyntaxValidation.swift b/Sources/SwiftSyntax/generated/raw/RawSyntaxValidation.swift index 073bce7fa02..6e31e0aa5e3 100644 --- a/Sources/SwiftSyntax/generated/raw/RawSyntaxValidation.swift +++ b/Sources/SwiftSyntax/generated/raw/RawSyntaxValidation.swift @@ -511,6 +511,30 @@ func validateLayout(layout: RawSyntaxBuffer, as kind: SyntaxKind) { assertNoError(kind, 2, verify(layout[2], as: RawUnexpectedNodesSyntax?.self)) assertNoError(kind, 3, verify(layout[3], as: RawTokenSyntax?.self, tokenChoices: [.tokenKind(.identifier)])) assertNoError(kind, 4, verify(layout[4], as: RawUnexpectedNodesSyntax?.self)) + case .canImportExpr: + assert(layout.count == 11) + assertNoError(kind, 0, verify(layout[0], as: RawUnexpectedNodesSyntax?.self)) + assertNoError(kind, 1, verify(layout[1], as: RawTokenSyntax.self, tokenChoices: [.keyword("canImport")])) + assertNoError(kind, 2, verify(layout[2], as: RawUnexpectedNodesSyntax?.self)) + assertNoError(kind, 3, verify(layout[3], as: RawTokenSyntax.self, tokenChoices: [.tokenKind(.leftParen)])) + assertNoError(kind, 4, verify(layout[4], as: RawUnexpectedNodesSyntax?.self)) + assertNoError(kind, 5, verify(layout[5], as: RawTokenSyntax.self, tokenChoices: [.tokenKind(.identifier)])) + assertNoError(kind, 6, verify(layout[6], as: RawUnexpectedNodesSyntax?.self)) + assertNoError(kind, 7, verify(layout[7], as: RawCanImportVersionInfoSyntax?.self)) + assertNoError(kind, 8, verify(layout[8], as: RawUnexpectedNodesSyntax?.self)) + assertNoError(kind, 9, verify(layout[9], as: RawTokenSyntax.self, tokenChoices: [.tokenKind(.rightParen)])) + assertNoError(kind, 10, verify(layout[10], as: RawUnexpectedNodesSyntax?.self)) + case .canImportVersionInfo: + assert(layout.count == 9) + assertNoError(kind, 0, verify(layout[0], as: RawUnexpectedNodesSyntax?.self)) + assertNoError(kind, 1, verify(layout[1], as: RawTokenSyntax.self, tokenChoices: [.tokenKind(.comma)])) + assertNoError(kind, 2, verify(layout[2], as: RawUnexpectedNodesSyntax?.self)) + assertNoError(kind, 3, verify(layout[3], as: RawTokenSyntax.self, tokenChoices: [.keyword("_version"), .keyword("_underlyingVersion")])) + assertNoError(kind, 4, verify(layout[4], as: RawUnexpectedNodesSyntax?.self)) + assertNoError(kind, 5, verify(layout[5], as: RawTokenSyntax.self, tokenChoices: [.tokenKind(.colon)])) + assertNoError(kind, 6, verify(layout[6], as: RawUnexpectedNodesSyntax?.self)) + assertNoError(kind, 7, verify(layout[7], as: RawVersionTupleSyntax.self)) + assertNoError(kind, 8, verify(layout[8], as: RawUnexpectedNodesSyntax?.self)) case .caseItemList: for (index, element) in layout.enumerated() { assertNoError(kind, index, verify(element, as: RawCaseItemSyntax.self)) @@ -2608,19 +2632,24 @@ func validateLayout(layout: RawSyntaxBuffer, as kind: SyntaxKind) { assertNoError(kind, 6, verify(layout[6], as: RawUnexpectedNodesSyntax?.self)) assertNoError(kind, 7, verify(layout[7], as: RawPatternBindingListSyntax.self)) assertNoError(kind, 8, verify(layout[8], as: RawUnexpectedNodesSyntax?.self)) + case .versionComponentList: + for (index, element) in layout.enumerated() { + assertNoError(kind, index, verify(element, as: RawVersionComponentSyntax.self)) + } + case .versionComponent: + assert(layout.count == 5) + assertNoError(kind, 0, verify(layout[0], as: RawUnexpectedNodesSyntax?.self)) + assertNoError(kind, 1, verify(layout[1], as: RawTokenSyntax.self, tokenChoices: [.tokenKind(.period)])) + assertNoError(kind, 2, verify(layout[2], as: RawUnexpectedNodesSyntax?.self)) + assertNoError(kind, 3, verify(layout[3], as: RawTokenSyntax.self, tokenChoices: [.tokenKind(.integerLiteral)])) + assertNoError(kind, 4, verify(layout[4], as: RawUnexpectedNodesSyntax?.self)) case .versionTuple: - assert(layout.count == 11) + assert(layout.count == 5) assertNoError(kind, 0, verify(layout[0], as: RawUnexpectedNodesSyntax?.self)) assertNoError(kind, 1, verify(layout[1], as: RawTokenSyntax.self, tokenChoices: [.tokenKind(.integerLiteral)])) assertNoError(kind, 2, verify(layout[2], as: RawUnexpectedNodesSyntax?.self)) - assertNoError(kind, 3, verify(layout[3], as: RawTokenSyntax?.self, tokenChoices: [.tokenKind(.period)])) + assertNoError(kind, 3, verify(layout[3], as: RawVersionComponentListSyntax?.self)) assertNoError(kind, 4, verify(layout[4], as: RawUnexpectedNodesSyntax?.self)) - assertNoError(kind, 5, verify(layout[5], as: RawTokenSyntax?.self, tokenChoices: [.tokenKind(.integerLiteral)])) - assertNoError(kind, 6, verify(layout[6], as: RawUnexpectedNodesSyntax?.self)) - assertNoError(kind, 7, verify(layout[7], as: RawTokenSyntax?.self, tokenChoices: [.tokenKind(.period)])) - assertNoError(kind, 8, verify(layout[8], as: RawUnexpectedNodesSyntax?.self)) - assertNoError(kind, 9, verify(layout[9], as: RawTokenSyntax?.self, tokenChoices: [.tokenKind(.integerLiteral)])) - assertNoError(kind, 10, verify(layout[10], as: RawUnexpectedNodesSyntax?.self)) case .whereClause: assert(layout.count == 5) assertNoError(kind, 0, verify(layout[0], as: RawUnexpectedNodesSyntax?.self)) diff --git a/Sources/SwiftSyntax/generated/syntaxNodes/SyntaxExprNodes.swift b/Sources/SwiftSyntax/generated/syntaxNodes/SyntaxExprNodes.swift index 66bf0b84c6a..cbaede0e76a 100644 --- a/Sources/SwiftSyntax/generated/syntaxNodes/SyntaxExprNodes.swift +++ b/Sources/SwiftSyntax/generated/syntaxNodes/SyntaxExprNodes.swift @@ -923,6 +923,368 @@ public struct BorrowExprSyntax: ExprSyntaxProtocol, SyntaxHashable { } } +// MARK: - CanImportExprSyntax + + +public struct CanImportExprSyntax: ExprSyntaxProtocol, SyntaxHashable { + public let _syntaxNode: Syntax + + public init?(_ node: S) { + guard node.raw.kind == .canImportExpr else { + return nil + } + self._syntaxNode = node._syntaxNode + } + + /// Creates a `CanImportExprSyntax` node from the given `SyntaxData`. This assumes + /// that the `SyntaxData` is of the correct kind. If it is not, the behaviour + /// is undefined. + internal init(_ data: SyntaxData) { + precondition(data.raw.kind == .canImportExpr) + self._syntaxNode = Syntax(data) + } + + public init( + leadingTrivia: Trivia? = nil, + _ unexpectedBeforeCanImportKeyword: UnexpectedNodesSyntax? = nil, + canImportKeyword: TokenSyntax = .keyword(.canImport), + _ unexpectedBetweenCanImportKeywordAndLeftParen: UnexpectedNodesSyntax? = nil, + leftParen: TokenSyntax = .leftParenToken(), + _ unexpectedBetweenLeftParenAndImportPath: UnexpectedNodesSyntax? = nil, + importPath: TokenSyntax, + _ unexpectedBetweenImportPathAndVersionInfo: UnexpectedNodesSyntax? = nil, + versionInfo: CanImportVersionInfoSyntax? = nil, + _ unexpectedBetweenVersionInfoAndRightParen: UnexpectedNodesSyntax? = nil, + rightParen: TokenSyntax = .rightParenToken(), + _ unexpectedAfterRightParen: UnexpectedNodesSyntax? = nil, + trailingTrivia: Trivia? = nil + + ) { + // Extend the lifetime of all parameters so their arenas don't get destroyed + // before they can be added as children of the new arena. + let data: SyntaxData = withExtendedLifetime((SyntaxArena(), ( + unexpectedBeforeCanImportKeyword, + canImportKeyword, + unexpectedBetweenCanImportKeywordAndLeftParen, + leftParen, + unexpectedBetweenLeftParenAndImportPath, + importPath, + unexpectedBetweenImportPathAndVersionInfo, + versionInfo, + unexpectedBetweenVersionInfoAndRightParen, + rightParen, + unexpectedAfterRightParen + ))) {(arena, _) in + let layout: [RawSyntax?] = [ + unexpectedBeforeCanImportKeyword?.raw, + canImportKeyword.raw, + unexpectedBetweenCanImportKeywordAndLeftParen?.raw, + leftParen.raw, + unexpectedBetweenLeftParenAndImportPath?.raw, + importPath.raw, + unexpectedBetweenImportPathAndVersionInfo?.raw, + versionInfo?.raw, + unexpectedBetweenVersionInfoAndRightParen?.raw, + rightParen.raw, + unexpectedAfterRightParen?.raw + ] + let raw = RawSyntax.makeLayout( + kind: SyntaxKind.canImportExpr, + from: layout, + arena: arena, + leadingTrivia: leadingTrivia, + trailingTrivia: trailingTrivia + + ) + return SyntaxData.forRoot(raw) + } + self.init(data) + } + + public var unexpectedBeforeCanImportKeyword: UnexpectedNodesSyntax? { + get { + return data.child(at: 0, parent: Syntax(self)).map(UnexpectedNodesSyntax.init) + } + set(value) { + self = CanImportExprSyntax(data.replacingChild(at: 0, with: value?.raw, arena: SyntaxArena())) + } + } + + public var canImportKeyword: TokenSyntax { + get { + return TokenSyntax(data.child(at: 1, parent: Syntax(self))!) + } + set(value) { + self = CanImportExprSyntax(data.replacingChild(at: 1, with: value.raw, arena: SyntaxArena())) + } + } + + public var unexpectedBetweenCanImportKeywordAndLeftParen: UnexpectedNodesSyntax? { + get { + return data.child(at: 2, parent: Syntax(self)).map(UnexpectedNodesSyntax.init) + } + set(value) { + self = CanImportExprSyntax(data.replacingChild(at: 2, with: value?.raw, arena: SyntaxArena())) + } + } + + public var leftParen: TokenSyntax { + get { + return TokenSyntax(data.child(at: 3, parent: Syntax(self))!) + } + set(value) { + self = CanImportExprSyntax(data.replacingChild(at: 3, with: value.raw, arena: SyntaxArena())) + } + } + + public var unexpectedBetweenLeftParenAndImportPath: UnexpectedNodesSyntax? { + get { + return data.child(at: 4, parent: Syntax(self)).map(UnexpectedNodesSyntax.init) + } + set(value) { + self = CanImportExprSyntax(data.replacingChild(at: 4, with: value?.raw, arena: SyntaxArena())) + } + } + + public var importPath: TokenSyntax { + get { + return TokenSyntax(data.child(at: 5, parent: Syntax(self))!) + } + set(value) { + self = CanImportExprSyntax(data.replacingChild(at: 5, with: value.raw, arena: SyntaxArena())) + } + } + + public var unexpectedBetweenImportPathAndVersionInfo: UnexpectedNodesSyntax? { + get { + return data.child(at: 6, parent: Syntax(self)).map(UnexpectedNodesSyntax.init) + } + set(value) { + self = CanImportExprSyntax(data.replacingChild(at: 6, with: value?.raw, arena: SyntaxArena())) + } + } + + public var versionInfo: CanImportVersionInfoSyntax? { + get { + return data.child(at: 7, parent: Syntax(self)).map(CanImportVersionInfoSyntax.init) + } + set(value) { + self = CanImportExprSyntax(data.replacingChild(at: 7, with: value?.raw, arena: SyntaxArena())) + } + } + + public var unexpectedBetweenVersionInfoAndRightParen: UnexpectedNodesSyntax? { + get { + return data.child(at: 8, parent: Syntax(self)).map(UnexpectedNodesSyntax.init) + } + set(value) { + self = CanImportExprSyntax(data.replacingChild(at: 8, with: value?.raw, arena: SyntaxArena())) + } + } + + public var rightParen: TokenSyntax { + get { + return TokenSyntax(data.child(at: 9, parent: Syntax(self))!) + } + set(value) { + self = CanImportExprSyntax(data.replacingChild(at: 9, with: value.raw, arena: SyntaxArena())) + } + } + + public var unexpectedAfterRightParen: UnexpectedNodesSyntax? { + get { + return data.child(at: 10, parent: Syntax(self)).map(UnexpectedNodesSyntax.init) + } + set(value) { + self = CanImportExprSyntax(data.replacingChild(at: 10, with: value?.raw, arena: SyntaxArena())) + } + } + + public static var structure: SyntaxNodeStructure { + return .layout([ + \Self.unexpectedBeforeCanImportKeyword, + \Self.canImportKeyword, + \Self.unexpectedBetweenCanImportKeywordAndLeftParen, + \Self.leftParen, + \Self.unexpectedBetweenLeftParenAndImportPath, + \Self.importPath, + \Self.unexpectedBetweenImportPathAndVersionInfo, + \Self.versionInfo, + \Self.unexpectedBetweenVersionInfoAndRightParen, + \Self.rightParen, + \Self.unexpectedAfterRightParen + ]) + } +} + +// MARK: - CanImportVersionInfoSyntax + + +public struct CanImportVersionInfoSyntax: ExprSyntaxProtocol, SyntaxHashable { + public let _syntaxNode: Syntax + + public init?(_ node: S) { + guard node.raw.kind == .canImportVersionInfo else { + return nil + } + self._syntaxNode = node._syntaxNode + } + + /// Creates a `CanImportVersionInfoSyntax` node from the given `SyntaxData`. This assumes + /// that the `SyntaxData` is of the correct kind. If it is not, the behaviour + /// is undefined. + internal init(_ data: SyntaxData) { + precondition(data.raw.kind == .canImportVersionInfo) + self._syntaxNode = Syntax(data) + } + + public init( + leadingTrivia: Trivia? = nil, + _ unexpectedBeforeComma: UnexpectedNodesSyntax? = nil, + comma: TokenSyntax = .commaToken(), + _ unexpectedBetweenCommaAndLabel: UnexpectedNodesSyntax? = nil, + label: TokenSyntax, + _ unexpectedBetweenLabelAndColon: UnexpectedNodesSyntax? = nil, + colon: TokenSyntax = .colonToken(), + _ unexpectedBetweenColonAndVersionTuple: UnexpectedNodesSyntax? = nil, + versionTuple: VersionTupleSyntax, + _ unexpectedAfterVersionTuple: UnexpectedNodesSyntax? = nil, + trailingTrivia: Trivia? = nil + + ) { + // Extend the lifetime of all parameters so their arenas don't get destroyed + // before they can be added as children of the new arena. + let data: SyntaxData = withExtendedLifetime((SyntaxArena(), ( + unexpectedBeforeComma, + comma, + unexpectedBetweenCommaAndLabel, + label, + unexpectedBetweenLabelAndColon, + colon, + unexpectedBetweenColonAndVersionTuple, + versionTuple, + unexpectedAfterVersionTuple + ))) {(arena, _) in + let layout: [RawSyntax?] = [ + unexpectedBeforeComma?.raw, + comma.raw, + unexpectedBetweenCommaAndLabel?.raw, + label.raw, + unexpectedBetweenLabelAndColon?.raw, + colon.raw, + unexpectedBetweenColonAndVersionTuple?.raw, + versionTuple.raw, + unexpectedAfterVersionTuple?.raw + ] + let raw = RawSyntax.makeLayout( + kind: SyntaxKind.canImportVersionInfo, + from: layout, + arena: arena, + leadingTrivia: leadingTrivia, + trailingTrivia: trailingTrivia + + ) + return SyntaxData.forRoot(raw) + } + self.init(data) + } + + public var unexpectedBeforeComma: UnexpectedNodesSyntax? { + get { + return data.child(at: 0, parent: Syntax(self)).map(UnexpectedNodesSyntax.init) + } + set(value) { + self = CanImportVersionInfoSyntax(data.replacingChild(at: 0, with: value?.raw, arena: SyntaxArena())) + } + } + + public var comma: TokenSyntax { + get { + return TokenSyntax(data.child(at: 1, parent: Syntax(self))!) + } + set(value) { + self = CanImportVersionInfoSyntax(data.replacingChild(at: 1, with: value.raw, arena: SyntaxArena())) + } + } + + public var unexpectedBetweenCommaAndLabel: UnexpectedNodesSyntax? { + get { + return data.child(at: 2, parent: Syntax(self)).map(UnexpectedNodesSyntax.init) + } + set(value) { + self = CanImportVersionInfoSyntax(data.replacingChild(at: 2, with: value?.raw, arena: SyntaxArena())) + } + } + + public var label: TokenSyntax { + get { + return TokenSyntax(data.child(at: 3, parent: Syntax(self))!) + } + set(value) { + self = CanImportVersionInfoSyntax(data.replacingChild(at: 3, with: value.raw, arena: SyntaxArena())) + } + } + + public var unexpectedBetweenLabelAndColon: UnexpectedNodesSyntax? { + get { + return data.child(at: 4, parent: Syntax(self)).map(UnexpectedNodesSyntax.init) + } + set(value) { + self = CanImportVersionInfoSyntax(data.replacingChild(at: 4, with: value?.raw, arena: SyntaxArena())) + } + } + + public var colon: TokenSyntax { + get { + return TokenSyntax(data.child(at: 5, parent: Syntax(self))!) + } + set(value) { + self = CanImportVersionInfoSyntax(data.replacingChild(at: 5, with: value.raw, arena: SyntaxArena())) + } + } + + public var unexpectedBetweenColonAndVersionTuple: UnexpectedNodesSyntax? { + get { + return data.child(at: 6, parent: Syntax(self)).map(UnexpectedNodesSyntax.init) + } + set(value) { + self = CanImportVersionInfoSyntax(data.replacingChild(at: 6, with: value?.raw, arena: SyntaxArena())) + } + } + + public var versionTuple: VersionTupleSyntax { + get { + return VersionTupleSyntax(data.child(at: 7, parent: Syntax(self))!) + } + set(value) { + self = CanImportVersionInfoSyntax(data.replacingChild(at: 7, with: value.raw, arena: SyntaxArena())) + } + } + + public var unexpectedAfterVersionTuple: UnexpectedNodesSyntax? { + get { + return data.child(at: 8, parent: Syntax(self)).map(UnexpectedNodesSyntax.init) + } + set(value) { + self = CanImportVersionInfoSyntax(data.replacingChild(at: 8, with: value?.raw, arena: SyntaxArena())) + } + } + + public static var structure: SyntaxNodeStructure { + return .layout([ + \Self.unexpectedBeforeComma, + \Self.comma, + \Self.unexpectedBetweenCommaAndLabel, + \Self.label, + \Self.unexpectedBetweenLabelAndColon, + \Self.colon, + \Self.unexpectedBetweenColonAndVersionTuple, + \Self.versionTuple, + \Self.unexpectedAfterVersionTuple + ]) + } +} + // MARK: - ClosureExprSyntax diff --git a/Sources/SwiftSyntax/generated/syntaxNodes/SyntaxNodes.swift b/Sources/SwiftSyntax/generated/syntaxNodes/SyntaxNodes.swift index 7f553d5830a..416626c14a9 100644 --- a/Sources/SwiftSyntax/generated/syntaxNodes/SyntaxNodes.swift +++ b/Sources/SwiftSyntax/generated/syntaxNodes/SyntaxNodes.swift @@ -17432,73 +17432,55 @@ public struct UnderscorePrivateAttributeArgumentsSyntax: SyntaxProtocol, SyntaxH } } -// MARK: - VersionTupleSyntax +// MARK: - VersionComponentSyntax -/// A version number of the form major.minor.patch in which the minor and patch part may be omitted. -public struct VersionTupleSyntax: SyntaxProtocol, SyntaxHashable { +/// An element to represent a single component in a version, like `.1`. +public struct VersionComponentSyntax: SyntaxProtocol, SyntaxHashable { public let _syntaxNode: Syntax public init?(_ node: S) { - guard node.raw.kind == .versionTuple else { + guard node.raw.kind == .versionComponent else { return nil } self._syntaxNode = node._syntaxNode } - /// Creates a `VersionTupleSyntax` node from the given `SyntaxData`. This assumes + /// Creates a `VersionComponentSyntax` node from the given `SyntaxData`. This assumes /// that the `SyntaxData` is of the correct kind. If it is not, the behaviour /// is undefined. internal init(_ data: SyntaxData) { - precondition(data.raw.kind == .versionTuple) + precondition(data.raw.kind == .versionComponent) self._syntaxNode = Syntax(data) } public init( leadingTrivia: Trivia? = nil, - _ unexpectedBeforeMajor: UnexpectedNodesSyntax? = nil, - major: TokenSyntax, - _ unexpectedBetweenMajorAndMinorPeriod: UnexpectedNodesSyntax? = nil, - minorPeriod: TokenSyntax? = nil, - _ unexpectedBetweenMinorPeriodAndMinor: UnexpectedNodesSyntax? = nil, - minor: TokenSyntax? = nil, - _ unexpectedBetweenMinorAndPatchPeriod: UnexpectedNodesSyntax? = nil, - patchPeriod: TokenSyntax? = nil, - _ unexpectedBetweenPatchPeriodAndPatch: UnexpectedNodesSyntax? = nil, - patch: TokenSyntax? = nil, - _ unexpectedAfterPatch: UnexpectedNodesSyntax? = nil, + _ unexpectedBeforePeriod: UnexpectedNodesSyntax? = nil, + period: TokenSyntax = .periodToken(), + _ unexpectedBetweenPeriodAndNumber: UnexpectedNodesSyntax? = nil, + number: TokenSyntax, + _ unexpectedAfterNumber: UnexpectedNodesSyntax? = nil, trailingTrivia: Trivia? = nil ) { // Extend the lifetime of all parameters so their arenas don't get destroyed // before they can be added as children of the new arena. let data: SyntaxData = withExtendedLifetime((SyntaxArena(), ( - unexpectedBeforeMajor, - major, - unexpectedBetweenMajorAndMinorPeriod, - minorPeriod, - unexpectedBetweenMinorPeriodAndMinor, - minor, - unexpectedBetweenMinorAndPatchPeriod, - patchPeriod, - unexpectedBetweenPatchPeriodAndPatch, - patch, - unexpectedAfterPatch + unexpectedBeforePeriod, + period, + unexpectedBetweenPeriodAndNumber, + number, + unexpectedAfterNumber ))) {(arena, _) in let layout: [RawSyntax?] = [ - unexpectedBeforeMajor?.raw, - major.raw, - unexpectedBetweenMajorAndMinorPeriod?.raw, - minorPeriod?.raw, - unexpectedBetweenMinorPeriodAndMinor?.raw, - minor?.raw, - unexpectedBetweenMinorAndPatchPeriod?.raw, - patchPeriod?.raw, - unexpectedBetweenPatchPeriodAndPatch?.raw, - patch?.raw, - unexpectedAfterPatch?.raw + unexpectedBeforePeriod?.raw, + period.raw, + unexpectedBetweenPeriodAndNumber?.raw, + number.raw, + unexpectedAfterNumber?.raw ] let raw = RawSyntax.makeLayout( - kind: SyntaxKind.versionTuple, + kind: SyntaxKind.versionComponent, from: layout, arena: arena, leadingTrivia: leadingTrivia, @@ -17510,107 +17492,187 @@ public struct VersionTupleSyntax: SyntaxProtocol, SyntaxHashable { self.init(data) } - public var unexpectedBeforeMajor: UnexpectedNodesSyntax? { + public var unexpectedBeforePeriod: UnexpectedNodesSyntax? { get { return data.child(at: 0, parent: Syntax(self)).map(UnexpectedNodesSyntax.init) } set(value) { - self = VersionTupleSyntax(data.replacingChild(at: 0, with: value?.raw, arena: SyntaxArena())) + self = VersionComponentSyntax(data.replacingChild(at: 0, with: value?.raw, arena: SyntaxArena())) } } - /// The major version. - public var major: TokenSyntax { + /// The period of this version component + public var period: TokenSyntax { get { return TokenSyntax(data.child(at: 1, parent: Syntax(self))!) } set(value) { - self = VersionTupleSyntax(data.replacingChild(at: 1, with: value.raw, arena: SyntaxArena())) + self = VersionComponentSyntax(data.replacingChild(at: 1, with: value.raw, arena: SyntaxArena())) } } - public var unexpectedBetweenMajorAndMinorPeriod: UnexpectedNodesSyntax? { + public var unexpectedBetweenPeriodAndNumber: UnexpectedNodesSyntax? { get { return data.child(at: 2, parent: Syntax(self)).map(UnexpectedNodesSyntax.init) } set(value) { - self = VersionTupleSyntax(data.replacingChild(at: 2, with: value?.raw, arena: SyntaxArena())) + self = VersionComponentSyntax(data.replacingChild(at: 2, with: value?.raw, arena: SyntaxArena())) } } - /// If the version contains a minor number, the period separating the major from the minor number. - public var minorPeriod: TokenSyntax? { + /// The version number of this component + public var number: TokenSyntax { get { - return data.child(at: 3, parent: Syntax(self)).map(TokenSyntax.init) + return TokenSyntax(data.child(at: 3, parent: Syntax(self))!) } set(value) { - self = VersionTupleSyntax(data.replacingChild(at: 3, with: value?.raw, arena: SyntaxArena())) + self = VersionComponentSyntax(data.replacingChild(at: 3, with: value.raw, arena: SyntaxArena())) } } - public var unexpectedBetweenMinorPeriodAndMinor: UnexpectedNodesSyntax? { + public var unexpectedAfterNumber: UnexpectedNodesSyntax? { get { return data.child(at: 4, parent: Syntax(self)).map(UnexpectedNodesSyntax.init) } set(value) { - self = VersionTupleSyntax(data.replacingChild(at: 4, with: value?.raw, arena: SyntaxArena())) + self = VersionComponentSyntax(data.replacingChild(at: 4, with: value?.raw, arena: SyntaxArena())) } } - /// The minor version if specified. - public var minor: TokenSyntax? { - get { - return data.child(at: 5, parent: Syntax(self)).map(TokenSyntax.init) + public static var structure: SyntaxNodeStructure { + return .layout([ + \Self.unexpectedBeforePeriod, + \Self.period, + \Self.unexpectedBetweenPeriodAndNumber, + \Self.number, + \Self.unexpectedAfterNumber + ]) + } +} + +// MARK: - VersionTupleSyntax + +/// A version number like `1.2.0`. Only the first version component is required. There might be an arbitrary number of following components. +public struct VersionTupleSyntax: SyntaxProtocol, SyntaxHashable { + public let _syntaxNode: Syntax + + public init?(_ node: S) { + guard node.raw.kind == .versionTuple else { + return nil } - set(value) { - self = VersionTupleSyntax(data.replacingChild(at: 5, with: value?.raw, arena: SyntaxArena())) + self._syntaxNode = node._syntaxNode + } + + /// Creates a `VersionTupleSyntax` node from the given `SyntaxData`. This assumes + /// that the `SyntaxData` is of the correct kind. If it is not, the behaviour + /// is undefined. + internal init(_ data: SyntaxData) { + precondition(data.raw.kind == .versionTuple) + self._syntaxNode = Syntax(data) + } + + public init( + leadingTrivia: Trivia? = nil, + _ unexpectedBeforeMajor: UnexpectedNodesSyntax? = nil, + major: TokenSyntax, + _ unexpectedBetweenMajorAndComponents: UnexpectedNodesSyntax? = nil, + components: VersionComponentListSyntax? = nil, + _ unexpectedAfterComponents: UnexpectedNodesSyntax? = nil, + trailingTrivia: Trivia? = nil + + ) { + // Extend the lifetime of all parameters so their arenas don't get destroyed + // before they can be added as children of the new arena. + let data: SyntaxData = withExtendedLifetime((SyntaxArena(), ( + unexpectedBeforeMajor, + major, + unexpectedBetweenMajorAndComponents, + components, + unexpectedAfterComponents + ))) {(arena, _) in + let layout: [RawSyntax?] = [ + unexpectedBeforeMajor?.raw, + major.raw, + unexpectedBetweenMajorAndComponents?.raw, + components?.raw, + unexpectedAfterComponents?.raw + ] + let raw = RawSyntax.makeLayout( + kind: SyntaxKind.versionTuple, + from: layout, + arena: arena, + leadingTrivia: leadingTrivia, + trailingTrivia: trailingTrivia + + ) + return SyntaxData.forRoot(raw) } + self.init(data) } - public var unexpectedBetweenMinorAndPatchPeriod: UnexpectedNodesSyntax? { + public var unexpectedBeforeMajor: UnexpectedNodesSyntax? { get { - return data.child(at: 6, parent: Syntax(self)).map(UnexpectedNodesSyntax.init) + return data.child(at: 0, parent: Syntax(self)).map(UnexpectedNodesSyntax.init) } set(value) { - self = VersionTupleSyntax(data.replacingChild(at: 6, with: value?.raw, arena: SyntaxArena())) + self = VersionTupleSyntax(data.replacingChild(at: 0, with: value?.raw, arena: SyntaxArena())) } } - /// If the version contains a patch number, the period separating the minor from the patch number. - public var patchPeriod: TokenSyntax? { + /// The major version. + public var major: TokenSyntax { get { - return data.child(at: 7, parent: Syntax(self)).map(TokenSyntax.init) + return TokenSyntax(data.child(at: 1, parent: Syntax(self))!) } set(value) { - self = VersionTupleSyntax(data.replacingChild(at: 7, with: value?.raw, arena: SyntaxArena())) + self = VersionTupleSyntax(data.replacingChild(at: 1, with: value.raw, arena: SyntaxArena())) } } - public var unexpectedBetweenPatchPeriodAndPatch: UnexpectedNodesSyntax? { + public var unexpectedBetweenMajorAndComponents: UnexpectedNodesSyntax? { get { - return data.child(at: 8, parent: Syntax(self)).map(UnexpectedNodesSyntax.init) + return data.child(at: 2, parent: Syntax(self)).map(UnexpectedNodesSyntax.init) } set(value) { - self = VersionTupleSyntax(data.replacingChild(at: 8, with: value?.raw, arena: SyntaxArena())) + self = VersionTupleSyntax(data.replacingChild(at: 2, with: value?.raw, arena: SyntaxArena())) } } - /// The patch version if specified. - public var patch: TokenSyntax? { + /// Any version components that are not the major version . For example, for `1.2.0`, this will contain `.2.0` + public var components: VersionComponentListSyntax? { get { - return data.child(at: 9, parent: Syntax(self)).map(TokenSyntax.init) + return data.child(at: 3, parent: Syntax(self)).map(VersionComponentListSyntax.init) } set(value) { - self = VersionTupleSyntax(data.replacingChild(at: 9, with: value?.raw, arena: SyntaxArena())) + self = VersionTupleSyntax(data.replacingChild(at: 3, with: value?.raw, arena: SyntaxArena())) } } - public var unexpectedAfterPatch: UnexpectedNodesSyntax? { + /// Adds the provided `VersionComponent` to the node's `components` + /// collection. + /// - param element: The new `VersionComponent` to add to the node's + /// `components` collection. + /// - returns: A copy of the receiver with the provided `VersionComponent` + /// appended to its `components` collection. + public func addVersionComponent(_ element: VersionComponentSyntax) -> VersionTupleSyntax { + var collection: RawSyntax + let arena = SyntaxArena() + if let col = raw.layoutView!.children[3] { + collection = col.layoutView!.appending(element.raw, arena: arena) + } else { + collection = RawSyntax.makeLayout(kind: SyntaxKind.versionComponentList, + from: [element.raw], arena: arena) + } + let newData = data.replacingChild(at: 3, with: collection, arena: arena) + return VersionTupleSyntax(newData) + } + + public var unexpectedAfterComponents: UnexpectedNodesSyntax? { get { - return data.child(at: 10, parent: Syntax(self)).map(UnexpectedNodesSyntax.init) + return data.child(at: 4, parent: Syntax(self)).map(UnexpectedNodesSyntax.init) } set(value) { - self = VersionTupleSyntax(data.replacingChild(at: 10, with: value?.raw, arena: SyntaxArena())) + self = VersionTupleSyntax(data.replacingChild(at: 4, with: value?.raw, arena: SyntaxArena())) } } @@ -17618,15 +17680,9 @@ public struct VersionTupleSyntax: SyntaxProtocol, SyntaxHashable { return .layout([ \Self.unexpectedBeforeMajor, \Self.major, - \Self.unexpectedBetweenMajorAndMinorPeriod, - \Self.minorPeriod, - \Self.unexpectedBetweenMinorPeriodAndMinor, - \Self.minor, - \Self.unexpectedBetweenMinorAndPatchPeriod, - \Self.patchPeriod, - \Self.unexpectedBetweenPatchPeriodAndPatch, - \Self.patch, - \Self.unexpectedAfterPatch + \Self.unexpectedBetweenMajorAndComponents, + \Self.components, + \Self.unexpectedAfterComponents ]) } } diff --git a/Sources/SwiftSyntaxBuilder/generated/BuildableCollectionNodes.swift b/Sources/SwiftSyntaxBuilder/generated/BuildableCollectionNodes.swift index 429eb5f6617..6971be229dc 100644 --- a/Sources/SwiftSyntaxBuilder/generated/BuildableCollectionNodes.swift +++ b/Sources/SwiftSyntaxBuilder/generated/BuildableCollectionNodes.swift @@ -348,6 +348,13 @@ extension UnexpectedNodesSyntax: ExpressibleByArrayLiteral { } } +/// `VersionComponentList` represents a collection of `VersionComponentSyntax` +extension VersionComponentListSyntax: ExpressibleByArrayLiteral { + public init(arrayLiteral elements: Element...) { + self.init(elements) + } +} + /// `YieldExprList` represents a collection of `YieldExprListElementSyntax` extension YieldExprListSyntax: ExpressibleByArrayLiteral { public init(arrayLiteral elements: Element...) { diff --git a/Sources/SwiftSyntaxBuilder/generated/ResultBuilders.swift b/Sources/SwiftSyntaxBuilder/generated/ResultBuilders.swift index 9b7db84da0d..236cbf67263 100644 --- a/Sources/SwiftSyntaxBuilder/generated/ResultBuilders.swift +++ b/Sources/SwiftSyntaxBuilder/generated/ResultBuilders.swift @@ -3838,6 +3838,86 @@ public extension UnexpectedNodesSyntax { } } +@resultBuilder +public struct VersionComponentListBuilder { + /// The type of individual statement expressions in the transformed function, + /// which defaults to Component if buildExpression() is not provided. + public typealias Expression = VersionComponentSyntax + + /// The type of a partial result, which will be carried through all of the + /// build methods. + public typealias Component = [Expression] + + /// The type of the final returned result, which defaults to Component if + /// buildFinalResult() is not provided. + public typealias FinalResult = VersionComponentListSyntax + + /// Required by every result builder to build combined results from + /// statement blocks. + public static func buildBlock(_ components: Self.Component...) -> Self.Component { + return components.flatMap { + $0 + } + } + + /// If declared, provides contextual type information for statement + /// expressions to translate them into partial results. + public static func buildExpression(_ expression: Self.Expression) -> Self.Component { + return [expression] + } + + /// Add all the elements of `expression` to this result builder, effectively flattening them. + public static func buildExpression(_ expression: Self.FinalResult) -> Self.Component { + return expression.map { + $0 + } + } + + /// Enables support for `if` statements that do not have an `else`. + public static func buildOptional(_ component: Self.Component?) -> Self.Component { + return component ?? [] + } + + /// With buildEither(second:), enables support for 'if-else' and 'switch' + /// statements by folding conditional results into a single result. + public static func buildEither(first component: Self.Component) -> Self.Component { + return component + } + + /// With buildEither(first:), enables support for 'if-else' and 'switch' + /// statements by folding conditional results into a single result. + public static func buildEither(second component: Self.Component) -> Self.Component { + return component + } + + /// Enables support for 'for..in' loops by combining the + /// results of all iterations into a single result. + public static func buildArray(_ components: [Self.Component]) -> Self.Component { + return components.flatMap { + $0 + } + } + + /// If declared, this will be called on the partial result of an 'if' + /// #available' block to allow the result builder to erase type + /// information. + public static func buildLimitedAvailability(_ component: Self.Component) -> Self.Component { + return component + } + + /// If declared, this will be called on the partial result from the outermost + /// block statement to produce the final returned result. + public static func buildFinalResult(_ component: Component) -> FinalResult { + return .init(component) + } +} + +public extension VersionComponentListSyntax { + init(@VersionComponentListBuilder itemsBuilder: () throws -> VersionComponentListSyntax) rethrows { + self = try itemsBuilder() + } +} + @resultBuilder public struct YieldExprListBuilder { /// The type of individual statement expressions in the transformed function, diff --git a/Tests/SwiftParserTest/AvailabilityTests.swift b/Tests/SwiftParserTest/AvailabilityTests.swift index de866041b6e..8b71a793e75 100644 --- a/Tests/SwiftParserTest/AvailabilityTests.swift +++ b/Tests/SwiftParserTest/AvailabilityTests.swift @@ -121,8 +121,7 @@ final class AvailabilityTests: XCTestCase { substructure: Syntax( VersionTupleSyntax( major: .integerLiteral("10"), - minorPeriod: .periodToken(), - minor: .integerLiteral("0") + components: VersionComponentListSyntax([VersionComponentSyntax(number: .integerLiteral("0"))]) ) ) ) @@ -135,10 +134,10 @@ final class AvailabilityTests: XCTestCase { substructure: Syntax( VersionTupleSyntax( major: .integerLiteral("10"), - minorPeriod: .periodToken(), - minor: .integerLiteral("0"), - patchPeriod: .periodToken(), - patch: .integerLiteral("1") + components: VersionComponentListSyntax([ + VersionComponentSyntax(number: .integerLiteral("0")), + VersionComponentSyntax(number: .integerLiteral("1")), + ]) ) ) ) diff --git a/Tests/SwiftParserTest/translated/IfconfigExprTests.swift b/Tests/SwiftParserTest/translated/IfconfigExprTests.swift index 51b7509b6f4..673d0cbd214 100644 --- a/Tests/SwiftParserTest/translated/IfconfigExprTests.swift +++ b/Tests/SwiftParserTest/translated/IfconfigExprTests.swift @@ -259,12 +259,12 @@ final class IfconfigExprTests: XCTestCase { func testIfconfigExpr17() { assertParse( """ - #if canImport(A, _version: 2.2.2.2.2) + #if canImport(A, _version: 2.2.2.21️⃣.2) let a = 1 #endif """, diagnostics: [ - // TODO: Old parser expected warning on line 1: trailing components of version '2.2.2.2' are ignored + DiagnosticSpec(message: "trailing components of version 2.2.2.2 are ignored", severity: .warning) ] ) } @@ -312,12 +312,12 @@ final class IfconfigExprTests: XCTestCase { func testIfconfigExpr22() { assertParse( """ - #if canImport(A, unknown: 2.2) + #if canImport(A, 1️⃣unknown: 2.2) let a = 1 #endif """, diagnostics: [ - // TODO: Old parser expected error on line 1: 2nd parameter of canImport should be labeled as _version or _underlyingVersion + DiagnosticSpec(message: "2nd parameter of canImport should be labeled as _version or _underlyingVersion") ] ) } @@ -330,25 +330,20 @@ final class IfconfigExprTests: XCTestCase { #endif """, diagnostics: [ - DiagnosticSpec(message: "expected value in function call", fixIts: ["insert value"]) - ], - fixedSource: """ - #if canImport(A, <#expression#>) - let a = 1 - #endif - """ + DiagnosticSpec(message: "2nd parameter of canImport should be labeled as _version or _underlyingVersion") + ] ) } func testIfconfigExpr24() { assertParse( """ - #if canImport(A, 2.2) + #if canImport(A, 1️⃣2.2) let a = 1 #endif """, diagnostics: [ - // TODO: Old parser expected error on line 1: 2nd parameter of canImport should be labeled as _version or _underlyingVersion + DiagnosticSpec(message: "2nd parameter of canImport should be labeled as _version or _underlyingVersion") ] ) } @@ -356,12 +351,13 @@ final class IfconfigExprTests: XCTestCase { func testIfconfigExpr25() { assertParse( """ - #if canImport(A, 2.2, 1.1) + #if canImport(A, 1️⃣2.22️⃣, 1.1) let a = 1 #endif """, diagnostics: [ - // TODO: Old parser expected error on line 1: canImport can take only two parameters + DiagnosticSpec(locationMarker: "1️⃣", message: "2nd parameter of canImport should be labeled as _version or _underlyingVersion"), + DiagnosticSpec(locationMarker: "2️⃣", message: "canImport can take only two parameters"), ] ) } @@ -374,10 +370,10 @@ final class IfconfigExprTests: XCTestCase { #endif """, diagnostics: [ - DiagnosticSpec(message: "expected value in function call", fixIts: ["insert value"]) + DiagnosticSpec(message: "expected version tuple in 'canImport' expression", fixIts: ["insert version tuple"]) ], fixedSource: """ - #if canImport(A, _version: <#expression#>) + #if canImport(A, _version: <#integer literal#>) let a = 1 #endif """ @@ -387,12 +383,12 @@ final class IfconfigExprTests: XCTestCase { func testIfconfigExpr27() { assertParse( #""" - #if canImport(A, _version: "") + #if canImport(A, _version: 1️⃣"") let a = 1 #endif """#, diagnostics: [ - // TODO: Old parser expected error on line 1: _version argument cannot be empty + DiagnosticSpec(message: "cannot parse version \"\"") ] ) } @@ -400,12 +396,12 @@ final class IfconfigExprTests: XCTestCase { func testIfconfigExpr28() { assertParse( """ - #if canImport(A, _version: >=2.2) + #if canImport(A, _version: 1️⃣>=2.2) let a = 1 #endif """, diagnostics: [ - // TODO: Old parser expected error on line 1: cannot parse module version '>=2.2' + DiagnosticSpec(message: "cannot parse version >=2.2") ] ) } @@ -413,12 +409,12 @@ final class IfconfigExprTests: XCTestCase { func testIfconfigExpr29() { assertParse( """ - #if canImport(A, _version: 201️⃣A301) + #if canImport(A, _version: 1️⃣20A301) let a = 1 #endif """, diagnostics: [ - DiagnosticSpec(message: "'A' is not a valid digit in integer literal") + DiagnosticSpec(message: "cannot parse version 20A301") ] ) } @@ -426,12 +422,12 @@ final class IfconfigExprTests: XCTestCase { func testIfconfigExpr30() { assertParse( #""" - #if canImport(A, _version: "20A301") + #if canImport(A, _version: 1️⃣"20A301") let a = 1 #endif """#, diagnostics: [ - // TODO: Old parser expected error on line 1: cannot parse module version '20A301' + DiagnosticSpec(message: "cannot parse version \"20A301\"") ] ) } @@ -561,6 +557,54 @@ final class IfconfigExprTests: XCTestCase { ) } + func testCanImportFuncCall() { + assertParse( + """ + canImport(a, b, c) + """ + ) + } + + func testArchFuncCall() { + assertParse( + """ + arch() + """ + ) + } + + func testOsFuncCall() { + assertParse( + """ + os(bogus) + """ + ) + } + + func testTargetEnvironmentFuncCall() { + assertParse( + """ + targetEnvironment(foo, bar) + """ + ) + } + + func testCompilerFuncCall() { + assertParse( + """ + compiler(a) + """ + ) + } + + func testSwiftFuncCall() { + assertParse( + """ + swift(foo) + """ + ) + } + func testUnknownPlatform1() { assertParse( """