[OCLint]OCLint代码检查规则

来源:互联网 发布:电子表格相同数据排序 编辑:程序博客网 时间:2024/05/16 11:12

OCLint 0.10.2 包含67条规则

Basic(基本)

  • BitWiseOperationInConditional (在条件语句中查找按位操作的条件、虽然这些操作都很“聪明”,但太聪明的语法很难理解 like:if (a | b)
  • BrokenNilCheck (nil检查 在某些情况会返回相反的结果 like:if (!obj1))
  • BrokenNullCheck (null检查会导致程序crash like:if (a == NULL)
  • BrokenOddnessCheck (x % 2 == 1 对于负数不起作用、使用 x & 1 == 1 or x % 2 != 0 代替)
  • CollapsibleIfStatements(检查是否两个情况可以合在一个条件中
 if (x)              // these two if statements can be    {        if (y)          // combined to if (x && y)        {            foo();        }    }`
  • ConstantConditionalOperator(是否条件永远true或者永远false like:int a = 1== 1 ? 1:0
  • ConstantIfExpression(条件恒true like:if(true))
  • DeadCode (永远不会执行的代码 like:if(a = 1) return 1; return 2;//deadcode)
  • DoubleNegative(双重否定 like:if(!!a))
  • ForLoopShouldBeWhileLoop (在应该使用while的时候是用来for)
  • GotoStatement (使用goto 语句 like:goto a
  • JumbledIncrementer 乱七八糟的增量 like:
for (int i = 0; i < a; i++) {        for (int j = 0; j < a; i++) { // references both 'i' and 'j'        }    }
  • MisplacedNilCheck (nil 检查被放错了地方、在OC中、向一个nil对象发送消息、什么也不会发生、但是代码读起来会很让人费解 like:if ([obj1 isEqualTo:obj2] && obj1))
  • MisplacedNullCheck (null check被放错了地方、在C 和C++中、想一个null 指针发送消息会导致crash like:if (a->bar(b) && a != NULL)
  • MultipleUnaryOperator (多重一元操作很难理解 like:int b = -(+(!(~1)));)
  • ReturnFromFinallyBlock(在finallyBlock 中return 是不推荐的)
@try    {        foo();    }    @catch(id ex)    {        bar();    }    @finally    {        return;         // this can discard exceptions.    }
  • ThrowExceptionFromFinallyBlock()
@try {;}    @catch(id ex) {;}    @finally {        id ex1;        @throw ex1;                              // this throws an exception        NSException *ex2 = [NSException new];        [ex2 raise];                             // this throws an exception, too    }

Cocoa(objc)

  • ObjCVerifyIsEqualHash(重写isEqual 一定要重写 hash)
  • ObjCVerifyIsEqualHash(必须call super的情况 比如 layoutSubViews
  • ObjCVerifyProtectedMethod(因为在OC中是没有protected,所以有的时候希望强制某个方法只能被它自己或者子类才能调用)
@interface A : NSObject- (void)foo __attribute__((annotate("oclint:enforce[protected method]")));@end@interface B : NSObject@property (strong, nonatomic) A* a;@end@implementation B- (void)bar {    [self.a foo]; // calling protected method foo from outside A and its subclasses}@end
  • ObjCVerifySubclassMustImplement (子类必须实现的方法)
@interface Parent- (void)anAbstractMethod __attribute__((annotate("oclint:enforce[subclass must implement]")));@end@interface Child : Parent@end@implementation Child/*// Child, as a subclass of Parent, must implement anAbstractMethod- (void)anAbstractMethod {}*/@end

Convention(惯例)

  • AvoidBranchingStatementAsLastInLoop (在一个循环的最后语句中使用break非常让人疑惑)
    for (int i = 0; i < 10; i++)    {        if (foo(i))        {            continue;        }        break;      // this break is confusing    }
  • CoveredSwitchStatementsDontNeedDefault (switch中如果case覆盖了所有的情况、那么defaul 是不需要的)
typedef enum {    value1 = 0,    value2 = 1} eValues;void aMethod(eValues a){    switch(a)    {        case value1:            break;        case value2:            break;        default:          // this break is obsolete because all            break;        // values of variable a are already covered.    }}
  • DefaultLabelNotLastInSwitchStatement(default没有在最后一个)
void example(int a){    switch (a) {        case 1:            break;        default:  // the default case should be last            break;        case 2:            break;    }}
  • DestructorOfVirtualClass(虚类的子数的解析函数也要是虚函数)
class Base { // class Base should have a virtual destructor ~Base()    public: virtual void f();};class Child : public Base {    public: ~Child();  // destructor ~Child() should be virtual};
  • InvertedLogic(反转逻辑很难理解)
if (a != 0)             // if (a == 0)    {                       // {        i = 1;              //      i = 0;    }                       // }    else                    // else    {                       // {        i = 0;              //      i = 1;    }                       // }    return !i ? -1 : 1;     // return i ? 1 : -1;
  • MissingBreakInSwitchStatement (switch中缺少break)
  • NonCaseLabelInSwitchStatement (switch中缺少case)
  • ObjCAssignIvarOutsideAccessors (禁止在setter、getter、和init之外定义变量)
@interface Foo : NSObject{    int _bar;}@property (assign, nonatomic) int bar;@end@implementation Foo@synthesize bar = _bar;- (void)doSomething {    _bar = 3; // access _bar outside its getter, setter or init}@end
  • ParameterReassignment(参数再赋值在大部分情况下是有问题的 like:if (a < 0){a = 0; // reassign parameter a to 0}
  • PreferEarlyExit (不期望的结果先判断)
int *doSomething(int a) {  if (!foo(a) && bar(a) && doOtherThing(a)) {    // ... some really long code ....  }  return 0;}// is preferred asint *doSomething(int a) {  if (foo(a)) {    return 0;  }  if (!bar(a)) {    return 0;  }  if (!doOtherThing(a)) {    return 0;  }  // ... some long code ....}
  • SwitchStatementsShouldHaveDefault
  • TooFewBranchesInSwitchStatement(如果swtich的case很少、建议使用if)

Empty(空)

  • EmpthCatchStatement (一个exception 被catch、但是什么也没做)
    try    {        int* m= new int[1000];    }    catch(...)                  // empty catch statement, this swallows an exception    {    }
  • EmptyDoWhileStatement
do    {                           // empty do-while statement    } while(1);
  • EmptyElseBlock
  if (1)    {        return a + 1;    }    else                // empty else statement, can be safely removed    {    }
  • EmptyFinallyStatement
 Foo *foo;    @try    {        [foo bar];    }    @catch(NSException *e)    {        NSLog(@"Exception occurred: %@", [e description]);    }    @finally            // empty finally statement, probably forget to clean up?    {    }
  • EmptyForStatement
    for (;;)                // empty for statement    {    }    for (id it in array)    // empty for-each statement    {    }
  • EmptyIfStatement
    if (a == 1)                  // empty if statement    {    }
  • EmptySwitchStatement
    switch (i)              // empty switch statement    {    }
  • EmptyTryStatement
  • EmptyWhileStatement

Migration(移植、感觉叫最佳实践更好理解)

  • ObjCBoxedExpressions(可以使用简单的写法、 就尽量不要太繁琐)
void aMethod(){    NSNumber *fortyTwo = [NSNumber numberWithInt:(43 - 1)];    // NSNumber *fortyTwo = @(43 - 1);    NSString *env = [NSString stringWithUTF8String:getenv("PATH")];    // NSString *env = @(getenv("PATH"));}
  • ObjCContainerLiterals
void aMethod(){    NSArray *a = [NSArray arrayWithObjects:@1, @2, @3, nil];    // NSArray *a = @[ @1, @2, @3 ];    NSDictionary *d = [NSDictionary dictionaryWithObjects:@[@2,@4] forKeys:@[@1,@3]];    // NSDictionary *d = @{ @1 : @2, @3 : @4 };}
  • ObjCNSNumberLiterals
void aMethod(){    NSNumber *fortyTwo = [NSNumber numberWithInt:42];    // NSNumber *fortyTwo = @42;    NSNumber *yesBool = [NSNumber numberWithBool:YES];    // NSNumber *yesBool = @YES;}
  • ObjCObjectSubscripting
void aMethod(NSArray *a, NSDictionary *d){    id item = [a objectAtIndex:0];    // id item = a[0];    id item = [d objectForKey:@1];    // id item = d[@1];}

Naming(命名)

  • LongVariableName (太长的变量名称)
  • LongVariableName (过短的变量名称)

Redundant(多余的)

  • RedundantConditionalOperator
void example(int a, int b, int c){    bool b1 = a > b ? true : false;     // true/false: bool b1 = a > b;    bool b2 = a > b ? false : true;     // false/true: bool b2 = !(a > b);    int i1 = a > b ? 1 : 1;             // same constant: int i1 = 1;    float f1 = a > b ? 1.0 : 1.00;      // equally constant: float f1 = 1.0;    int i2 = a > b ? c : c;             // same variable: int i2 = c;}
  • RedundantIfStatement
bool example(int a, int b){    if (a == b)             // this if statement is redundant    {        return true;    }    else    {        return false;    }                       // the entire method can be simplified to return a == b;}
  • RedundantLocalVariable
int example(int a){    int b = a * 2;    return b;   // variable b is returned immediately after its declaration,}               // can be simplified to return a * 2;
  • RedundantNilCheck
+ (void)compare:(A *)obj1 withOther:(A *)obj2{    if (obj1 && [obj1 isEqualTo:obj2]) // if ([obj1 isEqualTo:obj2]) is okay    {    }}
  • UnnecessaryElseStatement
bool example(int a){    if (a == 1)                 // if (a == 1)    {                           // {        cout << "a is 1.";      //     cout << "a is 1.";        return true;            //     return true;    }                           // }    else                        //    {                           //        cout << "a is not 1."   // cout << "a is not 1."    }                           //}
  • UnnecessaryNullCheckForCXXDealloc
void m(char* c) {    if (c != nullptr) { // and be simplified to delete c;        delete c;    }
  • UselessParentheses
int example(int a){    int y = (a + 1);    // int y = a + 1;    if ((y > 0))        // if (y > 0)    {        return a;    }    return (0);         // return 0;}

Size(尺寸)

  • CyclomaticComplexity(圈复杂度)
  • LongClass(过大的类)
  • LongLine (每行过长)
  • LongMethod (方法过长)
  • NcssMethodCount(Ncss:Non Commenting Source Statements 没有说明的代码的数量 方法数量)
  • NestedBlockDepth (层次过大)
  • NPathComplexity (NPath 复杂度)
  • TooManyFields (太多的域)
class c{    int a, b;    int c;    // ...    int l;    int m, n;    // ...    int x, y, z;    void m() {}};
  • TooManyMethods
class c{    int a();    int b();    int c();    // ...    int l();    int m();    int n();    // ...    int x();    int y();    int z();    int aa();    int ab();    int ac();    int ad();    int ae();};
  • TooManyParameters
void example(int a, int b, int c, int d, int e, int f,    int g, int h, int i, int j, int k, int l){}

Unused(从未被使用)

  • UnusedLocalVariable (未被使用的本地变量)
  • UnusedMethodParameter (未被使用的方法)

注:这些规则你可以在http://docs.oclint.org/en/stable/rules/index.html?highlight=rules找到

之后的博客会更新如何自定义检查规则,敬请期待。

0 0