blob: 47db5ac904571389f331aff6eea80487ee9ccdf8 [file] [log] [blame] [view]
Daniel Cheng7ecc1d62017-06-12 20:24:301# Blink C++ Style Guide
2
3This document is a list of differences from the overall [Chromium Style Guide],
4which is in turn a set of differences from the [Google C++ Style Guide]. The
5long-term goal is to make both Chromium and Blink style more similar to Google
6style over time, so this document aims to highlight areas where Blink style
7differs from Google style.
8
9[TOC]
10
Matt Falkenhagencf4f2dd2019-05-10 22:35:2511## May use mutable reference arguments
Daniel Cheng7ecc1d62017-06-12 20:24:3012
Matt Falkenhagencf4f2dd2019-05-10 22:35:2513Mutable reference arguments are permitted in Blink, in contrast to Google style.
Daniel Cheng7ecc1d62017-06-12 20:24:3014
Matt Falkenhagencf4f2dd2019-05-10 22:35:2515> Note: This rule is under [discussion](https://groups.google.com/a/chromium.org/d/msg/blink-dev/O7R4YwyPIHc/mJyEyJs-EAAJ).
16
17**OK:**
Daniel Cheng7ecc1d62017-06-12 20:24:3018```c++
Matt Falkenhagencf4f2dd2019-05-10 22:35:2519// May be passed by mutable reference since |frame| is assumed to be non-null.
Daniel Cheng7ecc1d62017-06-12 20:24:3020FrameLoader::FrameLoader(LocalFrame& frame)
21 : frame_(&frame),
22 progress_tracker_(ProgressTracker::Create(frame)) {
23 // ...
24}
Daniel Cheng7ecc1d62017-06-12 20:24:3025```
26
Dmitry Gozmanca984d72018-06-21 22:47:2527## Prefer WTF types over STL and base types
Daniel Cheng01b0ec512018-03-13 20:50:4228
Dmitry Gozmanca984d72018-06-21 22:47:2529See [Blink readme](../../third_party/blink/renderer/README.md#Type-dependencies)
30for more details on Blink directories and their type usage.
Daniel Cheng01b0ec512018-03-13 20:50:4231
32**Good:**
33```c++
34 String title;
35 Vector<KURL> urls;
36 HashMap<int, Deque<RefPtr<SecurityOrigin>>> origins;
37```
38
39**Bad:**
40```c++
41 std::string title;
42 std::vector<GURL> urls;
43 std::unordered_map<int, std::deque<url::Origin>> origins;
44```
45
Darwin Huang33266b52019-04-15 21:31:2146When interacting with WTF types, use `wtf_size_t` instead of `size_t`.
47
Darwin Huang2f4b7a52019-02-12 03:57:5848## Do not use `new` and `delete`
49
50Object lifetime should not be managed using raw `new` and `delete`. Prefer to
51allocate objects instead using `std::make_unique`, `base::MakeRefCounted` or
52`blink::MakeGarbageCollected`, depending on the type, and manage their lifetime
53using appropriate smart pointers and handles (`std::unique_ptr`, `scoped_refptr`
54and strong Blink GC references, respectively). See [How Blink Works](https://docs.google.com/document/d/1aitSOucL0VHZa9Z2vbRJSyAIsAz24kX8LFByQ5xQnUg/edit#heading=h.ekwf97my4bgf)
55for more information.
56
Kentaro Harac7d2b2b2019-09-04 14:12:2657## Naming
58
59### Use `CamelCase` for all function names
60
61All function names should use `CamelCase()`-style names, beginning with an
62uppercase letter.
63
64As an exception, method names for web-exposed bindings begin with a lowercase
65letter to match JavaScript.
66
67**Good:**
68```c++
69class Document {
70 public:
71 // Function names should begin with an uppercase letter.
72 virtual void Shutdown();
73
74 // However, web-exposed function names should begin with a lowercase letter.
75 LocalDOMWindow* defaultView();
76
77 // ...
78};
79```
80
81**Bad:**
82```c++
83class Document {
84 public:
85 // Though this is a getter, all Blink function names must use camel case.
86 LocalFrame* frame() const { return frame_; }
87
88 // ...
89};
90```
91
92### Precede boolean values with words like “is” and “did”
93```c++
94bool is_valid;
95bool did_send_data;
96```
97
98**Bad:**
99```c++
100bool valid;
101bool sent_data;
102```
103
104### Precede setters with the word “Set”; use bare words for getters
105Precede setters with the word set”. Prefer bare words for getters. Setter and
106getter names should match the names of the variable being accessed/mutated.
107
108If a getters name collides with a type name, prefix it with Get”.
109
110**Good:**
111```c++
112class FrameTree {
113 public:
114 // Prefer to use the bare word for getters.
115 Frame* FirstChild() const { return first_child_; }
116 Frame* LastChild() const { return last_child_; }
117
118 // However, if the type name and function name would conflict, prefix the
119 // function name with “Get”.
120 Frame* GetFrame() const { return frame_; }
121
122 // ...
123};
124```
125
126**Bad:**
127```c++
128class FrameTree {
129 public:
130 // Should not be prefixed with “Get” since there's no naming conflict.
131 Frame* GetFirstChild() const { return first_child_; }
132 Frame* GetLastChild() const { return last_child_; }
133
134 // ...
135};
136```
137
138### Precede getters that return values via out-arguments with the word “Get”
139**Good:**
140```c++
141class RootInlineBox {
142 public:
143 Node* GetLogicalStartBoxWithNode(InlineBox*&) const;
144 // ...
145}
146```
147
148**Bad:**
149```c++
150class RootInlineBox {
151 public:
152 Node* LogicalStartBoxWithNode(InlineBox*&) const;
153 // ...
154}
155```
156
157### May leave obvious parameter names out of function declarations
158[Google C++ Style Guide] allows us to leave parameter names out only if
159the parameter is not used. In Blink, you may leave obvious parameter
160names out of function declarations for historical reason. A good rule of
161thumb is if the parameter type name contains the parameter name (without
162trailing numbers or pluralization), then the parameter name isnt needed.
163
164**Good:**
165```c++
166class Node {
167 public:
168 Node(TreeScope* tree_scope, ConstructionType construction_type);
169 // You may leave them out like:
170 // Node(TreeScope*, ConstructionType);
171
172 // The function name makes the meaning of the parameters clear.
173 void SetActive(bool);
174 void SetDragged(bool);
175 void SetHovered(bool);
176
177 // Parameters are not obvious.
178 DispatchEventResult DispatchDOMActivateEvent(int detail,
179 Event& underlying_event);
180};
181```
182
183**Bad:**
184```c++
185class Node {
186 public:
187 // ...
188
189 // Parameters are not obvious.
190 DispatchEventResult DispatchDOMActivateEvent(int, Event&);
191};
192```
193
194## Prefer enums or StrongAliases to bare bools for function parameters
195Prefer enums to bools for function parameters if callers are likely to be
196passing constants, since named constants are easier to read at the call site.
197Alternatively, you can use base::util::StrongAlias<Tag, bool>. An exception to
198this rule is a setter function, where the name of the function already makes
199clear what the boolean is.
200
201**Good:**
202```c++
203class FrameLoader {
204public:
205 enum class CloseType {
206 kNotForReload,
207 kForReload,
208 };
209
210 bool ShouldClose(CloseType) {
211 if (type == CloseType::kForReload) {
212 ...
213 } else {
214 DCHECK_EQ(type, CloseType::kNotForReload);
215 ...
216 }
217 }
218};
219
220// An named enum value makes it clear what the parameter is for.
221if (frame_->Loader().ShouldClose(FrameLoader::CloseType::kNotForReload)) {
222 // No need to use enums for boolean setters, since the meaning is clear.
223 frame_->SetIsClosing(true);
224
225 // ...
226```
227
228**Good:**
229```c++
230class FrameLoader {
231public:
232 using ForReload = base::util::StrongAlias<class ForReloadTag, bool>;
233
234 bool ShouldClose(ForReload) {
235 // A StrongAlias<_, bool> can be tested like a bool.
236 if (for_reload) {
237 ...
238 } else {
239 ...
240 }
241 }
242};
243
244// Using a StrongAlias makes it clear what the parameter is for.
245if (frame_->Loader().ShouldClose(FrameLoader::ForReload(false))) {
246 // No need to use enums for boolean setters, since the meaning is clear.
247 frame_->SetIsClosing(true);
248
249 // ...
250```
251
252**Bad:**
253```c++
254class FrameLoader {
255public:
256 bool ShouldClose(bool for_reload) {
257 if (for_reload) {
258 ...
259 } else {
260 ...
261 }
262 }
263};
264
265// Not obvious what false means here.
266if (frame_->Loader().ShouldClose(false)) {
267 frame_->SetIsClosing(ClosingState::kTrue);
268
269 // ...
270```
271
272## Comments
273Please follow the standard [Chromium Documentation Guidelines]. In particular,
274most classes should have a class-level comment describing the purpose, while
275non-trivial code should have comments describing why the code is written the
276way it is. Often, what is apparent when the code is written is not so obvious
277a year later.
278
279From [Google C++ Style Guide: Comments]:
280> Giving sensible names to types and variables is much better than obscure
281> names that must be explained through comments.
282
283### Use `README.md` to document high-level components
284
285Documentation for a related-set of classes and how they interact should be done
286with a `README.md` file in the root directory of a component.
287
288### TODO style
289
290Comments for future work should use `TODO` and have a name or bug attached.
291
292From [Google C++ Style Guide: TODO Comments]:
293
294> The person named is not necessarily the person who must fix it.
295
296**Good:**
297```c++
298// TODO(dcheng): Clean up after the Blink rename is done.
299// TODO(https://crbug.com/675877): Clean up after the Blink rename is done.
300```
301
302**Bad:**
303```c++
304// FIXME(dcheng): Clean up after the Blink rename is done.
305// FIXME: Clean up after the Blink rename is done.
306// TODO: Clean up after the Blink rename is done.
307```
308
Daniel Cheng7ecc1d62017-06-12 20:24:30309[Chromium Style Guide]: c++.md
310[Google C++ Style Guide]: https://google.github.io/styleguide/cppguide.html
311[Chromium Documentation Guidelines]: ../../docs/documentation_guidelines.md
312[Google C++ Style Guide: Comments]: https://google.github.io/styleguide/cppguide.html#Comments
313[Google C++ Style Guide: TODO Comments]:https://google.github.io/styleguide/cppguide.html#TODO_Comments