| ========================== | 
 | Clang's refactoring engine | 
 | ========================== | 
 |  | 
 | This document describes the design of Clang's refactoring engine and provides | 
 | a couple of examples that show how various primitives in the refactoring API | 
 | can be used to implement different refactoring actions. The :doc:`LibTooling` | 
 | library provides several other APIs that are used when developing a | 
 | refactoring action. | 
 |  | 
 | Refactoring engine can be used to implement local refactorings that are | 
 | initiated using a selection in an editor or an IDE. You can combine | 
 | :doc:`AST matchers<LibASTMatchers>` and the refactoring engine to implement | 
 | refactorings that don't lend themselves well to source selection and/or have to | 
 | query ASTs for some particular nodes. | 
 |  | 
 | We assume basic knowledge about the Clang AST. See the :doc:`Introduction | 
 | to the Clang AST <IntroductionToTheClangAST>` if you want to learn more | 
 | about how the AST is structured. | 
 |  | 
 | ..  FIXME: create new refactoring action tutorial and link to the tutorial | 
 |  | 
 | Introduction | 
 | ------------ | 
 |  | 
 | Clang's refactoring engine defines a set refactoring actions that implement | 
 | a number of different source transformations. The ``clang-refactor`` | 
 | command-line tool can be used to perform these refactorings. Certain | 
 | refactorings are also available in other clients like text editors and IDEs. | 
 |  | 
 | A refactoring action is a class that defines a list of related refactoring | 
 | operations (rules). These rules are grouped under a common umbrella - a single | 
 | ``clang-refactor`` command. In addition to rules, the refactoring action | 
 | provides the action's command name and description to ``clang-refactor``. | 
 | Each action must implement the ``RefactoringAction`` interface. Here's an | 
 | outline of a ``local-rename`` action: | 
 |  | 
 | .. code-block:: c++ | 
 |  | 
 |   class LocalRename final : public RefactoringAction { | 
 |   public: | 
 |     StringRef getCommand() const override { return "local-rename"; } | 
 |  | 
 |     StringRef getDescription() const override { | 
 |       return "Finds and renames symbols in code with no indexer support"; | 
 |     } | 
 |  | 
 |     RefactoringActionRules createActionRules() const override { | 
 |       ... | 
 |     } | 
 |   }; | 
 |  | 
 | Refactoring Action Rules | 
 | ------------------------ | 
 |  | 
 | An individual refactoring action is responsible for creating the set of | 
 | grouped refactoring action rules that represent one refactoring operation. | 
 | Although the rules in one action may have a number of different implementations, | 
 | they should strive to produce a similar result. It should be easy for users to | 
 | identify which refactoring action produced the result regardless of which | 
 | refactoring action rule was used. | 
 |  | 
 | The distinction between actions and rules enables the creation of actions | 
 | that define a set of different rules that produce similar results. For example, | 
 | the "add missing switch cases" refactoring operation typically adds missing | 
 | cases to one switch at a time. However, it could be useful to have a | 
 | refactoring that works on all switches that operate on a particular enum, as | 
 | one could then automatically update all of them after adding a new enum | 
 | constant. To achieve that, we can create two different rules that will use one | 
 | ``clang-refactor`` subcommand. The first rule will describe a local operation | 
 | that's initiated when the user selects a single switch. The second rule will | 
 | describe a global operation that works across translation units and is initiated | 
 | when the user provides the name of the enum to clang-refactor (or the user could | 
 | select the enum declaration instead). The clang-refactor tool will then analyze | 
 | the selection and other options passed to the refactoring action, and will pick | 
 | the most appropriate rule for the given selection and other options. | 
 |  | 
 | Rule Types | 
 | ^^^^^^^^^^ | 
 |  | 
 | Clang's refactoring engine supports several different refactoring rules: | 
 |  | 
 | - ``SourceChangeRefactoringRule`` produces source replacements that are applied | 
 |   to the source files. Subclasses that choose to implement this rule have to | 
 |   implement the ``createSourceReplacements`` member function. This type of | 
 |   rule is typically used to implement local refactorings that transform the | 
 |   source in one translation unit only. | 
 |  | 
 | - ``FindSymbolOccurrencesRefactoringRule`` produces a "partial" refactoring | 
 |   result: a set of occurrences that refer to a particular symbol. This type | 
 |   of rule is typically used to implement an interactive renaming action that | 
 |   allows users to specify which occurrences should be renamed during the | 
 |   refactoring. Subclasses that choose to implement this rule have to implement | 
 |   the ``findSymbolOccurrences`` member function. | 
 |  | 
 | The following set of quick checks might help if you are unsure about the type | 
 | of rule you should use: | 
 |  | 
 | #. If you would like to transform the source in one translation unit and if | 
 |    you don't need any cross-TU information, then the | 
 |    ``SourceChangeRefactoringRule`` should work for you. | 
 |  | 
 | #. If you would like to implement a rename-like operation with potential | 
 |    interactive components, then ``FindSymbolOccurrencesRefactoringRule`` might | 
 |    work for you. | 
 |  | 
 | How to Create a Rule | 
 | ^^^^^^^^^^^^^^^^^^^^ | 
 |  | 
 | Once you determine which type of rule is suitable for your needs you can | 
 | implement the refactoring by subclassing the rule and implementing its | 
 | interface. The subclass should have a constructor that takes the inputs that | 
 | are needed to perform the refactoring. For example, if you want to implement a | 
 | rule that simply deletes a selection, you should create a subclass of | 
 | ``SourceChangeRefactoringRule`` with a constructor that accepts the selection | 
 | range: | 
 |  | 
 | .. code-block:: c++ | 
 |  | 
 |   class DeleteSelectedRange final : public SourceChangeRefactoringRule { | 
 |   public: | 
 |     DeleteSelection(SourceRange Selection) : Selection(Selection) {} | 
 |  | 
 |     Expected<AtomicChanges> | 
 |     createSourceReplacements(RefactoringRuleContext &Context) override { | 
 |       AtomicChange Replacement(Context.getSources(), Selection.getBegin()); | 
 |       Replacement.replace(Context.getSource, | 
 |                           CharSourceRange::getCharRange(Selection), ""); | 
 |       return { Replacement }; | 
 |     } | 
 |   private: | 
 |     SourceRange Selection; | 
 |   }; | 
 |  | 
 | The rule's subclass can then be added to the list of refactoring action's | 
 | rules for a particular action using the ``createRefactoringActionRule`` | 
 | function. For example, the class that's shown above can be added to the | 
 | list of action rules using the following code: | 
 |  | 
 | .. code-block:: c++ | 
 |  | 
 |   RefactoringActionRules Rules; | 
 |   Rules.push_back( | 
 |     createRefactoringActionRule<DeleteSelectedRange>( | 
 |           SourceRangeSelectionRequirement()) | 
 |   ); | 
 |  | 
 | The ``createRefactoringActionRule`` function takes in a list of refactoring | 
 | action rule requirement values. These values describe the initiation | 
 | requirements that have to be satisfied by the refactoring engine before the | 
 | provided action rule can be constructed and invoked. The next section | 
 | describes how these requirements are evaluated and lists all the possible | 
 | requirements that can be used to construct a refactoring action rule. | 
 |  | 
 | Refactoring Action Rule Requirements | 
 | ------------------------------------ | 
 |  | 
 | A refactoring action rule requirement is a value whose type derives from the | 
 | ``RefactoringActionRuleRequirement`` class. The type must define an | 
 | ``evaluate`` member function that returns a value of type ``Expected<...>``. | 
 | When a requirement value is used as an argument to | 
 | ``createRefactoringActionRule``, that value is evaluated during the initiation | 
 | of the action rule. The evaluated result is then passed to the rule's | 
 | constructor unless the evaluation produced an error. For example, the | 
 | ``DeleteSelectedRange`` sample rule that's defined in the previous section | 
 | will be evaluated using the following steps: | 
 |  | 
 | #. ``SourceRangeSelectionRequirement``'s ``evaluate`` member function will be | 
 |    called first. It will return an ``Expected<SourceRange>``. | 
 |  | 
 | #. If the return value is an error the initiation will fail and the error | 
 |    will be reported to the client. Note that the client may not report the | 
 |    error to the user. | 
 |  | 
 | #. Otherwise the source range return value will be used to construct the | 
 |    ``DeleteSelectedRange`` rule. The rule will then be invoked as the initiation | 
 |    succeeded (all requirements were evaluated successfully). | 
 |  | 
 | The same series of steps applies to any refactoring rule. Firstly, the engine | 
 | will evaluate all of the requirements. Then it will check if these requirements | 
 | are satisfied (they should not produce an error). Then it will construct the | 
 | rule and invoke it. | 
 |  | 
 | The separation of requirements, their evaluation and the invocation of the | 
 | refactoring action rule allows the refactoring clients to: | 
 |  | 
 | - Disable refactoring action rules whose requirements are not supported. | 
 |  | 
 | - Gather the set of options and define a command-line / visual interface | 
 |   that allows users to input these options without ever invoking the | 
 |   action. | 
 |  | 
 | Selection Requirements | 
 | ^^^^^^^^^^^^^^^^^^^^^^ | 
 |  | 
 | The refactoring rule requirements that require some form of source selection | 
 | are listed below: | 
 |  | 
 | - ``SourceRangeSelectionRequirement`` evaluates to a source range when the | 
 |   action is invoked with some sort of selection. This requirement should be | 
 |   satisfied when a refactoring is initiated in an editor, even when the user | 
 |   has not selected anything (the range will contain the cursor's location in | 
 |   that case). | 
 |  | 
 | ..  FIXME: Future selection requirements | 
 |  | 
 | ..  FIXME: Maybe mention custom selection requirements? | 
 |  | 
 | Other Requirements | 
 | ^^^^^^^^^^^^^^^^^^ | 
 |  | 
 | There are several other requirements types that can be used when creating | 
 | a refactoring rule: | 
 |  | 
 | - The ``RefactoringOptionsRequirement`` requirement is an abstract class that | 
 |   should be subclassed by requirements working with options. The more | 
 |   concrete ``OptionRequirement`` requirement is a simple implementation of the | 
 |   aforementioned class that returns the value of the specified option when | 
 |   it's evaluated. The next section talks more about refactoring options and | 
 |   how they can be used when creating a rule. | 
 |  | 
 | Refactoring Options | 
 | ------------------- | 
 |  | 
 | Refactoring options are values that affect a refactoring operation and are | 
 | specified either using command-line options or another client-specific | 
 | mechanism. Options should be created using a class that derives either from | 
 | the ``OptionalRequiredOption`` or ``RequiredRefactoringOption``. The following | 
 | example shows how one can created a required string option that corresponds to | 
 | the ``-new-name`` command-line option in clang-refactor: | 
 |  | 
 | .. code-block:: c++ | 
 |  | 
 |   class NewNameOption : public RequiredRefactoringOption<std::string> { | 
 |   public: | 
 |     StringRef getName() const override { return "new-name"; } | 
 |     StringRef getDescription() const override { | 
 |       return "The new name to change the symbol to"; | 
 |     } | 
 |   }; | 
 |  | 
 | The option that's shown in the example above can then be used to create | 
 | a requirement for a refactoring rule using a requirement like | 
 | ``OptionRequirement``: | 
 |  | 
 | .. code-block:: c++ | 
 |  | 
 |   createRefactoringActionRule<RenameOccurrences>( | 
 |     ..., | 
 |     OptionRequirement<NewNameOption>()) | 
 |   ); | 
 |  | 
 | ..  FIXME: Editor Bindings section |