DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Mercurial (777e60ca8853)

VCS Links

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382
= 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,
and substituting _ for / and . in it.  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 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