1==========================
2Clang's refactoring engine
3==========================
4
5This document describes the design of Clang's refactoring engine and provides
6a couple of examples that show how various primitives in the refactoring API
7can be used to implement different refactoring actions. The :doc:`LibTooling`
8library provides several other APIs that are used when developing a
9refactoring action.
10
11Refactoring engine can be used to implement local refactorings that are
12initiated using a selection in an editor or an IDE. You can combine
13:doc:`AST matchers<LibASTMatchers>` and the refactoring engine to implement
14refactorings that don't lend themselves well to source selection and/or have to
15query ASTs for some particular nodes.
16
17We assume basic knowledge about the Clang AST. See the :doc:`Introduction
18to the Clang AST <IntroductionToTheClangAST>` if you want to learn more
19about how the AST is structured.
20
21..  FIXME: create new refactoring action tutorial and link to the tutorial
22
23Introduction
24------------
25
26Clang's refactoring engine defines a set refactoring actions that implement
27a number of different source transformations. The ``clang-refactor``
28command-line tool can be used to perform these refactorings. Certain
29refactorings are also available in other clients like text editors and IDEs.
30
31A refactoring action is a class that defines a list of related refactoring
32operations (rules). These rules are grouped under a common umbrella - a single
33``clang-refactor`` command. In addition to rules, the refactoring action
34provides the action's command name and description to ``clang-refactor``.
35Each action must implement the ``RefactoringAction`` interface. Here's an
36outline of a ``local-rename`` action:
37
38.. code-block:: c++
39
40  class LocalRename final : public RefactoringAction {
41  public:
42    StringRef getCommand() const override { return "local-rename"; }
43
44    StringRef getDescription() const override {
45      return "Finds and renames symbols in code with no indexer support";
46    }
47
48    RefactoringActionRules createActionRules() const override {
49      ...
50    }
51  };
52
53Refactoring Action Rules
54------------------------
55
56An individual refactoring action is responsible for creating the set of
57grouped refactoring action rules that represent one refactoring operation.
58Although the rules in one action may have a number of different implementations,
59they should strive to produce a similar result. It should be easy for users to
60identify which refactoring action produced the result regardless of which
61refactoring action rule was used.
62
63The distinction between actions and rules enables the creation of actions
64that define a set of different rules that produce similar results. For example,
65the "add missing switch cases" refactoring operation typically adds missing
66cases to one switch at a time. However, it could be useful to have a
67refactoring that works on all switches that operate on a particular enum, as
68one could then automatically update all of them after adding a new enum
69constant. To achieve that, we can create two different rules that will use one
70``clang-refactor`` subcommand. The first rule will describe a local operation
71that's initiated when the user selects a single switch. The second rule will
72describe a global operation that works across translation units and is initiated
73when the user provides the name of the enum to clang-refactor (or the user could
74select the enum declaration instead). The clang-refactor tool will then analyze
75the selection and other options passed to the refactoring action, and will pick
76the most appropriate rule for the given selection and other options.
77
78Rule Types
79^^^^^^^^^^
80
81Clang's refactoring engine supports several different refactoring rules:
82
83- ``SourceChangeRefactoringRule`` produces source replacements that are applied
84  to the source files. Subclasses that choose to implement this rule have to
85  implement the ``createSourceReplacements`` member function. This type of
86  rule is typically used to implement local refactorings that transform the
87  source in one translation unit only.
88
89- ``FindSymbolOccurrencesRefactoringRule`` produces a "partial" refactoring
90  result: a set of occurrences that refer to a particular symbol. This type
91  of rule is typically used to implement an interactive renaming action that
92  allows users to specify which occurrences should be renamed during the
93  refactoring. Subclasses that choose to implement this rule have to implement
94  the ``findSymbolOccurrences`` member function.
95
96The following set of quick checks might help if you are unsure about the type
97of rule you should use:
98
99#. If you would like to transform the source in one translation unit and if
100   you don't need any cross-TU information, then the
101   ``SourceChangeRefactoringRule`` should work for you.
102
103#. If you would like to implement a rename-like operation with potential
104   interactive components, then ``FindSymbolOccurrencesRefactoringRule`` might
105   work for you.
106
107How to Create a Rule
108^^^^^^^^^^^^^^^^^^^^
109
110Once you determine which type of rule is suitable for your needs you can
111implement the refactoring by subclassing the rule and implementing its
112interface. The subclass should have a constructor that takes the inputs that
113are needed to perform the refactoring. For example, if you want to implement a
114rule that simply deletes a selection, you should create a subclass of
115``SourceChangeRefactoringRule`` with a constructor that accepts the selection
116range:
117
118.. code-block:: c++
119
120  class DeleteSelectedRange final : public SourceChangeRefactoringRule {
121  public:
122    DeleteSelection(SourceRange Selection) : Selection(Selection) {}
123
124    Expected<AtomicChanges>
125    createSourceReplacements(RefactoringRuleContext &Context) override {
126      AtomicChange Replacement(Context.getSources(), Selection.getBegin());
127      Replacement.replace(Context.getSource,
128                          CharSourceRange::getCharRange(Selection), "");
129      return { Replacement };
130    }
131  private:
132    SourceRange Selection;
133  };
134
135The rule's subclass can then be added to the list of refactoring action's
136rules for a particular action using the ``createRefactoringActionRule``
137function. For example, the class that's shown above can be added to the
138list of action rules using the following code:
139
140.. code-block:: c++
141
142  RefactoringActionRules Rules;
143  Rules.push_back(
144    createRefactoringActionRule<DeleteSelectedRange>(
145          SourceRangeSelectionRequirement())
146  );
147
148The ``createRefactoringActionRule`` function takes in a list of refactoring
149action rule requirement values. These values describe the initiation
150requirements that have to be satisfied by the refactoring engine before the
151provided action rule can be constructed and invoked. The next section
152describes how these requirements are evaluated and lists all the possible
153requirements that can be used to construct a refactoring action rule.
154
155Refactoring Action Rule Requirements
156------------------------------------
157
158A refactoring action rule requirement is a value whose type derives from the
159``RefactoringActionRuleRequirement`` class. The type must define an
160``evaluate`` member function that returns a value of type ``Expected<...>``.
161When a requirement value is used as an argument to
162``createRefactoringActionRule``, that value is evaluated during the initiation
163of the action rule. The evaluated result is then passed to the rule's
164constructor unless the evaluation produced an error. For example, the
165``DeleteSelectedRange`` sample rule that's defined in the previous section
166will be evaluated using the following steps:
167
168#. ``SourceRangeSelectionRequirement``'s ``evaluate`` member function will be
169   called first. It will return an ``Expected<SourceRange>``.
170
171#. If the return value is an error the initiation will fail and the error
172   will be reported to the client. Note that the client may not report the
173   error to the user.
174
175#. Otherwise the source range return value will be used to construct the
176   ``DeleteSelectedRange`` rule. The rule will then be invoked as the initiation
177   succeeded (all requirements were evaluated successfully).
178
179The same series of steps applies to any refactoring rule. Firstly, the engine
180will evaluate all of the requirements. Then it will check if these requirements
181are satisfied (they should not produce an error). Then it will construct the
182rule and invoke it.
183
184The separation of requirements, their evaluation and the invocation of the
185refactoring action rule allows the refactoring clients to:
186
187- Disable refactoring action rules whose requirements are not supported.
188
189- Gather the set of options and define a command-line / visual interface
190  that allows users to input these options without ever invoking the
191  action.
192
193Selection Requirements
194^^^^^^^^^^^^^^^^^^^^^^
195
196The refactoring rule requirements that require some form of source selection
197are listed below:
198
199- ``SourceRangeSelectionRequirement`` evaluates to a source range when the
200  action is invoked with some sort of selection. This requirement should be
201  satisfied when a refactoring is initiated in an editor, even when the user
202  has not selected anything (the range will contain the cursor's location in
203  that case).
204
205..  FIXME: Future selection requirements
206
207..  FIXME: Maybe mention custom selection requirements?
208
209Other Requirements
210^^^^^^^^^^^^^^^^^^
211
212There are several other requirements types that can be used when creating
213a refactoring rule:
214
215- The ``RefactoringOptionsRequirement`` requirement is an abstract class that
216  should be subclassed by requirements working with options. The more
217  concrete ``OptionRequirement`` requirement is a simple implementation of the
218  aforementioned class that returns the value of the specified option when
219  it's evaluated. The next section talks more about refactoring options and
220  how they can be used when creating a rule.
221
222Refactoring Options
223-------------------
224
225Refactoring options are values that affect a refactoring operation and are
226specified either using command-line options or another client-specific
227mechanism. Options should be created using a class that derives either from
228the ``OptionalRequiredOption`` or ``RequiredRefactoringOption``. The following
229example shows how one can created a required string option that corresponds to
230the ``-new-name`` command-line option in clang-refactor:
231
232.. code-block:: c++
233
234  class NewNameOption : public RequiredRefactoringOption<std::string> {
235  public:
236    StringRef getName() const override { return "new-name"; }
237    StringRef getDescription() const override {
238      return "The new name to change the symbol to";
239    }
240  };
241
242The option that's shown in the example above can then be used to create
243a requirement for a refactoring rule using a requirement like
244``OptionRequirement``:
245
246.. code-block:: c++
247
248  createRefactoringActionRule<RenameOccurrences>(
249    ...,
250    OptionRequirement<NewNameOption>())
251  );
252
253..  FIXME: Editor Bindings section
254