Skip to content

Commit 53101dd

Browse files
committed
Remove CanImportSyntax
Add a function to determine whether an `ExprSyntax` is a valid `VersionTupleSyntax`
1 parent 3eb344c commit 53101dd

27 files changed

+148
-1127
lines changed

CodeGeneration/Sources/SyntaxSupport/AvailabilityNodes.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,7 @@ public let AVAILABILITY_NODES: [Node] = [
171171
base: .syntax,
172172
nameForDiagnostics: "version tuple",
173173
documentation: "A version number like `1.2.0`. Only the first version component is required. There might be an arbitrary number of following components.",
174+
parserFunction: "parseVersionTupleWithFourComponents",
174175
children: [
175176
Child(
176177
name: "Major",

CodeGeneration/Sources/SyntaxSupport/ExprNodes.swift

Lines changed: 0 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -192,61 +192,6 @@ public let EXPR_NODES: [Node] = [
192192
]
193193
),
194194

195-
// the canImport expr in if config expression
196-
Node(
197-
kind: .canImportExpr,
198-
base: .expr,
199-
nameForDiagnostics: "'canImport' expression",
200-
children: [
201-
Child(
202-
name: "CanImportKeyword",
203-
kind: .token(choices: [.keyword(text: "canImport")])
204-
),
205-
Child(
206-
name: "LeftParen",
207-
kind: .token(choices: [.token(.leftParen)])
208-
),
209-
Child(
210-
name: "ImportPath",
211-
kind: .token(choices: [.token(.identifier)])
212-
),
213-
Child(
214-
name: "VersionInfo",
215-
kind: .node(kind: .canImportVersionInfo),
216-
isOptional: true
217-
),
218-
Child(
219-
name: "RightParen",
220-
kind: .token(choices: [.token(.rightParen)])
221-
),
222-
]
223-
),
224-
225-
Node(
226-
kind: .canImportVersionInfo,
227-
base: .expr,
228-
nameForDiagnostics: nil,
229-
children: [
230-
Child(
231-
name: "Comma",
232-
kind: .token(choices: [.token(.comma)])
233-
),
234-
Child(
235-
name: "Label",
236-
kind: .token(choices: [.keyword(text: "_version"), .keyword(text: "_underlyingVersion")])
237-
),
238-
Child(
239-
name: "Colon",
240-
kind: .token(choices: [.token(.colon)])
241-
),
242-
Child(
243-
name: "Version",
244-
deprecatedName: "VersionTuple",
245-
kind: .node(kind: .versionTuple)
246-
),
247-
]
248-
),
249-
250195
// case-item -> pattern where-clause? ','?
251196
Node(
252197
kind: .switchCaseItem,

CodeGeneration/Sources/generate-swiftsyntax/templates/swiftparser/ParserEntryFile.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,5 +74,12 @@ let parserEntryFile = SourceFileSyntax(leadingTrivia: copyrightHeader) {
7474
}
7575
"""
7676
)
77+
DeclSyntax(
78+
"""
79+
mutating func parseVersionTupleWithFourComponents() -> RawVersionTupleSyntax {
80+
return self.parseVersionTuple(maxComponentCount: 4)
81+
}
82+
"""
83+
)
7784
}
7885
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2023 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
@_spi(RawSyntax) import SwiftSyntax
14+
15+
/// When we have `SwiftIfConfig` library, we will move the diagnose for `canImport` expression there and this function should help determine whether an `ExprSyntax` is a legal `VersionTupleSyntax`, which is the second parameter of a `canImport` expression
16+
extension ExprSyntax {
17+
public func interpretAsVersionTuple(with maxComponentCount: Int) -> VersionTupleSyntax? {
18+
var parser = Parser(self.description)
19+
return VersionTupleSyntax.parse(from: &parser)
20+
}
21+
}

Sources/SwiftParser/Expressions.swift

Lines changed: 1 addition & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -580,7 +580,7 @@ extension Parser {
580580
forDirective: Bool,
581581
pattern: PatternContext
582582
) -> RawExprSyntax {
583-
let head = self.parsePrimaryExpression(pattern: pattern, forDirective: forDirective, flavor: flavor)
583+
let head = self.parsePrimaryExpression(pattern: pattern, flavor: flavor)
584584
guard !head.is(RawMissingExprSyntax.self) else {
585585
return head
586586
}
@@ -1079,15 +1079,8 @@ extension Parser {
10791079
/// Swift expression grammar.
10801080
mutating func parsePrimaryExpression(
10811081
pattern: PatternContext,
1082-
forDirective: Bool,
10831082
flavor: ExprFlavor
10841083
) -> RawExprSyntax {
1085-
if forDirective == true,
1086-
let directiveExpr = self.parsePrimaryExprForDirective()
1087-
{
1088-
return RawExprSyntax(directiveExpr)
1089-
}
1090-
10911084
switch self.at(anyIn: PrimaryExpressionStart.self) {
10921085
case (.integerLiteral, let handle)?:
10931086
let literal = self.eat(handle)
@@ -1229,18 +1222,6 @@ extension Parser {
12291222
return RawExprSyntax(RawMissingExprSyntax(arena: self.arena))
12301223
}
12311224
}
1232-
1233-
// try to parse a primary expression for a directive
1234-
mutating func parsePrimaryExprForDirective() -> RawExprSyntax? {
1235-
switch self.at(anyIn: CompilationCondition.self) {
1236-
case (.canImport, let handle)?:
1237-
return RawExprSyntax(self.parseCanImportExpression(handle))
1238-
1239-
// TODO: add case `swift` and `compiler` here
1240-
default:
1241-
return nil
1242-
}
1243-
}
12441225
}
12451226

12461227
extension Parser {
@@ -2351,52 +2332,6 @@ extension Parser {
23512332
}
23522333
}
23532334

2354-
// MARK: Platform Condition
2355-
extension Parser {
2356-
mutating func parseCanImportExpression(_ handle: TokenConsumptionHandle) -> RawExprSyntax {
2357-
let canImportKeyword = self.eat(handle)
2358-
2359-
let (unexpectedBeforeLeftParen, leftParen) = self.expect(.leftParen)
2360-
2361-
let (unexpectedBeforeImportPath, importPath) = self.expect(.identifier)
2362-
2363-
var versionInfo: RawCanImportVersionInfoSyntax?
2364-
2365-
if let comma = self.consume(if: .comma) {
2366-
let (unexpectedBeforeLabel, label) = self.expect(anyIn: CanImportVersionInfoSyntax.LabelOptions.self, default: ._version)
2367-
let (unexpectedBeforeColon, colon) = self.expect(.colon)
2368-
2369-
let version = self.parseVersionTuple(maxComponentCount: 4)
2370-
2371-
versionInfo = RawCanImportVersionInfoSyntax(
2372-
comma: comma,
2373-
unexpectedBeforeLabel,
2374-
label: label,
2375-
unexpectedBeforeColon,
2376-
colon: colon,
2377-
version: version,
2378-
arena: self.arena
2379-
)
2380-
}
2381-
2382-
let (unexpectedBeforeRightParen, rightParen) = self.expect(.rightParen)
2383-
2384-
return RawExprSyntax(
2385-
RawCanImportExprSyntax(
2386-
canImportKeyword: canImportKeyword,
2387-
unexpectedBeforeLeftParen,
2388-
leftParen: leftParen,
2389-
unexpectedBeforeImportPath,
2390-
importPath: importPath,
2391-
versionInfo: versionInfo,
2392-
unexpectedBeforeRightParen,
2393-
rightParen: rightParen,
2394-
arena: self.arena
2395-
)
2396-
)
2397-
}
2398-
}
2399-
24002335
// MARK: Lookahead
24012336

24022337
extension Parser.Lookahead {

Sources/SwiftParser/generated/LayoutNodes+Parsable.swift

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,24 @@ extension TypeSyntax: SyntaxParseable {
324324
}
325325
}
326326

327+
extension VersionTupleSyntax: SyntaxParseable {
328+
public static func parse(from parser: inout Parser) -> Self {
329+
// Keep the parser alive so that the arena in which `raw` is allocated
330+
// doesn’t get deallocated before we have a chance to create a syntax node
331+
// from it. We can’t use `parser.arena` as the parameter to
332+
// `Syntax(raw:arena:)` because the node might have been re-used during an
333+
// incremental parse and would then live in a different arena than
334+
// `parser.arena`.
335+
defer {
336+
withExtendedLifetime(parser) {
337+
}
338+
}
339+
let node = parser.parseVersionTupleWithFourComponents()
340+
let raw = RawSyntax(parser.parseRemainder(into: node))
341+
return Syntax(raw: raw, rawNodeArena: raw.arena).cast(Self.self)
342+
}
343+
}
344+
327345
fileprivate extension Parser {
328346
mutating func parseNonOptionalCodeBlockItem() -> RawCodeBlockItemSyntax {
329347
guard let node = self.parseCodeBlockItem(isAtTopLevel: false, allowInitDecl: true) else {
@@ -345,4 +363,8 @@ fileprivate extension Parser {
345363
}
346364
return node
347365
}
366+
367+
mutating func parseVersionTupleWithFourComponents() -> RawVersionTupleSyntax {
368+
return self.parseVersionTuple(maxComponentCount: 4)
369+
}
348370
}

Sources/SwiftParser/generated/Parser+TokenSpecSet.swift

Lines changed: 0 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -393,47 +393,6 @@ extension BooleanLiteralExprSyntax {
393393
}
394394
}
395395

396-
extension CanImportVersionInfoSyntax {
397-
@_spi(Diagnostics)
398-
public enum LabelOptions: TokenSpecSet {
399-
case _version
400-
case _underlyingVersion
401-
402-
init?(lexeme: Lexer.Lexeme) {
403-
switch PrepareForKeywordMatch(lexeme) {
404-
case TokenSpec(._version):
405-
self = ._version
406-
case TokenSpec(._underlyingVersion):
407-
self = ._underlyingVersion
408-
default:
409-
return nil
410-
}
411-
}
412-
413-
var spec: TokenSpec {
414-
switch self {
415-
case ._version:
416-
return .keyword(._version)
417-
case ._underlyingVersion:
418-
return .keyword(._underlyingVersion)
419-
}
420-
}
421-
422-
/// Returns a token that satisfies the `TokenSpec` of this case.
423-
///
424-
/// If the token kind of this spec has variable text, e.g. for an identifier, this returns a token with empty text.
425-
@_spi(Diagnostics)
426-
public var tokenSyntax: TokenSyntax {
427-
switch self {
428-
case ._version:
429-
return .keyword(._version)
430-
case ._underlyingVersion:
431-
return .keyword(._underlyingVersion)
432-
}
433-
}
434-
}
435-
}
436-
437396
extension ClosureCaptureSpecifierSyntax {
438397
@_spi(Diagnostics)
439398
public enum SpecifierOptions: TokenSpecSet {

Sources/SwiftParserDiagnostics/ParseDiagnosticsGenerator.swift

Lines changed: 0 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -610,50 +610,6 @@ public class ParseDiagnosticsGenerator: SyntaxAnyVisitor {
610610
return .visitChildren
611611
}
612612

613-
public override func visit(_ node: CanImportExprSyntax) -> SyntaxVisitorContinueKind {
614-
if shouldSkip(node) {
615-
return .skipChildren
616-
}
617-
618-
if let versionTuple = node.versionInfo?.version,
619-
let unexpectedVersionTuple = node.unexpectedBetweenVersionInfoAndRightParen
620-
{
621-
if versionTuple.major.isMissing {
622-
addDiagnostic(
623-
versionTuple,
624-
CannotParseVersionTuple(versionTuple: unexpectedVersionTuple),
625-
handledNodes: [versionTuple.id, unexpectedVersionTuple.id]
626-
)
627-
} else {
628-
addDiagnostic(
629-
unexpectedVersionTuple,
630-
.canImportWrongNumberOfParameter,
631-
handledNodes: [unexpectedVersionTuple.id]
632-
)
633-
}
634-
}
635-
636-
return .visitChildren
637-
}
638-
639-
public override func visit(_ node: CanImportVersionInfoSyntax) -> SyntaxVisitorContinueKind {
640-
if shouldSkip(node) {
641-
return .skipChildren
642-
}
643-
644-
if node.label.isMissing {
645-
addDiagnostic(
646-
node.label,
647-
.canImportWrongSecondParameterLabel,
648-
handledNodes: [node.label.id]
649-
)
650-
651-
handledNodes.append(contentsOf: [node.unexpectedBetweenLabelAndColon?.id, node.colon.id, node.version.id].compactMap { $0 })
652-
}
653-
654-
return .visitChildren
655-
}
656-
657613
public override func visit(_ node: ConditionElementSyntax) -> SyntaxVisitorContinueKind {
658614
if shouldSkip(node) {
659615
return .skipChildren

Sources/SwiftParserDiagnostics/ParserDiagnosticMessages.swift

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -93,12 +93,6 @@ extension DiagnosticMessage where Self == StaticParserError {
9393
public static var associatedTypeCannotUsePack: Self {
9494
.init("associated types cannot be variadic")
9595
}
96-
public static var canImportWrongSecondParameterLabel: Self {
97-
.init("2nd parameter of canImport should be labeled as _version or _underlyingVersion")
98-
}
99-
public static var canImportWrongNumberOfParameter: Self {
100-
.init("canImport can take only two parameters")
101-
}
10296
public static var caseOutsideOfSwitchOrEnum: Self {
10397
.init("'case' can only appear inside a 'switch' statement or 'enum' declaration")
10498
}

Sources/SwiftParserDiagnostics/generated/SyntaxKindNameForDiagnostics.swift

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,6 @@ extension SyntaxKind {
6161
return "'_borrow' expression"
6262
case .breakStmt:
6363
return "'break' statement"
64-
case .canImportExpr:
65-
return "'canImport' expression"
6664
case .catchClauseList:
6765
return "'catch' clause"
6866
case .catchClause:

Sources/SwiftSyntax/Documentation.docc/generated/SwiftSyntax.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,6 @@ These articles are intended for developers wishing to contribute to SwiftSyntax
102102
- <doc:SwiftSyntax/BinaryOperatorExprSyntax>
103103
- <doc:SwiftSyntax/BooleanLiteralExprSyntax>
104104
- <doc:SwiftSyntax/BorrowExprSyntax>
105-
- <doc:SwiftSyntax/CanImportExprSyntax>
106-
- <doc:SwiftSyntax/CanImportVersionInfoSyntax>
107105
- <doc:SwiftSyntax/ClosureExprSyntax>
108106
- <doc:SwiftSyntax/ConsumeExprSyntax>
109107
- <doc:SwiftSyntax/CopyExprSyntax>

0 commit comments

Comments
 (0)