1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/mfbt/STYLE Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,382 @@ 1.4 += mfbt style rules = 1.5 + 1.6 +== Line length == 1.7 + 1.8 +The line limit is 80 characters, except that excessively long blocks of 1.9 +preprocessor directives may exceed this if it makes the code more readable (e.g. 1.10 +MOZ_STATIC_ASSERT in Assertions.h.), and unbreakable text in comments (e.g. 1.11 +URLs) may exceed this as well. Wrap expressions after binary operators. 1.12 + 1.13 +== Capitalization == 1.14 + 1.15 +Standalone functions, classes, structs, and template parameters are named 1.16 +InterCaps-style. Member functions and fields in classes and structs are named 1.17 +camelCaps-style. 1.18 + 1.19 +== Indentation == 1.20 + 1.21 +Indentation is two spaces, never tabs. 1.22 + 1.23 + if (x == 2) 1.24 + return 17; 1.25 + 1.26 +== Whitespace == 1.27 + 1.28 +Surround binary operators with a single space on either side. 1.29 + 1.30 + if (x == 2) 1.31 + return 17; 1.32 + 1.33 +When describing pointer types, the * shall be adjacent to the type name. (Same 1.34 +goes for references -- & goes by the type name.) 1.35 + 1.36 + int 1.37 + Foo(int* p) 1.38 + { 1.39 + typedef void* VoidPtr; 1.40 + int& i = *p; 1.41 + } 1.42 + 1.43 +A corollary: don't mix declaration types by declaring a T and a T* (or a T**, 1.44 +&c.) in the same declaration. 1.45 + 1.46 + T* foo, bar; // BAD 1.47 + 1.48 +== Expressions == 1.49 + 1.50 +Ternary expressions (a ? b : c) should use only one line if sufficiently short. 1.51 +Longer ternary expressions should use multiple lines. The condition, 1.52 +consequent, and alternative should each be on separate lines (each part 1.53 +overflowing to additional lines as necessary), and the ? and : should be aligned 1.54 +with the start of the condition: 1.55 + 1.56 + size_t 1.57 + BinaryTree::height() 1.58 + { 1.59 + return isLeaf() 1.60 + ? 0 1.61 + : 1 + std::max(left()->height(), 1.62 + right()->height()); 1.63 + } 1.64 + 1.65 +== Bracing == 1.66 + 1.67 +Don't brace single statements. 1.68 + 1.69 + if (y == 7) 1.70 + return 3; 1.71 + for (size_t i = 0; i < 5; i++) 1.72 + frob(i); 1.73 + 1.74 +But do brace them if the statement (or condition(s) or any additional 1.75 +consequents, if the braces would be associated with an if statement) occupies 1.76 +multiple lines. 1.77 + 1.78 + if (cond1 || 1.79 + cond2) 1.80 + { 1.81 + action(); 1.82 + } 1.83 + if (cond1) { 1.84 + consequent(); 1.85 + } else { 1.86 + alternative(arg1, 1.87 + arg2); 1.88 + } 1.89 + if (cond1 || cond2) { 1.90 + callMethod(arg1, 1.91 + arg2); 1.92 + } 1.93 + for (size_t j = 0; 1.94 + j < 17; 1.95 + j++) 1.96 + { 1.97 + action(); 1.98 + } 1.99 + 1.100 +Braces in control flow go at the end of the line except when associated with an 1.101 +|if| or loop-head where the condition covers multiple lines 1.102 + 1.103 +== Classes and structs == 1.104 + 1.105 +Inside class and structure definitions, public/private consume one level of 1.106 +indentation. 1.107 + 1.108 + class Baz 1.109 + { 1.110 + public: 1.111 + Baz() { } 1.112 + }; 1.113 + 1.114 +The absence of public/private in structs in which all members are public still 1.115 +consumes a level. 1.116 + 1.117 + struct Foo 1.118 + { 1.119 + int field; 1.120 + }; 1.121 + 1.122 +Braces delimiting a class or struct go on their own lines. 1.123 + 1.124 +Member initialization in constructors should be formatted as follows: 1.125 + 1.126 + class Fnord 1.127 + { 1.128 + size_t s1, s2, s3, s4, s5; 1.129 + 1.130 + public: 1.131 + Fnord(size_t s) : s1(s), s2(s), s3(s), s4(s), s5(s) { } 1.132 + Fnord() 1.133 + : s1(0), /* member initialization can be compressed if desired */ 1.134 + s2(0), 1.135 + s3(0), 1.136 + s4(0), 1.137 + s5(0) 1.138 + { 1.139 + ... 1.140 + } 1.141 + }; 1.142 + 1.143 +Fields should go first in the class so that the basic structure is all in one 1.144 +place, consistently. 1.145 + 1.146 +Use the inline keyword to annotate functions defined inline in a header. (If 1.147 +the function is defined inline in the class, don't bother adding it 1.148 +redundantly.) 1.149 + 1.150 +Explicitly delete (using Attributes.h's MOZ_DELETE) the copy constructor and 1.151 +assignment operator from classes not intended to be copied or assigned to avoid 1.152 +mistakes. 1.153 + 1.154 + class Funky 1.155 + { 1.156 + public: 1.157 + Funky() { } 1.158 + 1.159 + private: 1.160 + Funky(const Funky& other) MOZ_DELETE; 1.161 + void operator=(const Funky& other) MOZ_DELETE; 1.162 + }; 1.163 + 1.164 +Include a blank line between sections of structs and classes with different 1.165 +access control. 1.166 + 1.167 +The "get" prefix is used when a method is fallible. If it's infallible, don't 1.168 +use it. 1.169 + 1.170 + class String 1.171 + { 1.172 + public: 1.173 + size_t length() const; // not getLength() 1.174 + }; 1.175 + 1.176 +== Templates == 1.177 + 1.178 +Capitalize template parameter names to distinguish them from fields. 1.179 + 1.180 + template<size_t KeySize, typename T> 1.181 + class BloomFilter 1.182 + { 1.183 + }; 1.184 + 1.185 +Use single-letter names if it makes sense (T for an arbitrary type, K for key 1.186 +type, V for value type, &c.). Otherwise use InterCaps-style names. 1.187 + 1.188 +When declaring or defining a function, template<...> goes on one line, the 1.189 +return type and other specifiers go on another line, and the function name and 1.190 +argument list go on a third line. 1.191 + 1.192 + template<typename T> 1.193 + inline bool 1.194 + Vector::add(T t) 1.195 + { 1.196 + } 1.197 + 1.198 +== Namespaces == 1.199 + 1.200 +All C++ code shall be in the mozilla namespace, except that functionality only 1.201 +used to implement external-facing API should be in the mozilla::detail 1.202 +namespace, indicating that it should not be directly used. 1.203 + 1.204 +Namespace opening braces go on the same line as the namespace declaration. 1.205 +Namespace closing braces shall be commented. Namespace contents are not 1.206 +indented. 1.207 + 1.208 + namespace mozilla { 1.209 + ... 1.210 + } // namespace mozilla 1.211 + 1.212 +Don't use |using| in a header unless it's confined to a class or method. 1.213 +Implementation files for out-of-line functionality may use |using|. 1.214 + 1.215 +Name data structures and methods which must be usable in C code with a Moz* 1.216 +prefix, e.g. MozCustomStructure. If the data structure is not meant to be used 1.217 +outside of the header in which it is found (i.e. it would be in mozilla::detail 1.218 +but for its being required to work in C code), add a corresponding comment to 1.219 +highlight this. 1.220 + 1.221 +== #includes == 1.222 + 1.223 +Headers that include mfbt headers use a fully-qualified include path, even if 1.224 +full qualification is not strictly necessary. 1.225 + 1.226 + #include "mozilla/Assertions.h" 1.227 + 1.228 +mfbt headers should be included first, alphabetically. Standard includes should 1.229 +follow, separated from mfbt includes by a blank line. 1.230 + 1.231 + #include "mozilla/Assertions.h" 1.232 + #include "mozilla/Attributes.h" 1.233 + 1.234 + #include <string.h> 1.235 + 1.236 +If a header dependency is limited simply to the existence of a class, 1.237 +forward-declare it rather than #include that header. 1.238 + 1.239 + namespace mozilla { 1.240 + 1.241 + class BloomFilter; 1.242 + extern bool 1.243 + Test(BloomFilter* bf); 1.244 + 1.245 + } // namespace mozilla 1.246 + 1.247 +== Preprocessor == 1.248 + 1.249 +Include guards should be named by determining the fully-qualified include path, 1.250 +and substituting _ for / and . in it. For example, "mozilla/Assertions.h" 1.251 +becomes mozilla_Assertions_h. 1.252 + 1.253 +Nested preprocessor directives indent the directive name (but not the #) by two 1.254 +spaces. 1.255 + 1.256 + #ifdef __clang__ 1.257 + # define FOO ... 1.258 + #else 1.259 + # define FOO ... 1.260 + #endif 1.261 + 1.262 +Comments within nested preprocessor directives align with directive names at 1.263 +that nesting depth. 1.264 + 1.265 + #if defined(__GNUC__) 1.266 + /* gcc supports C++11 override syntax. */ 1.267 + # define MOZ_OVERRIDE override 1.268 + #else 1.269 + # define MOZ_OVERRIDE /* unsupported */ 1.270 + #endif 1.271 + 1.272 +Feature-testing macros may be defined to nothing. Macros intended to be 1.273 +textually expanded should be defined to a comment indicating non-support, as 1.274 +above or as appropriate to the situation. 1.275 + 1.276 +No particular preference is expressed between testing for a macro being defined 1.277 +using defined(...) and using #ifdef. 1.278 + 1.279 +When defining a macro with different expansions for different compilers, the top 1.280 +level of distinction should be the compiler, and the next nested level should be 1.281 +the compiler version. Clang seems likely to be around for awhile, so to reduce 1.282 +confusion test for it separately from gcc even when it's not strictly necessary. 1.283 + 1.284 + #if defined(__clang__) 1.285 + #elif defined(__GNUC__) 1.286 + # if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) 1.287 + # else 1.288 + # endif 1.289 + #elif defined(_MSC_VER) 1.290 + #endif 1.291 + 1.292 +But don't distinguish clang's feature support using version checks: use the 1.293 +__has_feature() and __has_extension() macros instead, because vendors may 1.294 +customize clang's version numbers. 1.295 + 1.296 +Use a MOZ_* prefix when defining macros (e.g. MOZ_OVERRIDE, MOZ_LIKELY, and so 1.297 +on) that are part of the mfbt interface. (C++ implementation files implementing 1.298 +mfbt's interface but which are not directly part of that interface may ignore 1.299 +this rule.) 1.300 + 1.301 +Prefer inline functions to macros whenever possible. 1.302 + 1.303 +== Comments == 1.304 + 1.305 +Header files shall have a short descriptive comment underneath license 1.306 +boilerplate indicating what functionality the file implements, to be picked up 1.307 +by MXR and displayed in directory listings. (But see bug 717196, which 1.308 +currently prevents MXR from doing this if the MPL2 boilerplate is used.) 1.309 + 1.310 + Assertions.h: 1.311 + ...license boilerplate... 1.312 + 1.313 + /* Implementations of runtime and static assertion macros for C and C++. */ 1.314 + 1.315 +Classes intended for public use shall have interface comments explaining their 1.316 +functionality from the user's perspective. These comments shall include 1.317 +examples of how the relevant functionality might be used. These interface 1.318 +comments use /** */ doxygen/Javadoc-style comments. 1.319 + 1.320 + /** 1.321 + * The Frobber class simplifies the process of frobbing. 1.322 + */ 1.323 + class Frobber 1.324 + { 1.325 + }; 1.326 + 1.327 +Comments describing implementation details (tradeoffs considered, assumptions 1.328 +made, mathematical background, &c.) occur separately from interface comments so 1.329 +that users need not consider them. They should go inside the class definition 1.330 +or inside the appropriate method, depending on the specificity of the comment. 1.331 + 1.332 +Headers which are intended to be C-compatible shall use only /**/-style 1.333 +comments. (Code examples nested inside documentation comments may use //-style 1.334 +comments.) Headers which are C++-compatible may also use //-style comments. 1.335 + 1.336 +Non-interface comments that are /**/-style shall not also be doxygen-style. 1.337 + 1.338 +Use Python-style ** to denote exponentiation inside comments, not ^ (which can 1.339 +be confused with C-style bitwise xor). If you're writing sufficiently complex 1.340 +math, feel free to descend into LaTeX math mode ;-) inside implementation 1.341 +comments if you need to. (But keep it out of interface comments, because most 1.342 +people probably haven't seen LaTeX.) 1.343 + 1.344 +== Miscellaneous == 1.345 + 1.346 +Enclose C-compatible code in |extern "C"| blocks, and #ifdef __cplusplus the 1.347 +block start/end as needed. The contents of these blocks should not be indented. 1.348 + 1.349 +Add new functionality to new headers unless an existing header makes sense. 1.350 +Err on the side of more headers rather than fewer, as this helps to minimize 1.351 +dependencies. 1.352 + 1.353 +Don't use bool for argument types unless the method is a "set" or "enable"-style 1.354 +method where the method name and bool value together indicate the sense of its 1.355 +effect. Use well-named enums in all other places, so that the semantics of the 1.356 +argument are clear at a glance and do not require knowing how the method 1.357 +interprets that argument. 1.358 + 1.359 + void 1.360 + setVisible(bool visible); // true clearly means visible, false clearly not 1.361 + enum Enumerability { 1.362 + Enumerable, 1.363 + NonEnumerable 1.364 + }; 1.365 + bool 1.366 + DefineProperty(JSObject* obj, const char* name, Value v, Enumerability e); 1.367 + 1.368 +Use NULL for the null pointer constant. 1.369 + 1.370 +If a consequent in an if-statement ends with a return, don't specify an else. 1.371 +The else would be redundant with the return, and not using it avoids excess 1.372 +indentation. If you feel the if-else alternation is important as a way to 1.373 +think about the choice being made, consider a ternary expression instead. 1.374 + 1.375 + // BAD 1.376 + if (f()) 1.377 + return 2; 1.378 + else 1.379 + return 5; 1.380 + // GOOD 1.381 + if (f()) 1.382 + return 2; 1.383 + return 5; 1.384 + // GOOD 1.385 + return f() ? 2 : 5