summaryrefslogtreecommitdiff
path: root/mfbt/STYLE
diff options
context:
space:
mode:
Diffstat (limited to 'mfbt/STYLE')
-rw-r--r--mfbt/STYLE383
1 files changed, 383 insertions, 0 deletions
diff --git a/mfbt/STYLE b/mfbt/STYLE
new file mode 100644
index 0000000..2d94c3a
--- /dev/null
+++ b/mfbt/STYLE
@@ -0,0 +1,383 @@
+= mfbt style rules =
+
+== Line length ==
+
+The line limit is 80 characters, except that excessively long blocks of
+preprocessor directives may exceed this if it makes the code more readable (e.g.
+MOZ_STATIC_ASSERT in Assertions.h.), and unbreakable text in comments (e.g.
+URLs) may exceed this as well. Wrap expressions after binary operators.
+
+== Capitalization ==
+
+Standalone functions, classes, structs, and template parameters are named
+InterCaps-style. Member functions and fields in classes and structs are named
+camelCaps-style.
+
+== Indentation ==
+
+Indentation is two spaces, never tabs.
+
+ if (x == 2)
+ return 17;
+
+== Whitespace ==
+
+Surround binary operators with a single space on either side.
+
+ if (x == 2)
+ return 17;
+
+When describing pointer types, the * shall be adjacent to the type name. (Same
+goes for references -- & goes by the type name.)
+
+ int
+ Foo(int* p)
+ {
+ typedef void* VoidPtr;
+ int& i = *p;
+ }
+
+A corollary: don't mix declaration types by declaring a T and a T* (or a T**,
+&c.) in the same declaration.
+
+ T* foo, bar; // BAD
+
+== Expressions ==
+
+Ternary expressions (a ? b : c) should use only one line if sufficiently short.
+Longer ternary expressions should use multiple lines. The condition,
+consequent, and alternative should each be on separate lines (each part
+overflowing to additional lines as necessary), and the ? and : should be aligned
+with the start of the condition:
+
+ size_t
+ BinaryTree::height()
+ {
+ return isLeaf()
+ ? 0
+ : 1 + std::max(left()->height(),
+ right()->height());
+ }
+
+== Bracing ==
+
+Don't brace single statements.
+
+ if (y == 7)
+ return 3;
+ for (size_t i = 0; i < 5; i++)
+ frob(i);
+
+But do brace them if the statement (or condition(s) or any additional
+consequents, if the braces would be associated with an if statement) occupies
+multiple lines.
+
+ if (cond1 ||
+ cond2)
+ {
+ action();
+ }
+ if (cond1) {
+ consequent();
+ } else {
+ alternative(arg1,
+ arg2);
+ }
+ if (cond1 || cond2) {
+ callMethod(arg1,
+ arg2);
+ }
+ for (size_t j = 0;
+ j < 17;
+ j++)
+ {
+ action();
+ }
+
+Braces in control flow go at the end of the line except when associated with an
+|if| or loop-head where the condition covers multiple lines
+
+== Classes and structs ==
+
+Inside class and structure definitions, public/private consume one level of
+indentation.
+
+ class Baz
+ {
+ public:
+ Baz() { }
+ };
+
+The absence of public/private in structs in which all members are public still
+consumes a level.
+
+ struct Foo
+ {
+ int field;
+ };
+
+Braces delimiting a class or struct go on their own lines.
+
+Member initialization in constructors should be formatted as follows:
+
+ class Fnord
+ {
+ size_t s1, s2, s3, s4, s5;
+
+ public:
+ Fnord(size_t s) : s1(s), s2(s), s3(s), s4(s), s5(s) { }
+ Fnord()
+ : s1(0), /* member initialization can be compressed if desired */
+ s2(0),
+ s3(0),
+ s4(0),
+ s5(0)
+ {
+ ...
+ }
+ };
+
+Fields should go first in the class so that the basic structure is all in one
+place, consistently.
+
+Use the inline keyword to annotate functions defined inline in a header. (If
+the function is defined inline in the class, don't bother adding it
+redundantly.)
+
+Explicitly delete (using Attributes.h's MOZ_DELETE) the copy constructor and
+assignment operator from classes not intended to be copied or assigned to avoid
+mistakes.
+
+ class Funky
+ {
+ public:
+ Funky() { }
+
+ private:
+ Funky(const Funky& other) MOZ_DELETE;
+ void operator=(const Funky& other) MOZ_DELETE;
+ };
+
+Include a blank line between sections of structs and classes with different
+access control.
+
+The "get" prefix is used when a method is fallible. If it's infallible, don't
+use it.
+
+ class String
+ {
+ public:
+ size_t length() const; // not getLength()
+ };
+
+== Templates ==
+
+Capitalize template parameter names to distinguish them from fields.
+
+ template<size_t KeySize, typename T>
+ class BloomFilter
+ {
+ };
+
+Use single-letter names if it makes sense (T for an arbitrary type, K for key
+type, V for value type, &c.). Otherwise use InterCaps-style names.
+
+When declaring or defining a function, template<...> goes on one line, the
+return type and other specifiers go on another line, and the function name and
+argument list go on a third line.
+
+ template<typename T>
+ inline bool
+ Vector::add(T t)
+ {
+ }
+
+== Namespaces ==
+
+All C++ code shall be in the mozilla namespace, except that functionality only
+used to implement external-facing API should be in the mozilla::detail
+namespace, indicating that it should not be directly used.
+
+Namespace opening braces go on the same line as the namespace declaration.
+Namespace closing braces shall be commented. Namespace contents are not
+indented.
+
+ namespace mozilla {
+ ...
+ } // namespace mozilla
+
+Don't use |using| in a header unless it's confined to a class or method.
+Implementation files for out-of-line functionality may use |using|.
+
+Name data structures and methods which must be usable in C code with a Moz*
+prefix, e.g. MozCustomStructure. If the data structure is not meant to be used
+outside of the header in which it is found (i.e. it would be in mozilla::detail
+but for its being required to work in C code), add a corresponding comment to
+highlight this.
+
+== #includes ==
+
+Headers that include mfbt headers use a fully-qualified include path, even if
+full qualification is not strictly necessary.
+
+ #include "mozilla/Assertions.h"
+
+mfbt headers should be included first, alphabetically. Standard includes should
+follow, separated from mfbt includes by a blank line.
+
+ #include "mozilla/Assertions.h"
+ #include "mozilla/Attributes.h"
+
+ #include <string.h>
+
+If a header dependency is limited simply to the existence of a class,
+forward-declare it rather than #include that header.
+
+ namespace mozilla {
+
+ class BloomFilter;
+ extern bool
+ Test(BloomFilter* bf);
+
+ } // namespace mozilla
+
+== Preprocessor ==
+
+Include guards should be named by determining the fully-qualified include path,
+then substituting _ for / and . in it, and finally appending a trailing _. For
+example, "mozilla/Assertions.h" becomes mozilla_Assertions_h_.
+
+Nested preprocessor directives indent the directive name (but not the #) by two
+spaces.
+
+ #ifdef __clang__
+ # define FOO ...
+ #else
+ # define FOO ...
+ #endif
+
+Comments within nested preprocessor directives align with directive names at
+that nesting depth.
+
+ #if defined(__GNUC__)
+ /* gcc supports C++11 override syntax. */
+ # define MOZ_OVERRIDE override
+ #else
+ # define MOZ_OVERRIDE /* unsupported */
+ #endif
+
+Feature-testing macros may be defined to nothing. Macros intended to be
+textually expanded should be defined to a comment indicating non-support, as
+above or as appropriate to the situation.
+
+No particular preference is expressed between testing for a macro being defined
+using defined(...) and using #ifdef.
+
+When defining a macro with different expansions for different compilers, the top
+level of distinction should be the compiler, and the next nested level should be
+the compiler version. Clang seems likely to be around for awhile, so to reduce
+confusion test for it separately from gcc even when it's not strictly necessary.
+
+ #if defined(__clang__)
+ #elif defined(__GNUC__)
+ # if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
+ # else
+ # endif
+ #elif defined(_MSC_VER)
+ #endif
+
+But don't distinguish clang's feature support using version checks: use the
+__has_feature() and __has_extension() macros instead, because vendors may
+customize clang's version numbers.
+
+Use a MOZ_* prefix when defining macros (e.g. MOZ_OVERRIDE, MOZ_LIKELY, and so
+on) that are part of the mfbt interface. (C++ implementation files implementing
+mfbt's interface but which are not directly part of that interface may ignore
+this rule.)
+
+Prefer inline functions to macros whenever possible.
+
+== Comments ==
+
+Header files shall have a short descriptive comment underneath license
+boilerplate indicating what functionality the file implements, to be picked up
+by MXR and displayed in directory listings. (But see bug 717196, which
+currently prevents MXR from doing this if the MPL2 boilerplate is used.)
+
+ Assertions.h:
+ ...license boilerplate...
+
+ /* Implementations of runtime and static assertion macros for C and C++. */
+
+Classes intended for public use shall have interface comments explaining their
+functionality from the user's perspective. These comments shall include
+examples of how the relevant functionality might be used. These interface
+comments use /** */ doxygen/Javadoc-style comments.
+
+ /**
+ * The Frobber class simplifies the process of frobbing.
+ */
+ class Frobber
+ {
+ };
+
+Comments describing implementation details (tradeoffs considered, assumptions
+made, mathematical background, &c.) occur separately from interface comments so
+that users need not consider them. They should go inside the class definition
+or inside the appropriate method, depending on the specificity of the comment.
+
+Headers which are intended to be C-compatible shall use only /**/-style
+comments. (Code examples nested inside documentation comments may use //-style
+comments.) Headers which are C++-compatible may also use //-style comments.
+
+Non-interface comments that are /**/-style shall not also be doxygen-style.
+
+Use Python-style ** to denote exponentiation inside comments, not ^ (which can
+be confused with C-style bitwise xor). If you're writing sufficiently complex
+math, feel free to descend into LaTeX math mode ;-) inside implementation
+comments if you need to. (But keep it out of interface comments, because most
+people probably haven't seen LaTeX.)
+
+== Miscellaneous ==
+
+Enclose C-compatible code in |extern "C"| blocks, and #ifdef __cplusplus the
+block start/end as needed. The contents of these blocks should not be indented.
+
+Add new functionality to new headers unless an existing header makes sense.
+Err on the side of more headers rather than fewer, as this helps to minimize
+dependencies. Don't add anything to Util.h, which will be split into multiple
+headers at some point (bug 713082).
+
+Don't use bool for argument types unless the method is a "set" or "enable"-style
+method where the method name and bool value together indicate the sense of its
+effect. Use well-named enums in all other places, so that the semantics of the
+argument are clear at a glance and do not require knowing how the method
+interprets that argument.
+
+ void
+ setVisible(bool visible); // true clearly means visible, false clearly not
+ enum Enumerability {
+ Enumerable,
+ NonEnumerable
+ };
+ bool
+ DefineProperty(JSObject* obj, const char* name, Value v, Enumerability e);
+
+Use NULL for the null pointer constant.
+
+If a consequent in an if-statement ends with a return, don't specify an else.
+The else would be redundant with the return, and not using it avoids excess
+indentation. If you feel the if-else alternation is important as a way to
+think about the choice being made, consider a ternary expression instead.
+
+ // BAD
+ if (f())
+ return 2;
+ else
+ return 5;
+ // GOOD
+ if (f())
+ return 2;
+ return 5;
+ // GOOD
+ return f() ? 2 : 5