Coding Conventions

From SailfishOS Documentation

General

As a rule of thumb follow the coding conventions of the open source project you want to contribute to. Most big projects like GStreamer, oFono and Telepathy have their own coding conventions that should be respected when contributing those frameworks.

Coding Conventions for Qt-based middleware and apps

When developing features for Sailfish applications, follow Qt C++ and QML coding conventions. Sailfish has traditionally been relatively flexible on coding style issues, leaving the decision on the enforcement of conventions to the individual teams and developers. Coding convention rules stir up a lot of opinions, but at the end are not so important as long as developers write clear, concise, readable, testable and in general high quality code they can be proud of.

Qt Coding Conventions

QML coding conventions

Additional Sailfish QML coding conventions

Sources: Qt Quick examples, Qt Components conventions

Omit ";" behind JavaScript function lines

Write

  x = a + b

instead of

  x = a + b;

Rationale: less code, basically either style way would be fine, but one was chosen.


Put spaces between conditional statements, code, and curly braces

Write

  if (a) {

instead of

  if(a){

or

  if ( a ) {


Rationale: criteria is mostly esthetic and thus subject to argumentation.

Write short one line functions in one line

It is ok to write

  onClicked: if (a) doSomething()

instead of

  onClicked: {
      if (a) {

doSomething()

      }
  }


Rationale: less lines needed, both forms equally readable.

Omit redundant property assignments

Write

  property bool propertyName
  property int propertyName

instead of

  property bool propertyName: false
  property int propertyName: 0


Rationale: less code, QML developer should already know the default values.

Don't define id for an element if id is not used

Write

  Image {}

instead of

  Image {
      id: background
  }

if you don't need the id.

Rationale: potentially less code. Like with properties only define something if you really need that something.

Use braces in one-line conditionals

Write

  if (a) {
      doSomething()
  }

instead of

  if (a)
      doSomething()


Rationale: Agreed with the team. Goes against Qt Coding convention, but is generally considered safer.


Group properties together when grouped property form is available: font {}, anchors {}, border {}, etc.

Write

  anchors { horizontalCenter: parent.horizontalCenter; horizontalCenterOffset: Theme.paddingSmall }

instead of

  anchors.horizontalCenter: parent.horizontalCenter
  anchors.horizontalCenterOffset: Theme.paddingSmall


Rationale: less code, grouping communicates relation.

Avoid unnecessary negatives

It is more readable to state

  if (a) .. else ..

than

  if (not a) .. else ..

and

  #ifdef USE_SQL
  ..
  #endif

instead of

  #ifdef NO_SQL
  ..
  #endif


Rationale: negatives require more mental load to decrypt. Avoids double negatives like !NO_SOMETHING.

Keep similar properties close to each other

There is no one clear rule with this, grouping is often contextual: base element properties versus specialized properties, visual versus non-visual properties.

Rationale: proximity implies relation, code is easier to read the less you need to jump between lines when interested in particular behavior/feature.

If no clear context division can be found, follow the general order:


  id declaration
  property declarations
  signal declarations
  signal handlers
  javascript functions
  bindings/assignments to existing properties
  grouped properties
  attached properties
  visual child items
  non-visual resource elements
  states
  transitions


Mark private API private

You can't stop developers from reading your code, and if they can't tell public symbols from private symbols their code will end up depending on something that changes in later versions. QML doesn't support for private members, however there are a couple of conventions useful for keeping symbols out of the way. The simplest and usually fastest is to prepend an underscore:


 Item {
     property int iAmPublic
     property int _iAmPrivate
 
     Text {
         text: "Hello"
     }
 }

Testing Conventions

Sailfish app development follows Qt conventions, and autotesting is no different.



There are couple of common anti-patterns highlighted below that you should avoid.

Prefer compare() over verify() when possible

Write

 compare(value, 10)

instead of

 verify(value == 10)

Rationale: Compare produces more descriptive error messages and does more type checking.

Use SignalSpy instead of wait()

Write

 SignalSpy { id: valueSpy; target: object; signalName: "onValueChanged" }
 function test_case() {
     signalSpy.clear()
     signalSpy.wait()
     compare(object.value, newValue)
 }

instead of

 function test_case() {
     wait(100)
     compare(object.value, newValue)
 }

Rationale: Too short arbitrary wait times may fail, at worst cases irregularly. Too long wait times unnecessarily postpone the completion of the autotest.