Skip to content

Commit e9d3460

Browse files
committed
Merge pull request swiftlang#1566 from kimdv/kimdv/fix-wrong-wrapping-of-quote-tokens
Fix for some wrong attribute fix its
1 parent 6ff8de4 commit e9d3460

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
@@ -483,7 +483,7 @@ extension Parser {
483483
// string literal.
484484
guard currentToken.leadingTriviaText.isEmpty else { break }
485485

486-
if let stringSegment = self.consume(if: .stringSegment) {
486+
if let stringSegment = self.consume(if: .stringSegment, TokenSpec(.identifier, remapping: .stringSegment)) {
487487
segments.append(.stringSegment(RawStringSegmentSyntax(content: stringSegment, arena: self.arena)))
488488
} else if let backslash = self.consume(if: .backslash) {
489489
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
@@ -893,6 +893,35 @@ public class ParseDiagnosticsGenerator: SyntaxAnyVisitor {
893893
return handleMissingSyntax(node, additionalHandledNodes: [node.placeholder.id])
894894
}
895895

896+
override open func visit(_ node: OriginallyDefinedInArgumentsSyntax) -> SyntaxVisitorContinueKind {
897+
if shouldSkip(node) {
898+
return .skipChildren
899+
}
900+
if let token = node.unexpectedBetweenModuleLabelAndColon?.onlyToken(where: { $0.tokenKind.isIdentifier }),
901+
node.moduleLabel.presence == .missing
902+
{
903+
addDiagnostic(
904+
node,
905+
MissingNodesError(missingNodes: [Syntax(node.moduleLabel)]),
906+
fixIts: [
907+
FixIt(
908+
message: ReplaceTokensFixIt(
909+
replaceTokens: [token],
910+
replacements: [node.moduleLabel]
911+
),
912+
changes: [
913+
FixIt.MultiNodeChange.makeMissing(token),
914+
FixIt.MultiNodeChange.makePresent(node.moduleLabel),
915+
]
916+
)
917+
],
918+
handledNodes: [node.moduleLabel.id, token.id]
919+
)
920+
}
921+
922+
return .visitChildren
923+
}
924+
896925
public override func visit(_ node: OperatorDeclSyntax) -> SyntaxVisitorContinueKind {
897926
if shouldSkip(node) {
898927
return .skipChildren
@@ -1191,6 +1220,36 @@ public class ParseDiagnosticsGenerator: SyntaxAnyVisitor {
11911220
return .visitChildren
11921221
}
11931222

1223+
public override func visit(_ node: UnavailableFromAsyncArgumentsSyntax) -> SyntaxVisitorContinueKind {
1224+
if shouldSkip(node) {
1225+
return .skipChildren
1226+
}
1227+
1228+
if let token = node.unexpectedBetweenMessageLabelAndColon?.onlyToken(where: { $0.tokenKind.isIdentifier }),
1229+
node.messageLabel.presence == .missing
1230+
{
1231+
addDiagnostic(
1232+
node,
1233+
MissingNodesError(missingNodes: [Syntax(node.messageLabel)]),
1234+
fixIts: [
1235+
FixIt(
1236+
message: ReplaceTokensFixIt(
1237+
replaceTokens: [token],
1238+
replacements: [node.messageLabel]
1239+
),
1240+
changes: [
1241+
FixIt.MultiNodeChange.makeMissing(token),
1242+
FixIt.MultiNodeChange.makePresent(node.messageLabel),
1243+
]
1244+
)
1245+
],
1246+
handledNodes: [node.messageLabel.id, token.id]
1247+
)
1248+
}
1249+
1250+
return .visitChildren
1251+
}
1252+
11941253
public override func visit(_ node: UnresolvedTernaryExprSyntax) -> SyntaxVisitorContinueKind {
11951254
if shouldSkip(node) {
11961255
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"),
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"),
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"),
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"),
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")
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")
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)