Skip to content

Commit 2e92078

Browse files
committed
[PaserDiagnostics] Improve '#if is not allowed' diagnostics
'#if' and '#endif' can be in the same node
1 parent fc00a5c commit 2e92078

File tree

2 files changed

+58
-23
lines changed

2 files changed

+58
-23
lines changed

Sources/SwiftParserDiagnostics/ParseDiagnosticsGenerator.swift

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -482,21 +482,36 @@ public class ParseDiagnosticsGenerator: SyntaxAnyVisitor {
482482
otherNode.lastToken(viewMode: .sourceAccurate)?.tokenKind == .poundEndif
483483
{
484484
let diagnoseOn = parent.parent ?? parent
485-
addDiagnostic(
486-
diagnoseOn,
487-
IfConfigDeclNotAllowedInContext(context: diagnoseOn),
488-
highlights: [Syntax(node), Syntax(otherNode)],
489-
fixIts: [
490-
FixIt(
491-
message: RemoveNodesFixIt([Syntax(node), Syntax(otherNode)]),
492-
changes: [
493-
.makeMissing([Syntax(node)], transferTrivia: false),
494-
.makeMissing([Syntax(otherNode)], transferTrivia: false),
495-
]
496-
)
497-
],
498-
handledNodes: [node.id, otherNode.id]
499-
)
485+
if node == otherNode {
486+
addDiagnostic(
487+
diagnoseOn,
488+
IfConfigDeclNotAllowedInContext(context: diagnoseOn),
489+
highlights: [Syntax(node)],
490+
fixIts: [
491+
FixIt(
492+
message: RemoveNodesFixIt([Syntax(node)]),
493+
changes: .makeMissing([Syntax(node)], transferTrivia: false),
494+
)
495+
],
496+
handledNodes: [node.id]
497+
)
498+
} else {
499+
addDiagnostic(
500+
diagnoseOn,
501+
IfConfigDeclNotAllowedInContext(context: diagnoseOn),
502+
highlights: [Syntax(node), Syntax(otherNode)],
503+
fixIts: [
504+
FixIt(
505+
message: RemoveNodesFixIt([Syntax(node), Syntax(otherNode)]),
506+
changes: [
507+
.makeMissing([Syntax(node)], transferTrivia: false),
508+
.makeMissing([Syntax(otherNode)], transferTrivia: false),
509+
]
510+
)
511+
],
512+
handledNodes: [node.id, otherNode.id]
513+
)
514+
}
500515
} else {
501516
addDiagnostic(node, UnexpectedNodesError(unexpectedNodes: node), highlights: [Syntax(node)])
502517
}

Tests/SwiftParserTest/AttributeTests.swift

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1402,15 +1402,35 @@ final class AttributeTests: ParserTestCase {
14021402
}
14031403

14041404
func testAttributeParsable() {
1405-
let source = """
1406-
#if true
1405+
assertParse(
1406+
"""
1407+
1️⃣#if true
14071408
@discardableResult
14081409
#endif
1409-
"""
1410-
var parser = Parser(source)
1411-
let attr = AttributeSyntax.parse(from: &parser)
1412-
1413-
XCTAssertTrue(attr.description == source)
1414-
XCTAssertTrue(attr.tokens(viewMode: .fixedUp).allSatisfy({ $0.presence == .missing }))
1410+
""",
1411+
{ AttributeSyntax.parse(from: &$0) },
1412+
substructure: AttributeSyntax(
1413+
atSign: .atSignToken(presence: .missing),
1414+
attributeName: TypeSyntax(MissingTypeSyntax(placeholder: .identifier("<#type#>", presence: .missing))),
1415+
UnexpectedNodesSyntax([
1416+
TokenSyntax.poundIfToken(),
1417+
TokenSyntax.keyword(.true),
1418+
TokenSyntax.atSignToken(),
1419+
TokenSyntax.identifier("discardableResult"),
1420+
TokenSyntax.poundEndifToken(),
1421+
])
1422+
),
1423+
diagnostics: [
1424+
DiagnosticSpec(message: "expected '@' and name in attribute", fixIts: ["insert '@' and name"]),
1425+
DiagnosticSpec(message: "conditional compilation not permitted in attribute", fixIts: ["""
1426+
remove '#if true
1427+
@discardableResult
1428+
#endif'
1429+
"""])
1430+
],
1431+
fixedSource: """
1432+
@<#type#>
1433+
"""
1434+
)
14151435
}
14161436
}

0 commit comments

Comments
 (0)