Skip to content

Commit 15cc691

Browse files
committed
Add a new test mutation strategy that flips each token presence
This uncovered two round-trip parsing failures which I’m fixing in this commit. rdar://109783066
1 parent 1a7ae03 commit 15cc691

File tree

11 files changed

+353
-100
lines changed

11 files changed

+353
-100
lines changed

CodeGeneration/Sources/SyntaxSupport/DeclNodes.swift

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -549,11 +549,33 @@ public let DECL_NODES: [Node] = [
549549
kind: .editorPlaceholderDecl,
550550
base: .decl,
551551
nameForDiagnostics: "editor placeholder",
552+
documentation: """
553+
An editor placeholder, e.g. `<#declaration#>` that is used in a position that expects a declaration.
554+
""",
555+
traits: [
556+
"WithAttributes",
557+
"WithModifiers",
558+
],
552559
children: [
553560
Child(
554-
name: "Identifier",
555-
kind: .token(choices: [.token(tokenKind: "IdentifierToken")])
556-
)
561+
name: "Attributes",
562+
kind: .collection(kind: .attributeList, collectionElementName: "Attribute"),
563+
description: "If there were attributes before the editor placeholder, the ``EditorPlaceholderDecl`` will contain these.",
564+
isOptional: true
565+
),
566+
Child(
567+
name: "Modifiers",
568+
kind: .collection(kind: .modifierList, collectionElementName: "Modifier"),
569+
description: "If there were modifiers before the editor placeholder, the `EditorPlaceholderDecl` will contain these.",
570+
isOptional: true
571+
),
572+
Child(
573+
name: "Placeholder",
574+
kind: .token(choices: [.token(tokenKind: "IdentifierToken")]),
575+
description: """
576+
The actual editor placeholder that starts with `<#` and ends with `#>`.
577+
"""
578+
),
557579
]
558580
),
559581

Sources/SwiftParser/Declarations.swift

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,9 @@ extension Parser {
286286
let placeholder = self.consumeAnyToken()
287287
return RawDeclSyntax(
288288
RawEditorPlaceholderDeclSyntax(
289-
identifier: placeholder,
289+
attributes: attrs.attributes,
290+
modifiers: attrs.modifiers,
291+
placeholder: placeholder,
290292
arena: self.arena
291293
)
292294
)
@@ -474,8 +476,12 @@ extension Parser {
474476
)
475477
}
476478

477-
precondition(self.currentToken.starts(with: "<"))
478-
let langle = self.consumePrefix("<", as: .leftAngle)
479+
let langle: RawTokenSyntax
480+
if self.currentToken.starts(with: "<") {
481+
langle = self.consumePrefix("<", as: .leftAngle)
482+
} else {
483+
langle = missingToken(.leftAngle)
484+
}
479485
var elements = [RawGenericParameterSyntax]()
480486
do {
481487
var keepGoing: RawTokenSyntax? = nil

Sources/SwiftParser/Types.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -546,7 +546,7 @@ extension Parser {
546546
inOut: nil,
547547
name: nil,
548548
secondName: nil,
549-
unexpectedBeforeColon,
549+
RawUnexpectedNodesSyntax(combining: misplacedSpecifiers, unexpectedBeforeColon, arena: self.arena),
550550
colon: nil,
551551
type: RawTypeSyntax(RawSimpleTypeIdentifierSyntax(name: first, genericArgumentClause: nil, arena: self.arena)),
552552
ellipsis: nil,

Sources/SwiftSyntax/SwiftSyntaxCompatibility.swift

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,3 +152,23 @@ extension TupleExprSyntax {
152152
)
153153
}
154154
}
155+
156+
public extension EditorPlaceholderDeclSyntax {
157+
@available(*, deprecated, renamed: "placeholder")
158+
var identifier: TokenSyntax { placeholder }
159+
160+
@available(*, deprecated, renamed: "placeholder")
161+
init(
162+
leadingTrivia: Trivia? = nil,
163+
_ unexpectedBeforeIdentifier: UnexpectedNodesSyntax? = nil,
164+
identifier: TokenSyntax,
165+
_ unexpectedAfterIdentifier: UnexpectedNodesSyntax? = nil
166+
) {
167+
self.init(
168+
leadingTrivia: leadingTrivia,
169+
unexpectedBeforeIdentifier,
170+
placeholder: identifier,
171+
unexpectedAfterIdentifier
172+
)
173+
}
174+
}

