Skip to content

Commit 8d5b3b6

Browse files
authored
Merge pull request #736 from ahoppen/ahoppen/unexpected-at-start-of-layout
Improve diagnostic message if unexpected tokens are found at the start of a layout node
2 parents 7eb77de + e605486 commit 8d5b3b6

File tree

6 files changed

+46
-38
lines changed

6 files changed

+46
-38
lines changed

Sources/SwiftParser/Diagnostics/ParserDiagnosticMessages.swift

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,20 @@ import SwiftSyntax
1616
let diagnosticDomain: String = "SwiftParser"
1717

1818
extension SyntaxProtocol {
19-
var nodeTypeNameForDiagnostics: String? {
19+
/// Return a name of this syntax node that can be used to describe it in
20+
/// diagnostics.
21+
/// Nodes that mostly exist for the syntax tree's structure and don't have a
22+
/// correspondence in the source code that's meeingful to the user by default
23+
/// use the name of the parent node that encloses it. Pass `false` to `inherit`
24+
/// to prevent this name inheritance.
25+
func nodeTypeNameForDiagnostics(inherit: Bool = true) -> String? {
2026
if let name = Syntax(self).as(SyntaxEnum.self).nameForDiagnostics {
2127
return name
2228
}
23-
if let parent = self.parent {
24-
return parent.nodeTypeNameForDiagnostics
29+
if inherit {
30+
if let parent = self.parent {
31+
return parent.nodeTypeNameForDiagnostics(inherit: inherit)
32+
}
2533
}
2634
return nil
2735
}
@@ -118,7 +126,7 @@ public struct MissingTokenError: ParserError {
118126
public let missingToken: TokenSyntax
119127

120128
public var message: String {
121-
guard let parent = missingToken.parent, let parentTypeName = parent.nodeTypeNameForDiagnostics else {
129+
guard let parent = missingToken.parent, let parentTypeName = parent.nodeTypeNameForDiagnostics() else {
122130
return "Expected '\(missingToken.text)'"
123131
}
124132
switch missingToken.tokenKind {
@@ -141,17 +149,17 @@ public struct UnexpectedNodesError: ParserError {
141149
public let unexpectedNodes: UnexpectedNodesSyntax
142150

143151
public var message: String {
144-
let parentTypeName = unexpectedNodes.parent?.nodeTypeNameForDiagnostics
145-
let shortContent = unexpectedNodes.contentForDiagnosticsIfShortSingleLine
146-
switch (parentTypeName, shortContent) {
147-
case (let parentTypeName?, let shortContent?):
148-
return "Unexpected text '\(shortContent)' found in \(parentTypeName)"
149-
case (let parentTypeName?, nil):
150-
return "Unexpected text found in \(parentTypeName)"
151-
case (nil, let shortContent?):
152-
return "Unexpected text '\(shortContent)'"
153-
case (nil, nil):
154-
return "Unexpected text"
152+
var message = "Unexpected text"
153+
if let shortContent = unexpectedNodes.contentForDiagnosticsIfShortSingleLine {
154+
message += " '\(shortContent)'"
155+
}
156+
if let parent = unexpectedNodes.parent {
157+
if let parentTypeName = parent.nodeTypeNameForDiagnostics(inherit: false), parent.children(viewMode: .sourceAccurate).first?.id == unexpectedNodes.id {
158+
message += " before \(parentTypeName)"
159+
} else if let parentTypeName = parent.nodeTypeNameForDiagnostics() {
160+
message += " in \(parentTypeName)"
161+
}
155162
}
163+
return message
156164
}
157165
}

Tests/SwiftParserTest/Declarations.swift

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ final class DeclarationTests: XCTestCase {
5151
func foo() {}
5252
""",
5353
diagnostics: [
54-
DiagnosticSpec(message: "Unexpected text '}' found in function")
54+
DiagnosticSpec(message: "Unexpected text '}' before function")
5555
]
5656
)
5757
}
@@ -115,7 +115,7 @@ final class DeclarationTests: XCTestCase {
115115
actor Foo {}
116116
""",
117117
diagnostics: [
118-
DiagnosticSpec(message: "Unexpected text '}' found in actor")
118+
DiagnosticSpec(message: "Unexpected text '}' before actor")
119119
]
120120
)
121121
}
@@ -417,7 +417,7 @@ final class DeclarationTests: XCTestCase {
417417
"(first second #^DIAG^#third fourth: Int)",
418418
{ $0.parseFunctionSignature() },
419419
diagnostics: [
420-
DiagnosticSpec(message: "Unexpected text 'third fourth' found in function parameter")
420+
DiagnosticSpec(message: "Unexpected text 'third fourth' in function parameter")
421421
]
422422
)
423423
}
@@ -559,7 +559,7 @@ final class DeclarationTests: XCTestCase {
559559
diagnostics: [
560560
DiagnosticSpec(
561561
message: """
562-
Unexpected text '/ ###line 25 "line-directive.swift"' found in struct
562+
Unexpected text '/ ###line 25 "line-directive.swift"' in struct
563563
"""
564564
)
565565
]
@@ -574,7 +574,7 @@ final class DeclarationTests: XCTestCase {
574574
}
575575
""",
576576
diagnostics: [
577-
DiagnosticSpec(message: "Unexpected text 'bogus rethrows set' found in variable")
577+
DiagnosticSpec(message: "Unexpected text 'bogus rethrows set' in variable")
578578
]
579579
)
580580
}
@@ -606,7 +606,7 @@ final class DeclarationTests: XCTestCase {
606606
trailingComma: nil
607607
)),
608608
diagnostics: [
609-
DiagnosticSpec(message: "Unexpected text 'third' found in function parameter")
609+
DiagnosticSpec(message: "Unexpected text 'third' in function parameter")
610610
]
611611
)
612612
}
@@ -627,7 +627,7 @@ final class DeclarationTests: XCTestCase {
627627
trailingComma: nil
628628
)),
629629
diagnostics: [
630-
DiagnosticSpec(message: "Unexpected text 'third fourth' found in function parameter")
630+
DiagnosticSpec(message: "Unexpected text 'third fourth' in function parameter")
631631
]
632632
)
633633
}
@@ -678,7 +678,7 @@ final class DeclarationTests: XCTestCase {
678678
trailingComma: nil
679679
)),
680680
diagnostics: [
681-
DiagnosticSpec(message: "Unexpected text '[third fourth]' found in function parameter")
681+
DiagnosticSpec(message: "Unexpected text '[third fourth]' in function parameter")
682682
]
683683
)
684684
}
@@ -703,7 +703,7 @@ final class DeclarationTests: XCTestCase {
703703
diagnostics: [
704704
DiagnosticSpec(locationMarker: "COLON", message: "Expected ':' in function parameter"),
705705
DiagnosticSpec(locationMarker: "END_ARRAY" , message: "Expected ']' to end array type"),
706-
DiagnosticSpec(locationMarker: "END_ARRAY", message: "Unexpected text 'fourth: Int' found in parameter clause")
706+
DiagnosticSpec(locationMarker: "END_ARRAY", message: "Unexpected text 'fourth: Int' in parameter clause")
707707
]
708708
)
709709
}

Tests/SwiftParserTest/Directives.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,8 @@ final class DirectiveTests: XCTestCase {
9292
#endif
9393
""",
9494
diagnostics: [
95-
DiagnosticSpec(locationMarker: "DIAG_1", message: "Unexpected text '}' found in conditional compilation clause"),
96-
DiagnosticSpec(locationMarker: "DIAG_2", message: "Unexpected text '}' found in conditional compilation block"),
95+
DiagnosticSpec(locationMarker: "DIAG_1", message: "Unexpected text '}' before conditional compilation clause"),
96+
DiagnosticSpec(locationMarker: "DIAG_2", message: "Unexpected text '}' in conditional compilation block"),
9797
]
9898
)
9999
}

Tests/SwiftParserTest/Expressions.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ final class ExpressionTests: XCTestCase {
203203
" >> \( abc #^DIAG^#} ) << "
204204
"""#,
205205
diagnostics: [
206-
DiagnosticSpec(message: "Unexpected text '}' found in string literal")
206+
DiagnosticSpec(message: "Unexpected text '}' in string literal")
207207
]
208208
)
209209

@@ -426,7 +426,7 @@ final class ExpressionTests: XCTestCase {
426426
"[(Int) -> #^DIAG^#throws Int]()",
427427
diagnostics: [
428428
// FIXME: We should suggest to move 'throws' in front of '->'
429-
DiagnosticSpec(message: "Unexpected text 'throws Int' found in array")
429+
DiagnosticSpec(message: "Unexpected text 'throws Int' in array")
430430
]
431431
)
432432

@@ -456,7 +456,7 @@ final class ExpressionTests: XCTestCase {
456456
let :(#^DIAG_1^#..)->
457457
""",
458458
diagnostics: [
459-
DiagnosticSpec(locationMarker: "DIAG_1", message: "Unexpected text '..' found in function type"),
459+
DiagnosticSpec(locationMarker: "DIAG_1", message: "Unexpected text '..' in function type"),
460460
]
461461
)
462462
}

Tests/SwiftParserTest/Statements.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ final class StatementTests: XCTestCase {
3030
""",
3131
diagnostics: [
3232
DiagnosticSpec(message: "Expected '=' in pattern matching"),
33-
DiagnosticSpec(message: "Unexpected text '* ! = x' found in 'if' statement"),
33+
DiagnosticSpec(message: "Unexpected text '* ! = x' in 'if' statement"),
3434
]
3535
)
3636
}
@@ -174,8 +174,8 @@ final class StatementTests: XCTestCase {
174174
}
175175
""",
176176
diagnostics: [
177-
DiagnosticSpec(locationMarker: "TEST_1", message: "Unexpected text '@s return' found in function"),
178-
DiagnosticSpec(locationMarker: "TEST_2", message: "Unexpected text '@unknown return' found in function")
177+
DiagnosticSpec(locationMarker: "TEST_1", message: "Unexpected text '@s return' in function"),
178+
DiagnosticSpec(locationMarker: "TEST_2", message: "Unexpected text '@unknown return' in function")
179179
]
180180
)
181181
}
@@ -193,8 +193,8 @@ final class StatementTests: XCTestCase {
193193
}
194194
""",
195195
diagnostics: [
196-
DiagnosticSpec(locationMarker: "FOO", message: "Unexpected text 'foo()' found in conditional compilation clause"),
197-
DiagnosticSpec(locationMarker: "BAR", message: "Unexpected text 'bar()' found in conditional compilation block"),
196+
DiagnosticSpec(locationMarker: "FOO", message: "Unexpected text 'foo()' before conditional compilation clause"),
197+
DiagnosticSpec(locationMarker: "BAR", message: "Unexpected text 'bar()' in conditional compilation block"),
198198
]
199199
)
200200

@@ -213,7 +213,7 @@ final class StatementTests: XCTestCase {
213213
}
214214
""",
215215
diagnostics: [
216-
DiagnosticSpec(message: "Unexpected text 'print()' found in conditional compilation clause")
216+
DiagnosticSpec(message: "Unexpected text 'print()' before conditional compilation clause")
217217
]
218218
)
219219
}

Tests/SwiftParserTest/Types.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ final class TypeTests: XCTestCase {
2929

3030
func testFunctionTypes() throws {
3131
AssertParse("t as(#^DIAG^#..)->", diagnostics: [
32-
DiagnosticSpec(message: "Unexpected text '..' found in function type")
32+
DiagnosticSpec(message: "Unexpected text '..' in function type")
3333
])
3434
}
3535

@@ -49,14 +49,14 @@ final class TypeTests: XCTestCase {
4949
{ $0.parseClosureExpression() },
5050
diagnostics: [
5151
DiagnosticSpec(locationMarker: "DIAG_1", message: "Expected '' in closure capture item"),
52-
DiagnosticSpec(locationMarker: "DIAG_1", message: "Unexpected text 'class' found in closure capture signature"),
52+
DiagnosticSpec(locationMarker: "DIAG_1", message: "Unexpected text 'class' in closure capture signature"),
5353
DiagnosticSpec(locationMarker: "DIAG_2", message: "Expected '}' to end closure"),
5454
])
5555

5656
AssertParse("{[n#^DIAG^#`]in}",
5757
{ $0.parseClosureExpression() },
5858
diagnostics: [
59-
DiagnosticSpec(message: "Unexpected text '`' found in closure capture signature")
59+
DiagnosticSpec(message: "Unexpected text '`' in closure capture signature")
6060
])
6161
}
6262
}

0 commit comments

Comments
 (0)