Skip to content

Commit cef8815

Browse files
authored
Merge pull request #1566 from kimdv/kimdv/fix-wrong-wrapping-of-quote-tokens
Fix for some wrong attribute fix its
2 parents 8ddbb9a + bb57360 commit cef8815

File tree

4 files changed

+141
-20
lines changed

4 files changed

+141
-20
lines changed

Sources/SwiftParser/StringLiterals.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -487,7 +487,7 @@ extension Parser {
487487
// string literal.
488488
guard currentToken.leadingTriviaText.isEmpty else { break }
489489

490-
if let stringSegment = self.consume(if: .stringSegment) {
490+
if let stringSegment = self.consume(if: .stringSegment, TokenSpec(.identifier, remapping: .stringSegment)) {
491491
segments.append(.stringSegment(RawStringSegmentSyntax(content: stringSegment, arena: self.arena)))
492492
} else if let backslash = self.consume(if: .backslash) {
493493
let (unexpectedBeforeDelimiter, delimiter) = self.parsePoundDelimiter(.rawStringDelimiter, matching: openDelimiter)

Sources/SwiftParserDiagnostics/ParseDiagnosticsGenerator.swift

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -993,6 +993,35 @@ public class ParseDiagnosticsGenerator: SyntaxAnyVisitor {
993993
return handleMissingSyntax(node, additionalHandledNodes: [node.placeholder.id])
994994
}
995995

996+
override open func visit(_ node: OriginallyDefinedInArgumentsSyntax) -> SyntaxVisitorContinueKind {
997+
if shouldSkip(node) {
998+
return .skipChildren
999+
}
1000+
if let token = node.unexpectedBetweenModuleLabelAndColon?.onlyToken(where: { $0.tokenKind.isIdentifier }),
1001+
node.moduleLabel.presence == .missing
1002+
{
1003+
addDiagnostic(
1004+
node,
1005+
MissingNodesError(missingNodes: [Syntax(node.moduleLabel)]),
1006+
fixIts: [
1007+
FixIt(
1008+
message: ReplaceTokensFixIt(
1009+
replaceTokens: [token],
1010+
replacements: [node.moduleLabel]
1011+
),
1012+
changes: [
1013+
FixIt.MultiNodeChange.makeMissing(token),
1014+
FixIt.MultiNodeChange.makePresent(node.moduleLabel),
1015+
]
1016+
)
1017+
],
1018+
handledNodes: [node.moduleLabel.id, token.id]
1019+
)
1020+
}
1021+
1022+
return .visitChildren
1023+
}
1024+
9961025
public override func visit(_ node: OperatorDeclSyntax) -> SyntaxVisitorContinueKind {
9971026
if shouldSkip(node) {
9981027
return .skipChildren
@@ -1347,6 +1376,36 @@ public class ParseDiagnosticsGenerator: SyntaxAnyVisitor {
13471376
return .visitChildren
13481377
}
13491378

1379+
public override func visit(_ node: UnavailableFromAsyncArgumentsSyntax) -> SyntaxVisitorContinueKind {
1380+
if shouldSkip(node) {
1381+
return .skipChildren
1382+
}
1383+
1384+
if let token = node.unexpectedBetweenMessageLabelAndColon?.onlyToken(where: { $0.tokenKind.isIdentifier }),
1385+
node.messageLabel.presence == .missing
1386+
{
1387+
addDiagnostic(
1388+
node,
1389+
MissingNodesError(missingNodes: [Syntax(node.messageLabel)]),
1390+
fixIts: [
1391+
FixIt(
1392+
message: ReplaceTokensFixIt(
1393+
replaceTokens: [token],
1394+
replacements: [node.messageLabel]
1395+
),
1396+
changes: [
1397+
FixIt.MultiNodeChange.makeMissing(token),
1398+
FixIt.MultiNodeChange.makePresent(node.messageLabel),
1399+
]
1400+
)
1401+
],
1402+
handledNodes: [node.messageLabel.id, token.id]
1403+
)
1404+
}
1405+
1406+
return .visitChildren
1407+
}
1408+
13501409
public override func visit(_ node: UnresolvedTernaryExprSyntax) -> SyntaxVisitorContinueKind {
13511410
if shouldSkip(node) {
13521411
return .skipChildren

Tests/SwiftParserTest/AttributeTests.swift

Lines changed: 37 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -422,12 +422,23 @@ final class AttributeTests: XCTestCase {
422422

423423
assertParse(
424424
"""
425-
@_expose(Cxx, 1️⃣baz) func foo() {}
425+
@_expose(Cxx, 1️⃣baz2️⃣) func foo() {}
426426
""",
427427
diagnostics: [
428-
DiagnosticSpec(message: "expected string literal to end @_expose arguments", fixIts: ["insert string literal"]),
429-
DiagnosticSpec(message: "unexpected code 'baz' in attribute"),
430-
]
428+
DiagnosticSpec(
429+
locationMarker: "1️⃣",
430+
message: #"expected '"' in string literal"#,
431+
fixIts: [#"insert '"'"#]
432+
),
433+
DiagnosticSpec(
434+
locationMarker: "2️⃣",
435+
message: #"expected '"' to end string literal"#,
436+
fixIts: [#"insert '"'"#]
437+
),
438+
],
439+
fixedSource: """
440+
@_expose(Cxx, "baz") func foo() {}
441+
"""
431442
)
432443
}
433444

@@ -475,9 +486,12 @@ final class AttributeTests: XCTestCase {
475486
func foo() {}
476487
""",
477488
diagnostics: [
478-
DiagnosticSpec(message: "expected 'message' in @_unavailableFromAsync argument", fixIts: ["insert 'message'"]),
479-
DiagnosticSpec(message: "unexpected code 'nope' before @_unavailableFromAsync argument"),
480-
]
489+
DiagnosticSpec(message: "expected 'message' in @_unavailableFromAsync argument", fixIts: ["replace 'nope' with 'message'"])
490+
],
491+
fixedSource: """
492+
@_unavailableFromAsync(message: "abc")
493+
func foo() {}
494+
"""
481495
)
482496

483497
assertParse(
@@ -493,13 +507,25 @@ final class AttributeTests: XCTestCase {
493507

494508
assertParse(
495509
"""
496-
@_unavailableFromAsync(message: 1️⃣abc)
510+
@_unavailableFromAsync(message: 1️⃣abc2️⃣)
497511
func foo() {}
498512
""",
499513
diagnostics: [
500-
DiagnosticSpec(message: "expected string literal to end @_unavailableFromAsync argument", fixIts: ["insert string literal"]),
501-
DiagnosticSpec(message: "unexpected code 'abc' in attribute"),
502-
]
514+
DiagnosticSpec(
515+
locationMarker: "1️⃣",
516+
message: #"expected '"' in string literal"#,
517+
fixIts: [#"insert '"'"#]
518+
),
519+
DiagnosticSpec(
520+
locationMarker: "2️⃣",
521+
message: #"expected '"' to end string literal"#,
522+
fixIts: [#"insert '"'"#]
523+
),
524+
],
525+
fixedSource: """
526+
@_unavailableFromAsync(message: "abc")
527+
func foo() {}
528+
"""
503529
)
504530
}
505531

Tests/SwiftParserTest/translated/OriginalDefinedInAttrTests.swift

Lines changed: 44 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,15 @@ final class OriginalDefinedInAttrTests: XCTestCase {
3131
public func foo1() {}
3232
"""#,
3333
diagnostics: [
34-
DiagnosticSpec(message: "expected 'module' in @_originallyDefinedIn arguments", fixIts: ["insert 'module'"]),
35-
DiagnosticSpec(message: "unexpected code 'modulename' before @_originallyDefinedIn arguments"),
36-
]
34+
DiagnosticSpec(
35+
message: "expected 'module' in @_originallyDefinedIn arguments",
36+
fixIts: ["replace 'modulename' with 'module'"]
37+
)
38+
],
39+
fixedSource: #"""
40+
@_originallyDefinedIn(module: "foo", OSX 13.13)
41+
public func foo1() {}
42+
"""#
3743
)
3844
}
3945

@@ -53,20 +59,51 @@ final class OriginalDefinedInAttrTests: XCTestCase {
5359
public class ToplevelClass1 {}
5460
"""#,
5561
diagnostics: [
56-
DiagnosticSpec(locationMarker: "1️⃣", message: "expected ',' and version list in @_originallyDefinedIn arguments", fixIts: ["insert ',' and version list"])
62+
DiagnosticSpec(
63+
message: "expected ',' and version list in @_originallyDefinedIn arguments",
64+
fixIts: ["insert ',' and version list"]
65+
)
5766
]
5867
)
5968
}
6069

6170
func testOriginalDefinedInAttr5() {
6271
assertParse(
6372
"""
64-
@_originallyDefinedIn(1️⃣OSX 13.13.3)
73+
@_originallyDefinedIn(1️⃣OSX 2️⃣13.13.3)
6574
public class ToplevelClass2 {}
6675
""",
6776
diagnostics: [
68-
DiagnosticSpec(message: "expected 'module:', string literal, and ',' in @_originallyDefinedIn arguments", fixIts: ["insert 'module:', string literal, and ','"])
69-
]
77+
DiagnosticSpec(
78+
locationMarker: "1️⃣",
79+
message: "expected 'module:' in @_originallyDefinedIn arguments",
80+
fixIts: ["insert 'module:'"]
81+
),
82+
DiagnosticSpec(
83+
locationMarker: "1️⃣",
84+
message: #"expected '"' in string literal"#,
85+
fixIts: [#"insert '"'"#]
86+
),
87+
DiagnosticSpec(
88+
locationMarker: "2️⃣",
89+
message: #"expected '"' to end string literal"#,
90+
fixIts: [#"insert '"'"#]
91+
),
92+
DiagnosticSpec(
93+
locationMarker: "2️⃣",
94+
message: "expected ',' in @_originallyDefinedIn arguments",
95+
fixIts: ["insert ','"]
96+
),
97+
DiagnosticSpec(
98+
locationMarker: "2️⃣",
99+
message: "expected platform in version restriction",
100+
fixIts: ["insert platform"]
101+
),
102+
],
103+
fixedSource: """
104+
@_originallyDefinedIn(module: "OSX", <#identifier#> 13.13.3)
105+
public class ToplevelClass2 {}
106+
"""
70107
)
71108
}
72109

@@ -172,5 +209,4 @@ final class OriginalDefinedInAttrTests: XCTestCase {
172209
"""
173210
)
174211
}
175-
176212
}

0 commit comments

Comments
 (0)