Sources/SwiftSyntax/generated/ChildNameForKeyPath.swift

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1099,12 +1099,20 @@ public func childName(_ keyPath: AnyKeyPath) -> String? {
10991099
return "declname"
11001100
case \DynamicReplacementArgumentsSyntax.unexpectedAfterDeclname:
11011101
return "unexpectedAfterDeclname"
1102-
case \EditorPlaceholderDeclSyntax.unexpectedBeforeIdentifier:
1103-
return "unexpectedBeforeIdentifier"
1104-
case \EditorPlaceholderDeclSyntax.identifier:
1105-
return "identifier"
1106-
case \EditorPlaceholderDeclSyntax.unexpectedAfterIdentifier:
1107-
return "unexpectedAfterIdentifier"
1102+
case \EditorPlaceholderDeclSyntax.unexpectedBeforeAttributes:
1103+
return "unexpectedBeforeAttributes"
1104+
case \EditorPlaceholderDeclSyntax.attributes:
1105+
return "attributes"
1106+
case \EditorPlaceholderDeclSyntax.unexpectedBetweenAttributesAndModifiers:
1107+
return "unexpectedBetweenAttributesAndModifiers"
1108+
case \EditorPlaceholderDeclSyntax.modifiers:
1109+
return "modifiers"
1110+
case \EditorPlaceholderDeclSyntax.unexpectedBetweenModifiersAndPlaceholder:
1111+
return "unexpectedBetweenModifiersAndPlaceholder"
1112+
case \EditorPlaceholderDeclSyntax.placeholder:
1113+
return "placeholder"
1114+
case \EditorPlaceholderDeclSyntax.unexpectedAfterPlaceholder:
1115+
return "unexpectedAfterPlaceholder"
11081116
case \EditorPlaceholderExprSyntax.unexpectedBeforeIdentifier:
11091117
return "unexpectedBeforeIdentifier"
11101118
case \EditorPlaceholderExprSyntax.identifier:

Sources/SwiftSyntax/generated/SyntaxTraits.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -539,6 +539,8 @@ extension DoStmtSyntax: WithCodeBlockSyntax {}
539539

540540
extension DocumentationAttributeArgumentSyntax: WithTrailingCommaSyntax {}
541541

542+
extension EditorPlaceholderDeclSyntax: WithAttributesSyntax, WithModifiersSyntax {}
543+
542544
extension EnumCaseDeclSyntax: WithAttributesSyntax, WithModifiersSyntax {}
543545

544546
extension EnumCaseElementSyntax: WithTrailingCommaSyntax {}

Sources/SwiftSyntax/generated/raw/RawSyntaxNodes.swift

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7666,32 +7666,56 @@ public struct RawEditorPlaceholderDeclSyntax: RawDeclSyntaxNodeProtocol {
76667666
}
76677667

76687668
public init(
7669-
_ unexpectedBeforeIdentifier: RawUnexpectedNodesSyntax? = nil,
7670-
identifier: RawTokenSyntax,
7671-
_ unexpectedAfterIdentifier: RawUnexpectedNodesSyntax? = nil,
7669+
_ unexpectedBeforeAttributes: RawUnexpectedNodesSyntax? = nil,
7670+
attributes: RawAttributeListSyntax?,
7671+
_ unexpectedBetweenAttributesAndModifiers: RawUnexpectedNodesSyntax? = nil,
7672+
modifiers: RawModifierListSyntax?,
7673+
_ unexpectedBetweenModifiersAndPlaceholder: RawUnexpectedNodesSyntax? = nil,
7674+
placeholder: RawTokenSyntax,
7675+
_ unexpectedAfterPlaceholder: RawUnexpectedNodesSyntax? = nil,
76727676
arena: __shared SyntaxArena
76737677
) {
76747678
let raw = RawSyntax.makeLayout(
7675-
kind: .editorPlaceholderDecl, uninitializedCount: 3, arena: arena) { layout in
7679+
kind: .editorPlaceholderDecl, uninitializedCount: 7, arena: arena) { layout in
76767680
layout.initialize(repeating: nil)
7677-
layout[0] = unexpectedBeforeIdentifier?.raw
7678-
layout[1] = identifier.raw
7679-
layout[2] = unexpectedAfterIdentifier?.raw
7681+
layout[0] = unexpectedBeforeAttributes?.raw
7682+
layout[1] = attributes?.raw
7683+
layout[2] = unexpectedBetweenAttributesAndModifiers?.raw
7684+
layout[3] = modifiers?.raw
7685+
layout[4] = unexpectedBetweenModifiersAndPlaceholder?.raw
7686+
layout[5] = placeholder.raw
7687+
layout[6] = unexpectedAfterPlaceholder?.raw
76807688
}
76817689
self.init(unchecked: raw)
76827690
}
76837691

7684-
public var unexpectedBeforeIdentifier: RawUnexpectedNodesSyntax? {
7692+
public var unexpectedBeforeAttributes: RawUnexpectedNodesSyntax? {
76857693
layoutView.children[0].map(RawUnexpectedNodesSyntax.init(raw:))
76867694
}
76877695

7688-
public var identifier: RawTokenSyntax {
7689-
layoutView.children[1].map(RawTokenSyntax.init(raw:))!
7696+
public var attributes: RawAttributeListSyntax? {
7697+
layoutView.children[1].map(RawAttributeListSyntax.init(raw:))
76907698
}
76917699

7692-
public var unexpectedAfterIdentifier: RawUnexpectedNodesSyntax? {
7700+
public var unexpectedBetweenAttributesAndModifiers: RawUnexpectedNodesSyntax? {
76937701
layoutView.children[2].map(RawUnexpectedNodesSyntax.init(raw:))
76947702
}
7703+
7704+
public var modifiers: RawModifierListSyntax? {
7705+
layoutView.children[3].map(RawModifierListSyntax.init(raw:))
7706+
}
7707+
7708+
public var unexpectedBetweenModifiersAndPlaceholder: RawUnexpectedNodesSyntax? {
7709+
layoutView.children[4].map(RawUnexpectedNodesSyntax.init(raw:))
7710+
}
7711+
7712+
public var placeholder: RawTokenSyntax {
7713+
layoutView.children[5].map(RawTokenSyntax.init(raw:))!
7714+
}
7715+
7716+
public var unexpectedAfterPlaceholder: RawUnexpectedNodesSyntax? {
7717+
layoutView.children[6].map(RawUnexpectedNodesSyntax.init(raw:))
7718+
}
76957719
}
76967720

76977721
@_spi(RawSyntax)

Sources/SwiftSyntax/generated/raw/RawSyntaxValidation.swift

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1050,10 +1050,14 @@ func validateLayout(layout: RawSyntaxBuffer, as kind: SyntaxKind) {
10501050
assertNoError(kind, 5, verify(layout[5], as: RawDeclNameSyntax.self))
10511051
assertNoError(kind, 6, verify(layout[6], as: RawUnexpectedNodesSyntax?.self))
10521052
case .editorPlaceholderDecl:
1053-
assert(layout.count == 3)
1053+
assert(layout.count == 7)
10541054
assertNoError(kind, 0, verify(layout[0], as: RawUnexpectedNodesSyntax?.self))
1055-
assertNoError(kind, 1, verify(layout[1], as: RawTokenSyntax.self, tokenChoices: [.tokenKind(.identifier)]))
1055+
assertNoError(kind, 1, verify(layout[1], as: RawAttributeListSyntax?.self))
10561056
assertNoError(kind, 2, verify(layout[2], as: RawUnexpectedNodesSyntax?.self))
1057+
assertNoError(kind, 3, verify(layout[3], as: RawModifierListSyntax?.self))
1058+
assertNoError(kind, 4, verify(layout[4], as: RawUnexpectedNodesSyntax?.self))
1059+
assertNoError(kind, 5, verify(layout[5], as: RawTokenSyntax.self, tokenChoices: [.tokenKind(.identifier)]))
1060+
assertNoError(kind, 6, verify(layout[6], as: RawUnexpectedNodesSyntax?.self))
10571061
case .editorPlaceholderExpr:
10581062
assert(layout.count == 3)
10591063
assertNoError(kind, 0, verify(layout[0], as: RawUnexpectedNodesSyntax?.self))

Sources/SwiftSyntax/generated/syntaxNodes/SyntaxDeclNodes.swift

Lines changed: 117 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1429,7 +1429,7 @@ public struct DeinitializerDeclSyntax: DeclSyntaxProtocol, SyntaxHashable {
14291429

14301430
// MARK: - EditorPlaceholderDeclSyntax
14311431

1432-
1432+
/// An editor placeholder, e.g. `<#declaration#>` that is used in a position that expects a declaration.
14331433
public struct EditorPlaceholderDeclSyntax: DeclSyntaxProtocol, SyntaxHashable {
14341434
public let _syntaxNode: Syntax
14351435

@@ -1450,16 +1450,36 @@ public struct EditorPlaceholderDeclSyntax: DeclSyntaxProtocol, SyntaxHashable {
14501450

14511451
public init(
14521452
leadingTrivia: Trivia? = nil,
1453-
_ unexpectedBeforeIdentifier: UnexpectedNodesSyntax? = nil,
1454-
identifier: TokenSyntax,
1455-
_ unexpectedAfterIdentifier: UnexpectedNodesSyntax? = nil,
1453+
_ unexpectedBeforeAttributes: UnexpectedNodesSyntax? = nil,
1454+
attributes: AttributeListSyntax? = nil,
1455+
_ unexpectedBetweenAttributesAndModifiers: UnexpectedNodesSyntax? = nil,
1456+
modifiers: ModifierListSyntax? = nil,
1457+
_ unexpectedBetweenModifiersAndPlaceholder: UnexpectedNodesSyntax? = nil,
1458+
placeholder: TokenSyntax,
1459+
_ unexpectedAfterPlaceholder: UnexpectedNodesSyntax? = nil,
14561460
trailingTrivia: Trivia? = nil
14571461

14581462
) {
14591463
// Extend the lifetime of all parameters so their arenas don't get destroyed
14601464
// before they can be added as children of the new arena.
1461-
let data: SyntaxData = withExtendedLifetime((SyntaxArena(), (unexpectedBeforeIdentifier, identifier, unexpectedAfterIdentifier))) {(arena, _) in
1462-
let layout: [RawSyntax?] = [unexpectedBeforeIdentifier?.raw, identifier.raw, unexpectedAfterIdentifier?.raw]
1465+
let data: SyntaxData = withExtendedLifetime((SyntaxArena(), (
1466+
unexpectedBeforeAttributes,
1467+
attributes,
1468+
unexpectedBetweenAttributesAndModifiers,
1469+
modifiers,
1470+
unexpectedBetweenModifiersAndPlaceholder,
1471+
placeholder,
1472+
unexpectedAfterPlaceholder
1473+
))) {(arena, _) in
1474+
let layout: [RawSyntax?] = [
1475+
unexpectedBeforeAttributes?.raw,
1476+
attributes?.raw,
1477+
unexpectedBetweenAttributesAndModifiers?.raw,
1478+
modifiers?.raw,
1479+
unexpectedBetweenModifiersAndPlaceholder?.raw,
1480+
placeholder.raw,
1481+
unexpectedAfterPlaceholder?.raw
1482+
]
14631483
let raw = RawSyntax.makeLayout(
14641484
kind: SyntaxKind.editorPlaceholderDecl,
14651485
from: layout,
@@ -1473,7 +1493,7 @@ public struct EditorPlaceholderDeclSyntax: DeclSyntaxProtocol, SyntaxHashable {
14731493
self.init(data)
14741494
}
14751495

1476-
public var unexpectedBeforeIdentifier: UnexpectedNodesSyntax? {
1496+
public var unexpectedBeforeAttributes: UnexpectedNodesSyntax? {
14771497
get {
14781498
return data.child(at: 0, parent: Syntax(self)).map(UnexpectedNodesSyntax.init)
14791499
}
@@ -1482,16 +1502,36 @@ public struct EditorPlaceholderDeclSyntax: DeclSyntaxProtocol, SyntaxHashable {
14821502
}
14831503
}
14841504

1485-
public var identifier: TokenSyntax {
1505+
/// If there were attributes before the editor placeholder, the ``EditorPlaceholderDecl`` will contain these.
1506+
public var attributes: AttributeListSyntax? {
14861507
get {
1487-
return TokenSyntax(data.child(at: 1, parent: Syntax(self))!)
1508+
return data.child(at: 1, parent: Syntax(self)).map(AttributeListSyntax.init)
14881509
}
14891510
set(value) {
1490-
self = EditorPlaceholderDeclSyntax(data.replacingChild(at: 1, with: value.raw, arena: SyntaxArena()))
1511+
self = EditorPlaceholderDeclSyntax(data.replacingChild(at: 1, with: value?.raw, arena: SyntaxArena()))
14911512
}
14921513
}
14931514

1494-
public var unexpectedAfterIdentifier: UnexpectedNodesSyntax? {
1515+
/// Adds the provided `Attribute` to the node's `attributes`
1516+
/// collection.
1517+
/// - param element: The new `Attribute` to add to the node's
1518+
/// `attributes` collection.
1519+
/// - returns: A copy of the receiver with the provided `Attribute`
1520+
/// appended to its `attributes` collection.
1521+
public func addAttribute(_ element: Syntax) -> EditorPlaceholderDeclSyntax {
1522+
var collection: RawSyntax
1523+
let arena = SyntaxArena()
1524+
if let col = raw.layoutView!.children[1] {
1525+
collection = col.layoutView!.appending(element.raw, arena: arena)
1526+
} else {
1527+
collection = RawSyntax.makeLayout(kind: SyntaxKind.attributeList,
1528+
from: [element.raw], arena: arena)
1529+
}
1530+
let newData = data.replacingChild(at: 1, with: collection, arena: arena)
1531+
return EditorPlaceholderDeclSyntax(newData)
1532+
}
1533+
1534+
public var unexpectedBetweenAttributesAndModifiers: UnexpectedNodesSyntax? {
14951535
get {
14961536
return data.child(at: 2, parent: Syntax(self)).map(UnexpectedNodesSyntax.init)
14971537
}
@@ -1500,8 +1540,73 @@ public struct EditorPlaceholderDeclSyntax: DeclSyntaxProtocol, SyntaxHashable {
15001540
}
15011541
}
15021542

1543+
/// If there were modifiers before the editor placeholder, the `EditorPlaceholderDecl` will contain these.
1544+
public var modifiers: ModifierListSyntax? {
1545+
get {
1546+
return data.child(at: 3, parent: Syntax(self)).map(ModifierListSyntax.init)
1547+
}
1548+
set(value) {
1549+
self = EditorPlaceholderDeclSyntax(data.replacingChild(at: 3, with: value?.raw, arena: SyntaxArena()))
1550+
}
1551+
}
1552+
1553+
/// Adds the provided `Modifier` to the node's `modifiers`
1554+
/// collection.
1555+
/// - param element: The new `Modifier` to add to the node's
1556+
/// `modifiers` collection.
1557+
/// - returns: A copy of the receiver with the provided `Modifier`
1558+
/// appended to its `modifiers` collection.
1559+
public func addModifier(_ element: DeclModifierSyntax) -> EditorPlaceholderDeclSyntax {
1560+
var collection: RawSyntax
1561+
let arena = SyntaxArena()
1562+
if let col = raw.layoutView!.children[3] {
1563+
collection = col.layoutView!.appending(element.raw, arena: arena)
1564+
} else {
1565+
collection = RawSyntax.makeLayout(kind: SyntaxKind.modifierList,
1566+
from: [element.raw], arena: arena)
1567+
}
1568+
let newData = data.replacingChild(at: 3, with: collection, arena: arena)
1569+
return EditorPlaceholderDeclSyntax(newData)
1570+
}
1571+
1572+
public var unexpectedBetweenModifiersAndPlaceholder: UnexpectedNodesSyntax? {
1573+
get {
1574+
return data.child(at: 4, parent: Syntax(self)).map(UnexpectedNodesSyntax.init)
1575+
}
1576+
set(value) {
1577+
self = EditorPlaceholderDeclSyntax(data.replacingChild(at: 4, with: value?.raw, arena: SyntaxArena()))
1578+
}
1579+
}
1580+
1581+
/// The actual editor placeholder that starts with `<#` and ends with `#>`.
1582+
public var placeholder: TokenSyntax {
1583+
get {
1584+
return TokenSyntax(data.child(at: 5, parent: Syntax(self))!)
1585+
}
1586+
set(value) {
1587+
self = EditorPlaceholderDeclSyntax(data.replacingChild(at: 5, with: value.raw, arena: SyntaxArena()))
1588+
}
1589+
}
1590+
1591+
public var unexpectedAfterPlaceholder: UnexpectedNodesSyntax? {
1592+
get {
1593+
return data.child(at: 6, parent: Syntax(self)).map(UnexpectedNodesSyntax.init)
1594+
}
1595+
set(value) {
1596+
self = EditorPlaceholderDeclSyntax(data.replacingChild(at: 6, with: value?.raw, arena: SyntaxArena()))
1597+
}
1598+
}
1599+
15031600
public static var structure: SyntaxNodeStructure {
1504-
return .layout([\Self.unexpectedBeforeIdentifier, \Self.identifier, \Self.unexpectedAfterIdentifier])
1601+
return .layout([
1602+
\Self.unexpectedBeforeAttributes,
1603+
\Self.attributes,
1604+
\Self.unexpectedBetweenAttributesAndModifiers,
1605+
\Self.modifiers,
1606+
\Self.unexpectedBetweenModifiersAndPlaceholder,
1607+
\Self.placeholder,
1608+
\Self.unexpectedAfterPlaceholder
1609+
])
15051610
}
15061611
}
15071612

0 commit comments

Comments
 (0)