55// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
66//
77// ===----------------------------------------------------------------------===//
8+ //
9+ // Tweak to automatically generate stubs for pure virtual methods inherited from
10+ // base classes.
11+ //
12+ // Purpose:
13+ // - Simplifies making a derived class concrete by automating the creation of
14+ // required method overrides from abstract bases.
15+ //
16+ // Tweak Summary:
17+ //
18+ // 1. Activation Conditions (prepare):
19+ // - The tweak activates when the cursor is over a C++ class definition.
20+ // - The class must be abstract (it, or its base classes, have unimplemented
21+ // pure virtual functions).
22+ // - It must also inherit from at least one other abstract class.
23+ //
24+ // 2. Identifying Missing Methods:
25+ // - The tweak scans the inheritance hierarchy of the current class.
26+ // - It identifies all unique pure virtual methods from base classes
27+ // that are not yet implemented or overridden.
28+ // - These missing methods are then grouped by their original access
29+ // specifier (e.g., public, protected).
30+ //
31+ // 3. Code Generation and Insertion:
32+ // - For each group of missing methods, stubs are inserted.
33+ // - If an access specifier section (like `public:`) exists, stubs are
34+ // inserted there; otherwise, a new section is created and appended.
35+ // - Each generated stub includes the `override` keyword, a `// TODO:`
36+ // comment, and a `static_assert(false, ...)` to force a compile-time
37+ // error if the method remains unimplemented.
38+ // - The base method's signature is adjusted (e.g., `virtual` and `= 0`
39+ // are removed for the override).
40+ //
41+ // 4. Code Action Provided:
42+ // - A single code action titled "Override pure virtual methods" is offered.
43+ // - Applying this action results in a single source file modification
44+ // containing all the generated method stubs.
45+ //
46+ // Example:
47+ //
48+ // class Base {
49+ // public:
50+ // virtual void publicMethod() = 0;
51+ // protected:
52+ // virtual auto privateMethod() const -> int = 0;
53+ // };
54+ //
55+ // Before:
56+ // // cursor here
57+ // class Derived : public Base {}^;
58+ //
59+ // After:
60+ //
61+ // class Derived : public Base {
62+ // public:
63+ // void publicMethod() override {
64+ // // TODO: Implement this pure virtual method.
65+ // static_assert(false, "Method `publicMethod` is not implemented.");
66+ // }
67+ //
68+ // protected:
69+ // auto privateMethod() const -> int override {
70+ // // TODO: Implement this pure virtual method.
71+ // static_assert(false, "Method `privateMethod` is not implemented.");
72+ // }
73+ // };
74+ //
75+ // ===----------------------------------------------------------------------===//
876
977#include " refactor/Tweak.h"
1078#include " support/Token.h"
@@ -146,7 +214,8 @@ bool hasAbstractBaseAncestor(const clang::CXXRecordDecl *CurrentDecl) {
146214 });
147215}
148216
149- // Check if the current class has any pure virtual method to be implemented.
217+ // The tweak is available if the selection is over an abstract C++ class
218+ // definition that also inherits from at least one other abstract class.
150219bool OverridePureVirtuals::prepare (const Selection &Sel) {
151220 const SelectionTree::Node *Node = Sel.ASTSelection .commonAncestor ();
152221 if (!Node)
@@ -165,8 +234,11 @@ bool OverridePureVirtuals::prepare(const Selection &Sel) {
165234 hasAbstractBaseAncestor (CurrentDeclDef);
166235}
167236
168- // Collects all pure virtual methods that are missing an override in
169- // CurrentDecl, grouped by their original access specifier.
237+ // Collects all pure virtual methods from base classes that `CurrentDeclDef` has
238+ // not yet overridden, grouped by their original access specifier.
239+ //
240+ // Results are stored in `MissingMethodsByAccess` and `AccessSpecifierLocations`
241+ // is also populated.
170242void OverridePureVirtuals::collectMissingPureVirtuals () {
171243 if (!CurrentDeclDef)
172244 return ;
0 commit comments