mfbt/STYLE

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

michael@0 1 = mfbt style rules =
michael@0 2
michael@0 3 == Line length ==
michael@0 4
michael@0 5 The line limit is 80 characters, except that excessively long blocks of
michael@0 6 preprocessor directives may exceed this if it makes the code more readable (e.g.
michael@0 7 MOZ_STATIC_ASSERT in Assertions.h.), and unbreakable text in comments (e.g.
michael@0 8 URLs) may exceed this as well. Wrap expressions after binary operators.
michael@0 9
michael@0 10 == Capitalization ==
michael@0 11
michael@0 12 Standalone functions, classes, structs, and template parameters are named
michael@0 13 InterCaps-style. Member functions and fields in classes and structs are named
michael@0 14 camelCaps-style.
michael@0 15
michael@0 16 == Indentation ==
michael@0 17
michael@0 18 Indentation is two spaces, never tabs.
michael@0 19
michael@0 20 if (x == 2)
michael@0 21 return 17;
michael@0 22
michael@0 23 == Whitespace ==
michael@0 24
michael@0 25 Surround binary operators with a single space on either side.
michael@0 26
michael@0 27 if (x == 2)
michael@0 28 return 17;
michael@0 29
michael@0 30 When describing pointer types, the * shall be adjacent to the type name. (Same
michael@0 31 goes for references -- & goes by the type name.)
michael@0 32
michael@0 33 int
michael@0 34 Foo(int* p)
michael@0 35 {
michael@0 36 typedef void* VoidPtr;
michael@0 37 int& i = *p;
michael@0 38 }
michael@0 39
michael@0 40 A corollary: don't mix declaration types by declaring a T and a T* (or a T**,
michael@0 41 &c.) in the same declaration.
michael@0 42
michael@0 43 T* foo, bar; // BAD
michael@0 44
michael@0 45 == Expressions ==
michael@0 46
michael@0 47 Ternary expressions (a ? b : c) should use only one line if sufficiently short.
michael@0 48 Longer ternary expressions should use multiple lines. The condition,
michael@0 49 consequent, and alternative should each be on separate lines (each part
michael@0 50 overflowing to additional lines as necessary), and the ? and : should be aligned
michael@0 51 with the start of the condition:
michael@0 52
michael@0 53 size_t
michael@0 54 BinaryTree::height()
michael@0 55 {
michael@0 56 return isLeaf()
michael@0 57 ? 0
michael@0 58 : 1 + std::max(left()->height(),
michael@0 59 right()->height());
michael@0 60 }
michael@0 61
michael@0 62 == Bracing ==
michael@0 63
michael@0 64 Don't brace single statements.
michael@0 65
michael@0 66 if (y == 7)
michael@0 67 return 3;
michael@0 68 for (size_t i = 0; i < 5; i++)
michael@0 69 frob(i);
michael@0 70
michael@0 71 But do brace them if the statement (or condition(s) or any additional
michael@0 72 consequents, if the braces would be associated with an if statement) occupies
michael@0 73 multiple lines.
michael@0 74
michael@0 75 if (cond1 ||
michael@0 76 cond2)
michael@0 77 {
michael@0 78 action();
michael@0 79 }
michael@0 80 if (cond1) {
michael@0 81 consequent();
michael@0 82 } else {
michael@0 83 alternative(arg1,
michael@0 84 arg2);
michael@0 85 }
michael@0 86 if (cond1 || cond2) {
michael@0 87 callMethod(arg1,
michael@0 88 arg2);
michael@0 89 }
michael@0 90 for (size_t j = 0;
michael@0 91 j < 17;
michael@0 92 j++)
michael@0 93 {
michael@0 94 action();
michael@0 95 }
michael@0 96
michael@0 97 Braces in control flow go at the end of the line except when associated with an
michael@0 98 |if| or loop-head where the condition covers multiple lines
michael@0 99
michael@0 100 == Classes and structs ==
michael@0 101
michael@0 102 Inside class and structure definitions, public/private consume one level of
michael@0 103 indentation.
michael@0 104
michael@0 105 class Baz
michael@0 106 {
michael@0 107 public:
michael@0 108 Baz() { }
michael@0 109 };
michael@0 110
michael@0 111 The absence of public/private in structs in which all members are public still
michael@0 112 consumes a level.
michael@0 113
michael@0 114 struct Foo
michael@0 115 {
michael@0 116 int field;
michael@0 117 };
michael@0 118
michael@0 119 Braces delimiting a class or struct go on their own lines.
michael@0 120
michael@0 121 Member initialization in constructors should be formatted as follows:
michael@0 122
michael@0 123 class Fnord
michael@0 124 {
michael@0 125 size_t s1, s2, s3, s4, s5;
michael@0 126
michael@0 127 public:
michael@0 128 Fnord(size_t s) : s1(s), s2(s), s3(s), s4(s), s5(s) { }
michael@0 129 Fnord()
michael@0 130 : s1(0), /* member initialization can be compressed if desired */
michael@0 131 s2(0),
michael@0 132 s3(0),
michael@0 133 s4(0),
michael@0 134 s5(0)
michael@0 135 {
michael@0 136 ...
michael@0 137 }
michael@0 138 };
michael@0 139
michael@0 140 Fields should go first in the class so that the basic structure is all in one
michael@0 141 place, consistently.
michael@0 142
michael@0 143 Use the inline keyword to annotate functions defined inline in a header. (If
michael@0 144 the function is defined inline in the class, don't bother adding it
michael@0 145 redundantly.)
michael@0 146
michael@0 147 Explicitly delete (using Attributes.h's MOZ_DELETE) the copy constructor and
michael@0 148 assignment operator from classes not intended to be copied or assigned to avoid
michael@0 149 mistakes.
michael@0 150
michael@0 151 class Funky
michael@0 152 {
michael@0 153 public:
michael@0 154 Funky() { }
michael@0 155
michael@0 156 private:
michael@0 157 Funky(const Funky& other) MOZ_DELETE;
michael@0 158 void operator=(const Funky& other) MOZ_DELETE;
michael@0 159 };
michael@0 160
michael@0 161 Include a blank line between sections of structs and classes with different
michael@0 162 access control.
michael@0 163
michael@0 164 The "get" prefix is used when a method is fallible. If it's infallible, don't
michael@0 165 use it.
michael@0 166
michael@0 167 class String
michael@0 168 {
michael@0 169 public:
michael@0 170 size_t length() const; // not getLength()
michael@0 171 };
michael@0 172
michael@0 173 == Templates ==
michael@0 174
michael@0 175 Capitalize template parameter names to distinguish them from fields.
michael@0 176
michael@0 177 template<size_t KeySize, typename T>
michael@0 178 class BloomFilter
michael@0 179 {
michael@0 180 };
michael@0 181
michael@0 182 Use single-letter names if it makes sense (T for an arbitrary type, K for key
michael@0 183 type, V for value type, &c.). Otherwise use InterCaps-style names.
michael@0 184
michael@0 185 When declaring or defining a function, template<...> goes on one line, the
michael@0 186 return type and other specifiers go on another line, and the function name and
michael@0 187 argument list go on a third line.
michael@0 188
michael@0 189 template<typename T>
michael@0 190 inline bool
michael@0 191 Vector::add(T t)
michael@0 192 {
michael@0 193 }
michael@0 194
michael@0 195 == Namespaces ==
michael@0 196
michael@0 197 All C++ code shall be in the mozilla namespace, except that functionality only
michael@0 198 used to implement external-facing API should be in the mozilla::detail
michael@0 199 namespace, indicating that it should not be directly used.
michael@0 200
michael@0 201 Namespace opening braces go on the same line as the namespace declaration.
michael@0 202 Namespace closing braces shall be commented. Namespace contents are not
michael@0 203 indented.
michael@0 204
michael@0 205 namespace mozilla {
michael@0 206 ...
michael@0 207 } // namespace mozilla
michael@0 208
michael@0 209 Don't use |using| in a header unless it's confined to a class or method.
michael@0 210 Implementation files for out-of-line functionality may use |using|.
michael@0 211
michael@0 212 Name data structures and methods which must be usable in C code with a Moz*
michael@0 213 prefix, e.g. MozCustomStructure. If the data structure is not meant to be used
michael@0 214 outside of the header in which it is found (i.e. it would be in mozilla::detail
michael@0 215 but for its being required to work in C code), add a corresponding comment to
michael@0 216 highlight this.
michael@0 217
michael@0 218 == #includes ==
michael@0 219
michael@0 220 Headers that include mfbt headers use a fully-qualified include path, even if
michael@0 221 full qualification is not strictly necessary.
michael@0 222
michael@0 223 #include "mozilla/Assertions.h"
michael@0 224
michael@0 225 mfbt headers should be included first, alphabetically. Standard includes should
michael@0 226 follow, separated from mfbt includes by a blank line.
michael@0 227
michael@0 228 #include "mozilla/Assertions.h"
michael@0 229 #include "mozilla/Attributes.h"
michael@0 230
michael@0 231 #include <string.h>
michael@0 232
michael@0 233 If a header dependency is limited simply to the existence of a class,
michael@0 234 forward-declare it rather than #include that header.
michael@0 235
michael@0 236 namespace mozilla {
michael@0 237
michael@0 238 class BloomFilter;
michael@0 239 extern bool
michael@0 240 Test(BloomFilter* bf);
michael@0 241
michael@0 242 } // namespace mozilla
michael@0 243
michael@0 244 == Preprocessor ==
michael@0 245
michael@0 246 Include guards should be named by determining the fully-qualified include path,
michael@0 247 and substituting _ for / and . in it. For example, "mozilla/Assertions.h"
michael@0 248 becomes mozilla_Assertions_h.
michael@0 249
michael@0 250 Nested preprocessor directives indent the directive name (but not the #) by two
michael@0 251 spaces.
michael@0 252
michael@0 253 #ifdef __clang__
michael@0 254 # define FOO ...
michael@0 255 #else
michael@0 256 # define FOO ...
michael@0 257 #endif
michael@0 258
michael@0 259 Comments within nested preprocessor directives align with directive names at
michael@0 260 that nesting depth.
michael@0 261
michael@0 262 #if defined(__GNUC__)
michael@0 263 /* gcc supports C++11 override syntax. */
michael@0 264 # define MOZ_OVERRIDE override
michael@0 265 #else
michael@0 266 # define MOZ_OVERRIDE /* unsupported */
michael@0 267 #endif
michael@0 268
michael@0 269 Feature-testing macros may be defined to nothing. Macros intended to be
michael@0 270 textually expanded should be defined to a comment indicating non-support, as
michael@0 271 above or as appropriate to the situation.
michael@0 272
michael@0 273 No particular preference is expressed between testing for a macro being defined
michael@0 274 using defined(...) and using #ifdef.
michael@0 275
michael@0 276 When defining a macro with different expansions for different compilers, the top
michael@0 277 level of distinction should be the compiler, and the next nested level should be
michael@0 278 the compiler version. Clang seems likely to be around for awhile, so to reduce
michael@0 279 confusion test for it separately from gcc even when it's not strictly necessary.
michael@0 280
michael@0 281 #if defined(__clang__)
michael@0 282 #elif defined(__GNUC__)
michael@0 283 # if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
michael@0 284 # else
michael@0 285 # endif
michael@0 286 #elif defined(_MSC_VER)
michael@0 287 #endif
michael@0 288
michael@0 289 But don't distinguish clang's feature support using version checks: use the
michael@0 290 __has_feature() and __has_extension() macros instead, because vendors may
michael@0 291 customize clang's version numbers.
michael@0 292
michael@0 293 Use a MOZ_* prefix when defining macros (e.g. MOZ_OVERRIDE, MOZ_LIKELY, and so
michael@0 294 on) that are part of the mfbt interface. (C++ implementation files implementing
michael@0 295 mfbt's interface but which are not directly part of that interface may ignore
michael@0 296 this rule.)
michael@0 297
michael@0 298 Prefer inline functions to macros whenever possible.
michael@0 299
michael@0 300 == Comments ==
michael@0 301
michael@0 302 Header files shall have a short descriptive comment underneath license
michael@0 303 boilerplate indicating what functionality the file implements, to be picked up
michael@0 304 by MXR and displayed in directory listings. (But see bug 717196, which
michael@0 305 currently prevents MXR from doing this if the MPL2 boilerplate is used.)
michael@0 306
michael@0 307 Assertions.h:
michael@0 308 ...license boilerplate...
michael@0 309
michael@0 310 /* Implementations of runtime and static assertion macros for C and C++. */
michael@0 311
michael@0 312 Classes intended for public use shall have interface comments explaining their
michael@0 313 functionality from the user's perspective. These comments shall include
michael@0 314 examples of how the relevant functionality might be used. These interface
michael@0 315 comments use /** */ doxygen/Javadoc-style comments.
michael@0 316
michael@0 317 /**
michael@0 318 * The Frobber class simplifies the process of frobbing.
michael@0 319 */
michael@0 320 class Frobber
michael@0 321 {
michael@0 322 };
michael@0 323
michael@0 324 Comments describing implementation details (tradeoffs considered, assumptions
michael@0 325 made, mathematical background, &c.) occur separately from interface comments so
michael@0 326 that users need not consider them. They should go inside the class definition
michael@0 327 or inside the appropriate method, depending on the specificity of the comment.
michael@0 328
michael@0 329 Headers which are intended to be C-compatible shall use only /**/-style
michael@0 330 comments. (Code examples nested inside documentation comments may use //-style
michael@0 331 comments.) Headers which are C++-compatible may also use //-style comments.
michael@0 332
michael@0 333 Non-interface comments that are /**/-style shall not also be doxygen-style.
michael@0 334
michael@0 335 Use Python-style ** to denote exponentiation inside comments, not ^ (which can
michael@0 336 be confused with C-style bitwise xor). If you're writing sufficiently complex
michael@0 337 math, feel free to descend into LaTeX math mode ;-) inside implementation
michael@0 338 comments if you need to. (But keep it out of interface comments, because most
michael@0 339 people probably haven't seen LaTeX.)
michael@0 340
michael@0 341 == Miscellaneous ==
michael@0 342
michael@0 343 Enclose C-compatible code in |extern "C"| blocks, and #ifdef __cplusplus the
michael@0 344 block start/end as needed. The contents of these blocks should not be indented.
michael@0 345
michael@0 346 Add new functionality to new headers unless an existing header makes sense.
michael@0 347 Err on the side of more headers rather than fewer, as this helps to minimize
michael@0 348 dependencies.
michael@0 349
michael@0 350 Don't use bool for argument types unless the method is a "set" or "enable"-style
michael@0 351 method where the method name and bool value together indicate the sense of its
michael@0 352 effect. Use well-named enums in all other places, so that the semantics of the
michael@0 353 argument are clear at a glance and do not require knowing how the method
michael@0 354 interprets that argument.
michael@0 355
michael@0 356 void
michael@0 357 setVisible(bool visible); // true clearly means visible, false clearly not
michael@0 358 enum Enumerability {
michael@0 359 Enumerable,
michael@0 360 NonEnumerable
michael@0 361 };
michael@0 362 bool
michael@0 363 DefineProperty(JSObject* obj, const char* name, Value v, Enumerability e);
michael@0 364
michael@0 365 Use NULL for the null pointer constant.
michael@0 366
michael@0 367 If a consequent in an if-statement ends with a return, don't specify an else.
michael@0 368 The else would be redundant with the return, and not using it avoids excess
michael@0 369 indentation. If you feel the if-else alternation is important as a way to
michael@0 370 think about the choice being made, consider a ternary expression instead.
michael@0 371
michael@0 372 // BAD
michael@0 373 if (f())
michael@0 374 return 2;
michael@0 375 else
michael@0 376 return 5;
michael@0 377 // GOOD
michael@0 378 if (f())
michael@0 379 return 2;
michael@0 380 return 5;
michael@0 381 // GOOD
michael@0 382 return f() ? 2 : 5

mercurial