зеркало из https://github.com/mozilla/gecko-dev.git
358 строки
19 KiB
ReStructuredText
358 строки
19 KiB
ReStructuredText
====================================
|
|
DOM Workers & Storage C++ Code Style
|
|
====================================
|
|
|
|
This page describes the code style for the components maintained by the DOM Workers & Storage team. They live in-tree under the 'dom/docs/indexedDB' directory.
|
|
|
|
This document is currently owned by Simon Giesecke <sgiesecke@mozilla.com>.
|
|
|
|
.. contents::
|
|
:depth: 4
|
|
|
|
Introduction
|
|
============
|
|
|
|
This code style currently applies to the components living in the following directories:
|
|
|
|
* ``dom/file``
|
|
* ``dom/indexedDB``
|
|
* ``dom/localstorage``
|
|
* ``dom/payments``
|
|
* ``dom/quota``
|
|
* ``dom/serviceworkers``
|
|
* ``dom/workers``
|
|
|
|
In the long-term, the code is intended to use the
|
|
`Mozilla Coding Style <https://developer.mozilla.org/en-US/docs/Mozilla/Developer_guide/Coding_Style>`_,
|
|
which references the `Google C++ Coding Style <https://google.github.io/styleguide/cppguide.html>`_.
|
|
|
|
However, large parts of the code were written before rules and in particular
|
|
the reference to the Google C++ Coding Style were enacted, and due to the
|
|
size of the code, this misalignment cannot be fixed in the short term.
|
|
To avoid that an arbitrary mixture of old-style and new-style code grows,
|
|
this document makes deviations from the "global" code style explicit, and
|
|
will be amended to describe migration paths in the future.
|
|
|
|
In addition, to achieve higher consistency within the components maintained by
|
|
the team and to reduce style discussions during reviews, allowing them to focus
|
|
on more substantial issues, more specific rules are described here that go
|
|
beyond the global code style. These topics might have been deliberately or
|
|
accidentally omitted from the global code style. Depending on wider agreement
|
|
and applicability, these specific rules might be migrated into the global code
|
|
style in the future.
|
|
|
|
Note that this document does not cover pure formatting issues. The code is and
|
|
must be kept formatted automatically by clang-format using the supplied
|
|
configuration file, and whatever clang-format does takes precedence over any
|
|
other stated rules regarding formatting.
|
|
|
|
Deviations from the Google C++ Coding Style
|
|
===========================================
|
|
|
|
Deviations not documented yet.
|
|
|
|
Deviations from the Mozilla C++ Coding Style
|
|
============================================
|
|
|
|
.. the table renders impractically, cf. https://github.com/readthedocs/sphinx_rtd_theme/issues/117
|
|
|
|
.. tabularcolumns:: |p{4cm}|p{4cm}|p{2cm}|p{2cm}|
|
|
|
|
+--------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------+-----------------+-------------------------------------------------------------------------------------+
|
|
| Mozilla style | Prevalent WAS style | Deviation scope | Evolution |
|
|
+========================================================================================================+============================================================================================+=================+=====================================================================================+
|
|
| `We prefer using "static", instead of anonymous C++ namespaces. | Place all symbols that should have internal linkage in a single anonymous | All files | Unclear. The recommendation in the Mozilla code style says this might change in the |
|
|
| <https://developer.mozilla.org/en-US/docs/Mozilla/Developer_guide/Coding_Style#Anonymous_namespaces>`_ | namespace block at the top of an implementation file, rather than declarating them static. | | future depending on debugger support, so this deviation might become obsolete. |
|
|
| | | | |
|
|
+--------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------+-----------------+-------------------------------------------------------------------------------------+
|
|
| `All parameters passed by lvalue reference must be labeled const. [...] Input parameters may be const | Non-const reference parameters may be used. | All files | Unclear. Maybe at least restrict the use of non-const reference parameters to |
|
|
| pointers, but we never allow non-const reference parameters except when required by convention, e.g., | | | cases that are not clearly output parameters (i.e. which are assigned to). |
|
|
| swap(). <https://google.github.io/styleguide/cppguide.html#Reference_Arguments>`_ | | | |
|
|
+--------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------+-----------------+-------------------------------------------------------------------------------------+
|
|
|
|
Additions to the Google/Mozilla C++ Code Style
|
|
==============================================
|
|
|
|
This section contains style guidelines that do not conflict with the Google or
|
|
Mozilla C++ Code Style, but may make guidelines more specific or add guidelines
|
|
on topics not covered by those style guides at all.
|
|
|
|
Naming
|
|
------
|
|
|
|
gtest test names
|
|
~~~~~~~~~~~~~~~~
|
|
|
|
gtest constructs a full test name from different fragments. Test names are
|
|
constructed somewhat differently for basic and parametrized tests.
|
|
|
|
The *prefix* for a test should start with an identifier of the component
|
|
and class, based on the name of the source code directory, transformed to
|
|
PascalCase and underscores as separators, so e.g. for a class ``Key`` in
|
|
``dom/indexedDB``, use ``DOM_IndexedDB_Key`` as a prefix.
|
|
|
|
For basic tests constructed with ``TEST(test_case_name, test_name)``: Use
|
|
the *prefix* as the ``test_case_name``. Test ``test_name`` should start with
|
|
the name of tested method(s), and a . Use underscores as a separator within
|
|
the ``test_name``.
|
|
|
|
Value-parametrized tests are constructed with
|
|
``TEST_P(parametrized_test_case_name, parametrized_test_name)``. They require a
|
|
custom test base class, whose name is used as the ``parametrized_test_case_name``.
|
|
Start the class name with ``TestWithParam_``, and end it with a transliteration
|
|
of the parameter type (e.g. ``String_Int_Pair`` for ``std::pair<nsString, int>``),
|
|
and place it in an (anonymous) namespace.
|
|
|
|
.. attention::
|
|
It is important to place the class in an (anonymous) namespace, since its
|
|
name according to this guideline is not unique within libxul-gtest, and name
|
|
clashes are likely, which would lead to ODR violations otherwise.
|
|
|
|
A ``parametrized_test_name`` is constructed according to the same rules
|
|
described for ``test_name`` above.
|
|
|
|
Instances of value-parametrized tests are constructed using
|
|
``INSTANTIATE_TEST_CASE_P(prefix, parametrized_test_case_name, generator, ...)``.
|
|
As ``prefix``, use the prefix as described above.
|
|
|
|
Similar considerations apply to type-parametrized tests. If necessary, specific
|
|
rules for type-parametrized tests will be added here.
|
|
|
|
Rationale
|
|
All gtests (not only from the WAS components) are linked into libxul-gtest,
|
|
which requires names to be unique within that large scope. In addition, it
|
|
should be clear from the test name (e.g. in the test execution log) in what
|
|
source file (or at least which directory) the test code can be found.
|
|
Optimally, test names should be structured hierarchically to allow
|
|
easy selection of groups of tests for execution. However, gtest has some
|
|
restrictions that do not allow that completely. The guidelines try to
|
|
accommodate for these as far as possible. Note that gtest recommends not to
|
|
use underscores in test names in general, because this may lead to reserved
|
|
names and naming conflicts, but the rules stated here should avoid that.
|
|
In case of any problems arising, we can evolve the rules to accommodate
|
|
for that.
|
|
|
|
Specifying types
|
|
----------------
|
|
|
|
Use of ``auto`` for declaring variables
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
The `Google C++ Code Style on auto <https://google.github.io/styleguide/cppguide.html#auto>`_
|
|
allows the use of ``auto`` generally with encouragements for specific cases, which still
|
|
leaves a rather wide range for interpretation.
|
|
|
|
We extend this by some more encouragements and discouragements:
|
|
|
|
* DO use ``auto`` when the type is already present in the
|
|
initialization expression (esp. a template argument or similar),
|
|
e.g. ``auto c = static_cast<uint16_t>(*(iter++)) << 8;`` or
|
|
``auto x = MakeRefPtr<MediaStreamError>(mWindow, *aError);``
|
|
|
|
* DO use ``auto`` if the spelled out type were complex otherwise,
|
|
e.g. a nested typedef or type alias, e.g. ``foo_container::value_type``.
|
|
|
|
* DO NOT use ``auto`` if the type were spelled out as a builtin
|
|
integer type or one of the types from ``<cstdint>``, e.g.
|
|
instead of ``auto foo = funcThatReturnsUint16();`` use
|
|
``uint16_t foo = funcThatReturnsUint16();``.
|
|
|
|
.. note::
|
|
Some disadvantages of using ``auto`` relate to the unavailability of type
|
|
information outside an appropriate IDE/editor. This may be somewhat remedied
|
|
by resolving `Bug 1567464 <https://bugzilla.mozilla.org/show_bug.cgi?id=1567464>`_
|
|
which will make the type information available in searchfox. In consequence,
|
|
the guidelines might be amended to promote a more widespread use of ``auto``.
|
|
|
|
Pointer types
|
|
-------------
|
|
|
|
Plain pointers
|
|
~~~~~~~~~~~~~~
|
|
|
|
The use of plain pointers is error-prone. Avoid using owning plain pointers. In
|
|
particular, avoid using literal, non-placement new. There are various kinds
|
|
of smart pointers, not all of which provide appropriate factory functions.
|
|
However, where such factory functions exist, do use them (along with auto).
|
|
The following is an incomplete list of smart pointer types and corresponding
|
|
factory functions:
|
|
|
|
+------------------------+-------------------------+------------------------+
|
|
| Type | Factory function | Header file |
|
|
+========================+=========================+========================+
|
|
| ``mozilla::RefPtr`` | ``mozilla::MakeRefPtr`` | ``"mfbt/RefPtr.h"`` |
|
|
+------------------------+-------------------------+------------------------+
|
|
| ``mozilla::UniquePtr`` | ``mozilla::MakeUnique`` | ``"mfbt/UniquePtr.h"`` |
|
|
+------------------------+-------------------------+------------------------+
|
|
| ``std::unique_ptr`` | ``std::make_unique`` | ``<memory>`` |
|
|
+------------------------+-------------------------+------------------------+
|
|
| ``std::shared_ptr`` | ``std::make_shared`` | ``<memory>`` |
|
|
+------------------------+-------------------------+------------------------+
|
|
|
|
Also, to create an ``already_AddRefed<>`` to pass as a parameter or return from
|
|
a function without the need to dereference it, use ``MakeAndAddRef`` instead of
|
|
creating a dereferenceable ``RefPtr`` (or similar) first and then using
|
|
``.forget()``.
|
|
|
|
Smart pointers
|
|
~~~~~~~~~~~~~~
|
|
|
|
In function signatures, prefer accepting or returning ``RefPtr`` instead of
|
|
``already_AddRefed`` in conjunction with regular ``std::move`` rather than
|
|
``.forget()``. This improves readability and code generation. Prevailing
|
|
legimitate uses of ``already_AddRefed`` are described in its
|
|
`documentation <https://searchfox.org/mozilla-central/rev/4df8821c1b824db5f40f381f48432f219d99ae36/mfbt/AlreadyAddRefed.h#31>`_.
|
|
|
|
Prefer using ``mozilla::UniquePtr`` over ``nsAutoPtr``, since the latter is
|
|
deprecated (and e.g. has no factory function, see Bug 1600079).
|
|
|
|
Use ``nsCOMPtr<T>`` iff ``T`` is an XPCOM interface type
|
|
(`more details on MDN <https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XPCOM/nsCOMPtr_versus_RefPtr>`).
|
|
|
|
Enums
|
|
-----
|
|
|
|
Use scoped resp. strongly typed enums (``enum struct``) rather than non-scoped
|
|
enums. Use PascalCase for naming the values of scoped enums.
|
|
|
|
Evolution Process
|
|
=================
|
|
|
|
This section explains the process to evolve the coding style described in this
|
|
document. For clarity, we will distinguish coding tasks from code style
|
|
evolution tasks in this section.
|
|
|
|
Managing code style evolution tasks
|
|
-----------------------------------
|
|
|
|
A code style evolution task is a task that ought to amend or revise the
|
|
coding style as described in this document.
|
|
|
|
Code style evolution tasks should be managed in Bugzilla, as individual bugs
|
|
for each topic. All such tasks
|
|
should block the meta-bug
|
|
`1586788 <https://bugzilla.mozilla.org/show_bug.cgi?id=1586788>`.
|
|
|
|
When you take on to work on a code style evolution task:
|
|
|
|
- The task may already include a sketch of a resolution. If no preferred
|
|
solution is obvious, discuss options to resolve it via comments on the bug
|
|
first.
|
|
- When the general idea is ready to be spelled out in this document, amend or
|
|
revise it accordingly.
|
|
- Submit the changes to this document as a patch to Phabricator, and put it up
|
|
for review. Since this will affect a number of people, every change should
|
|
be reviewed by at least two people. Ideally, this should include the owner
|
|
of this style document and one person with good knowledge of the parts of
|
|
the code base this style applies to.
|
|
- If there are known violations of the amendment to the coding style, consider
|
|
fixing some of them, so that the amendment is tested on actual code. If
|
|
the code style evolution task refers to a particular code location from a
|
|
review, at least that location should be fixed to comply with the amended
|
|
coding style.
|
|
- When you have two r+, land the patch.
|
|
- Report on the addition in the next team meeting to raise awareness.
|
|
|
|
Basis for code style evolution tasks
|
|
------------------------------------
|
|
|
|
The desire or necessity to evolve the code style can originate from
|
|
different activities, including
|
|
- reviews
|
|
- reading or writing code locally
|
|
- reading the coding style
|
|
- general thoughts on coding style
|
|
|
|
The code style should not be cluttered with aspects that are rarely
|
|
relevant or rarely leads to discussions, as the maintenance of the
|
|
code style has a cost as well. The code style should be as comprehensive
|
|
as necessary to reduce the overall maintenance costs of the code and
|
|
code style combined.
|
|
|
|
A particular focus is therefore on aspects that led to some discussion in
|
|
a code review, as reducing the number or verbosity of necessary style
|
|
discussions in reviews is a major indicator for the effectiveness of the
|
|
documented style.
|
|
|
|
Evolving code style based on reviews
|
|
------------------------------------
|
|
|
|
The goal of the process described here is to take advantage of style-related
|
|
discussions that originate from a code review, but to decouple evolution of
|
|
the code style from the review process, so that it does not block progress on
|
|
the underlying bug.
|
|
|
|
The following should be considered when performing a review:
|
|
|
|
- Remind yourself of the code style, maybe skim through the document before
|
|
starting the review, or have it open side-by-side while doing the review.
|
|
- If you find a violation of an existing rule, add an inline comment.
|
|
- Have an eye on style-relevant aspects in the code itself or after a
|
|
discussions with the author. Consider if this could be generalized into a
|
|
style rule, but is not yet covered by the documented global or local style.
|
|
This might be something that is in a different style as opposed to other
|
|
locations, differs from your personal style, etc.
|
|
- In that case, find an acceptable temporary solution for the code fragments
|
|
at hand, which is acceptable for an r+ of the patch. Maybe agree with the
|
|
code author on adding a comment that this should be revised later, when
|
|
a rule is codified.
|
|
- Create a code style evolution task in Bugzilla as described above. In the
|
|
description of the bug, reference the review comment that gave rise to it.
|
|
If you can suggest a resolution, include that in the description, but this
|
|
is not a necessary condition for creating the task.
|
|
|
|
Improving code style compliance when writing code
|
|
-------------------------------------------------
|
|
|
|
Periodically look into the code style document, and remind yourself of its
|
|
rules, and give particular attention to recent changes.
|
|
|
|
When writing code, i.e. adding new code or modify existing code,
|
|
remind yourself of checking the code for style compliance.
|
|
|
|
Time permitting, resolve existing violations on-the-go as part of other work
|
|
in the code area. Submit such changes in dedicated patches. If you identify
|
|
major violations that are too complex to resolve on-the-go, consider
|
|
creating a bug dedicated to the resolution of that violation, which
|
|
then can be scheduled in the planning process.
|
|
|
|
Syncing with the global Mozilla C++ Coding Style
|
|
------------------------------------------------
|
|
|
|
Several aspects of the coding style described here will be applicable to
|
|
the overall code base. However, amendments to the global coding style will
|
|
affect a large number of code authors and may require extended discussion.
|
|
Deviations from the global coding style should be limited in the long term.
|
|
On the other hand, amendments that are not relevant to all parts of the code
|
|
base, or where it is difficult to reach a consensus at the global scope,
|
|
may make sense to be kept in the local style.
|
|
|
|
The details of synchronizing with the global style are subject to discussion
|
|
with the owner and peers of the global coding style (see
|
|
`Bug 1587810 <https://bugzilla.mozilla.org/show_bug.cgi?id=1587810>`).
|
|
|
|
FAQ
|
|
---
|
|
|
|
* When someone introduces new code that adheres to the current style, but the
|
|
remainder of the function/class/file does not, is it their responsibility
|
|
to update that remainder on-the-go?
|
|
|
|
The code author is not obliged to update the remainder, but they are
|
|
encouraged to do so, time permitting. Whether that is the case depends on a
|
|
number of factors, including the number and complexity of existing style
|
|
violations, the risk introduced by changing that on the go etc. Judging this
|
|
is left to the code author.
|
|
At the very least, the function/class/file should not be left in a worse
|
|
state than before.
|
|
|
|
* Are stylistic inconsistencies introduced by applying the style as defined
|
|
here only to new code considered acceptable?
|
|
|
|
While this is certainly not optimal, accepting such inconsistencies to
|
|
some degree is inevitable to allow making progress towards an improved style.
|
|
Personal preferences regarding the degree may differ, but in doubt such
|
|
inconsistencies should be considered acceptable. They should not block a bug
|
|
from being closed.
|
|
|