Skip to content

Robomongo Coding Style

Junior Dussouillez edited this page Aug 11, 2017 · 41 revisions

In most cases we follow MongoDB style guides, which in turns tries to follow Google C++ Style Guide.

  1. Basics
    1. Golden rule
    2. Use spaces, no literal tabs
    3. 4 spaces per indentation
    4. Use LF (Unix-style) line endings
    5. Case
    6. Comments
  2. Code Style
    1. Return Early
  3. Brackets and Spaces
    1. Brackets
    2. Blank lines
    3. Blank spaces
  4. Includes
    1. #includes
    2. Header (.h) files
    3. Implementation (.cpp) files
  5. Class Layout
    1. Declaration Order

Basics

Golden rule

If you are extending, enhancing, or bug fixing already implemented code, use the style that is already being used so that the source is uniform and easy to follow.

Use spaces, no literal tabs

In all cases, prefer spaces to tabs in source files. People have different preferred indentation levels, and different styles of indentation that they like; this is fine. What isn’t fine is that different editors/viewers expand tabs out to different tab stops. This can cause your code to look completely unreadable, and it is not worth dealing with.

4 spaces per indentation

Use 4 spaces for all indentations.

Use LF (Unix-style) line endings, not CR-LF (DOS)

Git will automatically manage line endings for you if you set the core.autocrlf option. This only need to be done when developing on Windows:

git config --global core.autocrlf true

Case

Use camelCase for most varNames. Use PascalCase for names of classes and structs. Use camelCase for instances of such classes.

class MongoDocument 
{
    void printAndGo(const std::string &textMessage) const 
    {
        int sizeLimit = 0;
        // ...
    }
}

Comments

When writing comments, write them as English prose, which means they should use proper capitalization, punctuation, etc. Always start comments with a capital letter.

We follow https://google.github.io/styleguide/cppguide.html#Comments for placement of comments.

As for style, we use javadocs in classes and methods (public or private):

/**
 * @brief Tab bar for WorkAreaTabWidget.
 */
class WorkAreaTabBar : public QTabBar
{
    Q_OBJECT

public:
    /**
     * @brief Creates WorkAreaTabBar, without parent widget. We are
     * assuming, that tab bar will be installed to (and owned by)
     * WorkAreaTabWidget, using QTabWidget::setTabBar().
     * @param parent Parent widget
     */
    WorkAreaTabBar(QWidget *parent=0);

    //...

private:
    /**
     * @brief Tab's context menu.
     */
    QMenu *_menu;

    // ..
};

We use simple comments inside methods and functions:

FindFrame *OutputItemContentWidget::configureLogText()
{
    FindFrame *logText = new FindFrame(this);
    logText->sciScintilla()->setLexer(_javaScriptLexer);

    // Wrap mode turned off because it introduces huge performance problems
    // even for medium size documents.
    logText->sciScintilla()->setWrapMode((QsciScintilla::WrapMode) QsciScintilla::SC_WRAP_NONE);

    return _logText;
}

Code Style

Return Early

Bad:

void foo(int x) 
{
    if (x) {
        // ...
    }
}

Good:

void foo(int x) 
{
    if (!x)
        return;

    // ...
}

They follow this rule:
LLVM Coding Standards: Use Early Exits and continue to Simplify Code
Mozilla Coding Style: Return from errors immediately
MongoDB Code Style: Return Early

Brackets and Spaces

Brackets

Classes, namespaces, methods and functions have the opening brace at the beginning of the next line:

class MongoDocument
{
    // ...
}

namespace Robomongo 
{
    // ...
}

void MongoDocument::print()
{
    // ...
}

But for everything inside methods and functions put the opening brace last on the line:

if (0) {
    // ...
}
else if (0) {
    // ...
}
else {
    // ...
}

do {
    // ...
} while (0);

Blank lines

Blank lines improve readability by setting of sections of code that are logically related. One blank line should always be used in the following circumstances:

  • Between class/struct definitions
  • Between methods/functions definitions
  • Before a comment (multi or single line)
  • Between logical sections inside a method to improve readability

Blank spaces

  • A keyword followed by a parenthesis should be separated by a space. This helps to distinguish keywords from function calls:
    while (index > 5) {
        // ...
    }
  • Blank space should appear after commas in argument lists.
  • All binary and ternary operators except . should be separated from their operands by spaces. Blanks should never separate unary operators such as unary minus, increment ++ and decrement -- from their operands:
    a += c + d;
    a = (a + b) / (c * d);
    a = (b > c) ? b : c;
    xCoord--;
  • The expressions in a for statement should be separated by spaces
    for (expr1; cond1; expr2) {
    }

Includes

#includes

Use "double quotes" for Robomongo code, <angle brackets> for 3rd party or library headers, including MongoDB files:

#include <QStringList>
#include <boost/shared_ptr.hpp>
#include <mongo/client/dbclient.h>

#include "robomongo/core/Core.h"
#include "robomongo/core/MongoElement.h"

All of a project's header files should be listed as descendants of the project's src/ source directory without use of directory shortcuts (. and ..).

Correct:

#include "robomongo/core/MongoElement.h"

Wrong:

#include "core/MongoElement.h"
#include "../core/MongoElement.h"
#include "MongoElement.h"

Header (.h) files

Follow this order:

  1. #pragma once at the top. Blank line.
  2. Third party #includes, sorted. Blank line.
  3. Robomongo #includes, sorted. Blank line.

Implementation (.cpp) files

  1. Primary file #include, if applicable. Blank line.
  2. Third party #includes, sorted. Blank line.
  3. Robomongo #includes, sorted. Blank line.

Class Layout

Declaration Order

Your class declaration should be divided on 'access' sections in the following order:

  1. public:
  2. signals:
  3. public slots:
  4. protected slots:
  5. protected:
  6. private slots:
  7. private:

If any of these sections are empty, omit them.

Within each section, the declaration should be in the following order:

  1. Typedefs and Enums
  2. Constants (static const data members)
  3. Constructors
  4. Destructor
  5. Methods, including static methods
  6. Data members

Method definitions in the corresponding .cpp file should be the same as the declaration order.

Do not put large method definitions inline in the class definition. Usually, only trivial or performance-critical, and very short, methods may be defined inline.