Mochi Dev Coding Style Guidelines

The following rules are simply meant for consistency and as general guidelines for how our open source code is presented. When in doubt, use your best judgement and match they style of the surrounding code, or refer to Apple's own Coding Guidelines for Cocoa. Currently a work in progress!

Indentation

  1. Use spaces, not tabs. Tabs should only appear in files that require them for semantic meaning, like TSVs.
  2. The indent size is 4 spaces.

    Right:

    - (void)method
    {
        return;
    }
    

    Wrong:

    - (void)method
    {
            return;
    }
    
  3. The contents of an outermost @interface - @end and @implementation - @end blocks should not be indented. Any interface variables should be indented.

    Right:

    @interface MDObject : NSObject {
        id someObject;
        NSString *aString;
    }
    
    @property (nonatomic, copy) NSString *aString;
    
    - (void)method;
    
    @end
    
    @implementation MDObject
    
    @synthesize aString;
    
    - (void)method
    {
        return;
    }
    
    @end
    

    Wrong:

    @interface MDObject : NSObject {
    id someObject;
    NSString *aString;
    }
    
        @property (nonatomic, copy) NSString *aString;
        - (void)method;
    
    @end
    
    @implementation MDObject
    
        @synthesize aString;
    
        - (void)method
        {
            return;
        }
    
    @end
    
    
  4. A case label should line up with its switch statement. The case statement is indented, unless it consists of a single statement.

    Right:

    switch (condition) {
    case fooCondition: 
    case barCondition:
        i++;
        break; 
    case zeeCondition: return CGRectMake(0, 0, 232, 232);
    default:
        i--;
    }
    

    Wrong:

    switch (condition) {
        case fooCondition:
        case barCondition:
            i++;
        break;
        case zeeCondition:
            return CGRectMake(0, 0, 232, 232);
        default:
            i--;
    }
    
  5. Boolean expressions at the same nesting level that span multiple lines should have their operators on the right side of the line instead of the left side. Indentation should follow the first statement's position.

    Right:

    if ([self.type isEqualToString:@"local"] ||
        [self.type isEqualToString:@"external"] ||
        [self.type isEqualToString:@"custom"])
        return;
    

    Wrong:

    if ([self.type isEqualToString:@"local"]
        || [self.type isEqualToString:@"external"] ||
            [self.type isEqualToString:@"custom"])
        return;
    

Spacing

  1. Do not place spaces around unary operators.

    Right:

    i++;
    a = -5;
    

    Wrong:

    i ++;
    a = - 5;
    
  2. Do not place spaces bitwise operators when the statement is bare, but do place them when it is surrounded by parenthesis

    Right:

    if ((a & MDConstant) == 0)
        return (MDConstantA | MDConstantB | MDConstantC);
    
    self.autoresizingMask = UIViewAutoresizingFlexibleRightMargin|UIViewAutoresizingFlexibleHeight;
    

    Wrong:

    if (a&MDConstant)
        return (MDConstantA|MDConstantB|MDConstantC);
    
    self.autoresizingMask = UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleHeight;
    
  3. Do place spaces around other binary and ternary operators, except when clarifying order of operations.

    Right:

    a = b * c;
    y = m*x + b;
    f(a, b);
    return condition ? 1 : 0;
    

    Wrong:

    y=m*x+b;
    f(a,b);
    return condition ? 1:0;
    
  4. Do not place spaces before comma and semicolon.

    Right:

    for (int i = 0; i < 10; i++)
        doSomething();
    
    f(a, b);
    

    Wrong:

    for (int i = 0 ; i < 10 ; i++)
        doSomething() ;
    
    f(a , b) ;
    
  5. Do not place spaces around colons in methods calls.

    Right:

    [self doSomethething:a withSomething:b];
    

    Wrong:

    [self doSomethething: a withSomething :b];
    
  6. Place spaces between control statements and their parentheses.

    Right:

    if (condition)
        doIt();
    

    Wrong:

    if(condition)
        doIt();
    
  7. Do not place spaces between a function and its parentheses, or between a parenthesis and its content.

    Right:

    f(a, b);
    

    Wrong:

    f (a, b);
    f( a, b );
    

