Skip to content

Commit 11f4393

Browse files
committed
Add design explanation for OverridePureVirtuals tweak
1 parent 2101884 commit 11f4393

File tree

1 file changed

+75
-3
lines changed

1 file changed

+75
-3
lines changed

clang-tools-extra/clangd/refactor/tweaks/OverridePureVirtuals.cpp

Lines changed: 75 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,74 @@
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.
150219
bool 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.
170242
void OverridePureVirtuals::collectMissingPureVirtuals() {
171243
if (!CurrentDeclDef)
172244
return;

0 commit comments

Comments
 (0)