Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(408)

Side by Side Diff: pkg/analyzer_plugin/doc/tutorial/fixes.md

Issue 2973753003: Initial documentation for the plugin package (Closed)
Patch Set: Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 # Providing Quick Fixes
2
3 A quick fix is used by clients to provide a set of possible changes to code that
4 are based on diagnostics reported against the code. Quick fixes are intended to
5 help users resolve the issue being reported.
6
7 If your plugin generates any diagnostics then you should consider providing
8 support for automatically fixing those diagnostics. There is often more than one
9 potential way of fixing a given problem, so it is possible for your plugin to
10 provide multiple fixes for a single problem.
11
12 For example, if an undefined identifier is used in the code, you might return
13 a fix to create an appropriate definition for the identifier. If there is a
14 similar identifier that is already defined, you might also return a second fix
15 to replace the undefined identifier with the defined identifier.
16
17 The latter example illustrates that fixes can be conditionally returned. You
18 will produce a better UX if only those fixes that actually make sense in the
19 given context are returned. If a lot of work is required to determine which
20 fixes make sense, it is possible to improve performance by generating different
21 diagnostics for the same issue, depending on the context in which the issue
22 occurs.
23
24 In addition, fixes have a priority associated with them. The priority allows the
25 client to display the fixes that are most likely to be of use closer to the top
26 of the list when there are multiple fixes available.
27
28 ## Implementation details
29
30 When appropriate, the analysis server will send your plugin an `edit.getFixes`
31 request. The request includes the `file` and `offset` associated with the
32 diagnostics for which fixes should be generated. Fixes are typically produced
33 for all of the diagnostics on a given line of code. Your plugin should only
34 return fixes associated with the errors that it produced earlier.
35
36 When an `edit.getFixes` request is received, the method `handleEditGetFixes`
37 will be invoked. This method is responsible for returning a response that
38 contains the available fixes.
39
40 The easiest way to implement this method is by adding the classes `FixesMixin`
41 and `DartFixesMixin` (from `package:analyzer_plugin/plugin/fix_mixin.dart`) to
42 the list of mixins for your subclass of `ServerPlugin`. This will leave you with
43 one abstract method that you need to implement: `getFixContributors`. That
44 method is responsible for returning a list of `FixContributor`s. It is the fix
45 contributors that produce the actual fixes. (Most plugins will only need a
46 single fix contributor.)
47
48 To write a fix contributor, create a class that implements `FixContributor`. The
49 interface defines a single method named `computeFixes`. The method has two
50 arguments: a `FixesRequest` that describes the errors that should be fixed and a
51 `FixCollector` through which fixes are to be added. (If you use the mixins above
52 then the list of errors available through the request object will only include
53 the errors for which fixes should be returned.)
54
55 The class `FixContributorMixin` defines a simple implementation of this method
56 that captures the two arguments in fields, iterates through the errors, and
57 invokes a method named `computeFixesForError` for each of the errors for which
58 fixes are to be computed.
59
60 ## Example
61
62 Start by creating a class that implements `FixContributor` and that mixes in the
63 class `FixContributorMixin`, then implement the method `computeFixesForError`.
64 This method is typically implemented by a series of `if` statements that test
65 the error code and invoke individual methods that compute the actual fixes to be
66 proposed. (In addition to keeping the method `computeFixesForError` shorter,
67 this also allows some fixes to be used for multiple error codes.)
68
69 To learn about the support available for creating the edits, see
70 [Creating Edits][creatingEdits].
71
72 For example, your contributor might look something like the following:
73
74 ```dart
75 class MyFixContributor extends Object
76 with FixContributorMixin
77 implements FixContributor {
78 static FixKind defineComponent =
79 new FixKind('defineComponent', 100, "Define a component named {0}");
80
81 AnalysisSession get session => request.result.session;
82
83 @override
84 void computeFixesForError(AnalysisError error) {
85 ErrorCode code = error.errorCode;
86 if (code == MyErrorCode.undefinedComponent) {
87 _defineComponent(error);
88 _useExistingComponent(error);
89 }
90 }
91
92 void _defineComponent(AnalysisError error) {
93 // TODO Get the name from the source code.
94 String componentName = null;
95 ChangeBuilder builder = new DartChangeBuilder(session);
96 // TODO Build the edit to insert the definition of the component.
97 addFix(error, defineComponent, builder, args: [componentName]);
98 }
99
100 void _useExistingComponent(AnalysisError error) {
101 // ...
102 }
103 }
104 ```
105
106 Given a contributor like the one above, you can implement your plugin similar to
107 the following:
108
109 ```dart
110 class MyPlugin extends ServerPlugin with FixesMixin, DartFixesMixin {
111 // ...
112
113 @override
114 List<FixContributor> getFixContributors(
115 covariant AnalysisDriverGeneric driver) {
116 return <FixContributor>[new MyFixContributor()];
117 }
118 }
119 ```
120
121 [creatingEdits]: creating_edits.md
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698