Line breaking

  1. Each statement should get its own line, unless the statement is concise.

    Right:

    x++;
    y++;
    if (condition) doIt();
    if (a == b)
        [self doAlotOfStuff:someJunk withThisStuff:(a + b*c) notForgettingThisJunk:[NSArray arrayWithObject:[NSNull null]]];
    

    Wrong:

    x++; y++;
    if (condition ||
        anotherCondition) doIt();
    if (a == b) [self doAlotOfStuff:someJunk withThisStuff:(a + b*c) notForgettingThisJunk:[NSArray arrayWithObject:[NSNull null]]];
    
  2. An else statement should go on the same line as a preceding close brace if one is present, else it should line up with the if statement.

    Right:

    if (condition) {
        ...
    } else {
        ...
    }
    
    if (condition)
        doSomething();
    else
        doSomethingElse();
    
    if (condition)
        doSomething();
    else {
        ...
    }
    

    Wrong:

    if (condition) {
        ...
    }
    else {
        ...
    }
    
    if (condition) doSomething(); else doSomethingElse();
    
    if (condition) doSomething(); else {
        ...
    }
    
  3. An else if statement should be written as an if statement when the prior if concludes with a return statement.

    Right:

    if (condition) {
        ...
        return someValue;
    }
    
    if (condition) {
        ...
    }
    

    Wrong:

    if (condition) {
        ...
        return someValue;
    } else if (condition) {
        ...
    }
    

Braces

  1. Function and Method definitions: place each brace on its own line.

    Right:

    int main()
    {
        ...
    }
    
    - (void)method
    {
        ...
    }
    

    Wrong:

    int main() {
        ...
    }
    
    - (void)method {
        ...
    }
    
  2. Other braces: place the open brace on the line preceding the code block; place the close brace on its own line.

    Right:

    @implementation MDObject : NSObject {
        ...
    }
    @end
    
    @autorelease {
        ...
    }
    
    for (int i = 0; i < 10; i++) {
        ...
    }
    

    Wrong:

    @implementation MDObject : NSObject
    {
        ...
    }
    @end
    
    @autorelease
    {
        ...
    }
    
    for (int i = 0; i < 10; i++)
    {
        ...
    }
    
  3. One-line control clauses should not use braces unless comments are included or a single statement spans multiple lines.

    Right:

    if (condition)
        doIt();
    
    if (condition) {
        // Some comment
        doIt();
    }
    
    if (condition) {
        [self doAlotOfStuff:someJunk
              withThisStuff:(a + b*c) notForgettingThisJunk:[NSArray arrayWithObject:[NSNull null]]];
    }
    

    Wrong:

    if (condition) {
        doIt();
    }
    
    if (condition)
        // Some comment
        doIt();
    
    if (condition)
        [self doAlotOfStuff:someJunk
              withThisStuff:(a + b*c) notForgettingThisJunk:[NSArray arrayWithObject:[NSNull null]]];
    
  4. If @autorelease spans an entire control structure, it should represent that control structure.

    Right:

    while (condition) @autorelease {
        ...
    }
    
    dispatch_async(cache.assetQueue, ^{ @autoreleasepool {
        ...
    }});
    
    - (void)method { @autoreleasepool
    {
    	...
    }}
    

    Wrong:

    while (condition) {
        @autorelease {
            ...
        }
    }
    
    dispatch_async(cache.assetQueue, ^{
        @autoreleasepool {
            ...
        }
    });
    
    - (void)method
    {
        @autoreleasepool {
            ...
        }
    }
    
  5. Control clauses without a body should use empty braces:

    Right:

    for ( ; current; current = current->next) {}
    

    Wrong:

    for ( ; current; current = current->next);
    

To be Continued!