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