Skip to content

Commit ab6c314

Browse files
committed
Improve sorting of diagnostics at MissingDeclaration
Resolves rdar://100214284 Fixes #823
1 parent 0d39242 commit ab6c314

File tree

3 files changed

+28
-5
lines changed

3 files changed

+28
-5
lines changed

Sources/SwiftParser/Diagnostics/ParseDiagnosticsGenerator.swift

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,19 @@ extension UnexpectedNodesSyntax {
2323
}
2424
}
2525

26+
extension Syntax {
27+
func hasParent(_ expectedParent: Syntax) -> Bool {
28+
var walk = self.parent
29+
while walk != nil {
30+
if walk == expectedParent {
31+
return true
32+
}
33+
walk = walk?.parent
34+
}
35+
return false
36+
}
37+
}
38+
2639
fileprivate extension FixIt.Change {
2740
/// Replaced a present node with a missing node
2841
static func makeMissing(node: TokenSyntax) -> FixIt.Change {
@@ -59,7 +72,17 @@ public class ParseDiagnosticsGenerator: SyntaxAnyVisitor {
5972
let diagProducer = ParseDiagnosticsGenerator()
6073
diagProducer.walk(tree)
6174
diagProducer.diagnostics.sort {
62-
return $0.node.id.indexInTree < $1.node.id.indexInTree
75+
if $0.position == $1.position {
76+
if $0.node.hasParent($1.node) {
77+
return true
78+
} else if $1.node.hasParent($0.node) {
79+
return false
80+
} else {
81+
return $0.node.id.indexInTree < $1.node.id.indexInTree
82+
}
83+
} else {
84+
return $0.position < $1.position
85+
}
6386
}
6487
return diagProducer.diagnostics
6588
}

Tests/SwiftParserTest/Attributes.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@ final class AttributeTests: XCTestCase {
1111
}
1212
""",
1313
diagnostics: [
14-
DiagnosticSpec(locationMarker: "DIAG_2", message: "Expected declaration after attribute"),
1514
DiagnosticSpec(locationMarker: "DIAG_1", message: "Expected 'for' in attribute argument"),
1615
DiagnosticSpec(locationMarker: "DIAG_1", message: "Expected ':' in attribute argument"),
1716
DiagnosticSpec(locationMarker: "DIAG_2", message: "Expected ')' to end attribute"),
17+
DiagnosticSpec(locationMarker: "DIAG_2", message: "Expected declaration after attribute"),
1818
]
1919
)
2020
}
@@ -42,9 +42,9 @@ final class AttributeTests: XCTestCase {
4242
@_specialize(e#^DIAG^#
4343
""",
4444
diagnostics: [
45-
DiagnosticSpec(message: "Expected declaration after attribute"),
4645
DiagnosticSpec(message: "Expected ':' in attribute argument"),
4746
DiagnosticSpec(message: "Expected ')' to end attribute"),
47+
DiagnosticSpec(message: "Expected declaration after attribute"),
4848
]
4949
)
5050
}
@@ -55,10 +55,10 @@ final class AttributeTests: XCTestCase {
5555
@_specialize(e#^DIAG_1^#, exported#^DIAG_2^#)#^DIAG_3^#
5656
""",
5757
diagnostics: [
58-
DiagnosticSpec(locationMarker: "DIAG_3", message: "Expected declaration after attribute"),
5958
DiagnosticSpec(locationMarker: "DIAG_1", message: "Expected ':' in attribute argument"),
6059
DiagnosticSpec(locationMarker: "DIAG_2", message: "Expected ':' in attribute argument"),
6160
DiagnosticSpec(locationMarker: "DIAG_2", message: "Expected 'false' in attribute argument"),
61+
DiagnosticSpec(locationMarker: "DIAG_3", message: "Expected declaration after attribute"),
6262
]
6363
)
6464
}

Tests/SwiftParserTest/Declarations.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -904,8 +904,8 @@ final class DeclarationTests: XCTestCase {
904904
diagnostics: [
905905
DiagnosticSpec(locationMarker: "OPENING_BRACE", message: "Expected '{' to start struct"),
906906
DiagnosticSpec(locationMarker: "AFTER_POUND_IF", message: "Expected condition of conditional compilation clause"),
907-
DiagnosticSpec(locationMarker: "END", message: "Expected declaration after attribute in conditional compilation clause"),
908907
DiagnosticSpec(locationMarker: "END", message: "Expected name of attribute"),
908+
DiagnosticSpec(locationMarker: "END", message: "Expected declaration after attribute in conditional compilation clause"),
909909
DiagnosticSpec(locationMarker: "END", message: "Expected '#endif' in conditional compilation block"),
910910
DiagnosticSpec(locationMarker: "END", message: "Expected '}' to end struct")
911911
]

0 commit comments

Comments
 (0)