1# Suggested Fixes in the Analysis Framework 2 3## The Purpose of Suggested Fixes 4 5The analysis framework is planned to add a facility to output 6suggested fixes. Suggested fixes in the analysis framework 7are meant to address two common use cases. The first is the 8natural use case of allowing the user to quickly fix errors or issues 9pointed out by analyzers through their editor or analysis tool. 10An editor, when showing a diagnostic for an issue, can propose 11code to fix that issue. Users can accept the proposal and have 12the editor apply the fix for them. The second case is to allow 13for defining refactorings. An analyzer meant to perform a 14refactoring can produce suggested fixes equivalent to the diff 15of the refactoring. Then, an analysis driver meant to apply 16refactorings can automatically apply all the diffs that 17are produced by the analysis as suggested fixes. 18 19## Proposed Suggested Fix API 20 21Suggested fixes will be defined using the following structs: 22 23```go 24// A SuggestedFix is a code change associated with a Diagnostic that a user can choose 25// to apply to their code. Usually the SuggestedFix is meant to fix the issue flagged 26// by the diagnostic. 27type SuggestedFix struct { 28 // A description for this suggested fix to be shown to a user deciding 29 // whether to accept it. 30 Message string 31 TextEdits []TextEdit 32} 33 34// A TextEdit represents the replacement of the code between Pos and End with the new text. 35type TextEdit struct { 36 // For a pure insertion, End can either be set to Pos or token.NoPos. 37 Pos token.Pos 38 End token.Pos 39 NewText []byte 40} 41``` 42 43A suggested fix needs a message field so it can specify what it will do. 44Some analyses may not have clear cut fixes, and a suggested fix may need 45to provide additional information to help users specify whether they 46should be added. 47 48Suggested fixes are allowed to make multiple 49edits in a file, because some logical changes may affect otherwise 50unrelated parts of the AST. 51 52A TextEdit specifies a Pos and End: these will usually be the Pos 53and End of an AST node that will be replaced. 54 55Finally, the replacements themselves are represented as []bytes. 56 57 58Suggested fixes themselves will be added as a field in the 59Diagnostic struct: 60 61```go 62 63type Diagnostic struct { 64 ... 65 SuggestedFixes []SuggestedFix // this is an optional field 66} 67 68``` 69 70### Requirements for SuggestedFixes 71 72SuggestedFixes will be required to conform to several requirements: 73 74* TextEdits for a SuggestedFix should not overlap. 75* TextEdits for SuggestedFixes should not contain edits for other packages. 76* Each TextEdit should apply to a single file. 77 78These requirements guarantee that suggested fixes can be cleanly applied. 79Because a driver may only analyze, or be able to modify, the current package, 80we restrict edits to the current package. In general this restriction should 81not be a big problem for users because other packages might not belong to the 82same module and so will not be safe to modify in a singe change. 83 84On the other hand, analyzers will not be required to produce gofmt-compliant 85code. Analysis drivers will be expected to apply gofmt to the results of 86a SuggestedFix application. 87 88## SuggestedFix integration points 89 90### ```checker -fix``` 91 92Singlechecker and multichecker have the ```-fix``` flag, which will automatically 93apply all fixes suggested by their analysis or analyses. This is intended to 94be used primarily by refactoring tools, because in general, like diagnostics, 95suggested fixes will need to be examined by a human who can decide whether 96they are relevent. 97 98### gopls 99 100Suggested fixes have been integrated into ```gopls```, and editors can choose 101to display the suggested fixes to the user as they type, so that they can be 102accepted to fix diagnostics immediately. 103 104### Code Review Tools (Future Work) 105 106Suggested fixes can be integrated into programs that are integrated with 107code review systems to suggest fixes that users can apply from their code review tools. 108 109## Alternatives 110 111### Performing transformations directly on the AST 112 113Even though it may be more convenient 114for authors of refactorings to perform transformations directly on 115the AST, allowing mutations on the AST would mean that a copy of the AST 116would need to be made every time a transformation was produced, to avoid 117having transformations interfere with each other. 118 119This is primarily an issue with the current design of the Go AST and 120it's possible that a new future version of the AST might make this a more 121viable option. 122 123### Supplying AST nodes directly 124 125Another possibility would be for SuggestedFixes to supply the replacement 126ASTs directly. There is one primary limitation to this: that because 127comments to ASTs specify their location using token.Pos values, it's very 128difficult to place any comments in the right place. 129 130In general, it's also more difficult to generate the AST structures for 131some code than to generate the text for that code. So we prefer to allow 132the flexibility to do the latter. 133 134Because users can call ```format.Node``` to produce the text for any 135AST node, users will always be able to produce a SuggestedFix from AST 136nodes. In future, we may choose to add a convenience method that does this for users. 137