You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: Sources/SwiftParser/SwiftParser.docc/FixingBugs.md
+20-29
Original file line number
Diff line number
Diff line change
@@ -10,14 +10,13 @@ Once you’ve written a test case (see below), set a breakpoint in `Parser.parse
10
10
11
11
1. Add a new test case in `SwiftParserTest` that looks like the following
12
12
```swift
13
-
tryAssertParse({ $0.parseSourceFile() }) {
13
+
AssertParse(
14
14
"""
15
15
<#your code that does not round trip#>
16
16
"""
17
-
}
17
+
)
18
18
```
19
19
2. Run the test case, read the error message to figure out which part of the source file does not round-trip
20
-
3. Optional: Reduce the test case even further by deleting more source code and calling into a specific production of the parser instead of `Parser.parseSourceFile`
21
20
22
21
23
22
## Parse of Valid Source Failed
@@ -28,20 +27,14 @@ Diagnostics are produced when the parsed syntax tree contains missing or unexpec
28
27
29
28
1. Add a test casein `SwiftParserTest` that looks like the following
30
29
```swift
31
-
let source ="""
32
-
<#your code that produces an invalid syntax tree#>
33
-
"""
34
-
35
-
let tree =withParser(source: source) {
36
-
Syntax(raw: $0.parseSourceFile().raw)
37
-
}
38
-
XCTAssertHasSubstructure(
39
-
tree,
40
-
<#create a syntax node that you expect the tree to have#>
30
+
AssertParse(
31
+
"""
32
+
<#your code that produces an invalid syntax tree#>
33
+
""",
34
+
substructure: <#create a syntax node that you expect the tree to have#>
41
35
)
42
36
```
43
-
2. Optional: Reduce the test case even further by deleting more source code and calling into a specific production of the parser instead of `Parser.parseSourceFile`
44
-
3. Run the test case and navigate the debugger to the place that produced the invalid syntax node.
37
+
2. Run the test case and navigate the debugger to the place that produced the invalid syntax node.
45
38
46
39
## Unhelpful Diagnostic Produced
47
40
@@ -51,31 +44,29 @@ Unhelpful diagnostics can result from two reasons:
51
44
52
45
To distinguish these cases run the following command and look at the dumped syntax tree. Use your own judgment to decide whether this models the intended meaning of the source code reasonably well.
Fixing the first case where the parser does not recover according to the user’s intent is similar to [Parse of Valid Source Code Produced an Invalid Syntax Tree](#Parse-of-Valid-Source-Code-Produced-an-Invalid-Syntax-Tree). See <doc:SwiftParser/ParserRecovery> for documentation how parser recovery works and determine how to recover better from the invalid source code.
58
51
59
52
To add a new, more contextual diagnostic, perform the following steps.
60
53
61
-
1. Add a test case to `DiagnosticTests.swift` like the following:
54
+
1. Add a test case in `SwiftParserTest` that looks like the following
62
55
63
56
```swift
64
-
let source = """
65
-
<#your code that produces a bad diagnostic#>
66
-
}
67
-
"""
68
-
let loop = withParser(source: source) {
69
-
Syntax(raw: $0.parserSourceFile().raw)
70
-
}
57
+
AssertParse(
58
+
"""
59
+
<#your code that produced the unhelpful diagnostic#>
2. Optional: Call a more specific production than `parseSourceFile` in the test case.
66
+
2. Mark the location at which you expect the diagnostic to be produced with `#^DIAG^#`. If you expect multiple diagnostics to be produced, you can use multiple of these markers with different names and use these markers by passing a `locationMarker` to `DiagnosticSpec`.
73
67
3. Determine which node encompasses all information that is necessary to produce the improved diagnostic – for example `FunctionSignatureSyntax` contains all information to diagnose if the `throws` keyword was written after the `->` instead of in front of it.
74
68
4. If the diagnostic message you want to emit does not exist yet, add a case to <doc:SwiftParser/DiagnosticKind> for the new diagnostic.
75
69
5. If the function does not already exist, write a new visit method on <doc:SwiftParser/ParseDiagnosticsGenerator>.
76
70
6. In that visitation method, detect the pattern for which the improved diagnostic should be emitted and emit it using `diagnostics.append`.
77
71
7. Mark the missing or garbage nodes that are covered by the new diagnostic as handled by adding their `SyntaxIdentifier`s to `handledNodes`.
78
-
8. Assert that the new diagnostic is emitted by addding the following to your test case:
8. If the diagnostic produces Fix-Its assert that they are generated by adding the Fix-It's message to the `DiagnosticSpec` with the `fixIt` parameter and asserting that applying the Fix-Its produces the correct source code by adding the `fixedSource` parameter to `AssertParse`.
0 commit comments