OCLint的规则

作者: Money_YC | 来源:发表于2021-02-07 17:31 被阅读0次

    一.前言

    最新的OCLint中有71个检查的规则http://docs.oclint.org/en/stable/rules/index.html
    主要对针对nil值的检查,cocoa的obj检查,类型转换,空值的检查,简洁语法的检查,参数,size和不使用的参数和变量的检查。

    1.主要分为10大类

    Basic(基本)
    Cocoa
    Convention(约定)
    Design
    Empty(判空)
    Migration(迁移)
    Naming(命名)
    Redundant(沉余)
    Size(大小)
    Unused(无用)
    

    详细对9大类进行解释

    Basic(基本)

    1.Bitwise operator in conditional
    定义类: oclint-rules/rules/basic/BitwiseOperatorInConditionalRule.cpp
    说明:对于按位与或者按位或的情况,OClint认为这不便于理解。

    void example(int a, int b)
    {
        if (a | b)
        {
        }
        if (a & b)
        {
        }
    }
    

    2.Broken Nil Check
    定义类: oclint-rules/rules/basic/BrokenNullCheckRule.cpp
    说明:nil检查,在某些情况会返回相反的结果

    + (void)compare:(A *)obj1 withOther:(A *)obj2
    {
        if (obj1 || [obj1 isEqualTo:obj2])
        {
        }
    
        if (!obj1 && ![obj1 isEqualTo:obj2])
        {
        }
    }
    

    3.Broken Null Check
    定义类: oclint-rules/rules/basic/BrokenNullCheckRule.cpp
    说明:NULL检查会导致程序crash

    void m(A *a, B *b)
    {
        if (a != NULL || a->bar(b))
        {
        }
    
        if (a == NULL && a->bar(b))
        {
        }
    }
    

    4.Broken Oddness Check
    定义类: oclint-rules/rules/basic/BrokenOddnessCheckRule.cpp
    说明:X%2==1对负数不起作用,需要使用X&1 ==1或者X%2!=0来代替

    void example()
    {
        if (x % 2 == 1)         // violation
        {
        }
    
        if (foo() % 2 == 1)     // violation
        {
        }
    }
    

    5.collapsible if statements
    定义类: oclint-rules/rules/basic/CollapsibleIfStatementsRule.cpp
    说明:判断两个相连的if是否能够合并,可以合并的连续两个if,应该合并,提高代码的可读性.

    void example(bool x, bool y)
    {
        if (x)              // these two if statements can be
        {
            if (y)          // combined to if (x && y)
            {
                foo();
            }
        }
    }
    

    6.Constant Conditional Operator
    定义类: oclint-rules/rules/basic/ConstantConditionalOperatorRule.cpp
    说明:条件是否永远为true或者永远false?

    void example()
    {
        int a = 1 == 1 ? 1 : 0;     // 1 == 1 is actually always true
    }
    
    1. constant if expression
      定义类: oclint-rules/rules/basic/ConstantIfExpressionRule.cpp
      说明:if判断中的值是恒定的,比如if(true),其中的值永远为真。
    void example()
    {
        if (true)       // always true
        {
            foo();
        }
        if (1 == 0)     // always false
        {
            bar();
        }
    }
    

    8.dead code
    定义类: oclint-rules/rules/basic/DeadCodeRule.cpp
    说明:无效代码,表示标示位置有永远不会被执行的代码。在 return, break, continue, and throw 之后的代码都是无效的。

    void example(id collection)
    {
        for (id it in collection)
        {
            continue;
            int i1;                 // dead code
        }
        return;
        int i2;                     // dead code
    }
    

    9.Double Negative
    定义类: oclint-rules/rules/basic/DoubleNegativeRule.cpp
    说明:双重否定,表示不需要使用双重否定,形如!!1,~~1等,因为这并没有用处。

    void example()
    {
        int b1 = !!1;
        int b2 = ~~1;
    }
    

    10.ForLoop Should Be WhileLoop
    定义类: oclint-rules/rules/basic/ForLoopShouldBeWhileLoopRule.cpp
    说明:表示此处不应该用for循环而应该使用while循环。

    void example(int a)
    {
        for (; a < 100;)
        {
            foo(a);
        }
    }
    

    11.Goto Statement
    定义类: oclint-rules/rules/basic/GotoStatementRule.cpp
    说明:Goto语句,提示谨慎使用Goto语句。

    void example()
    {
        A:
            a();
        goto A;     // Considered Harmful
    }
    

    12.Jumbled Incrementer
    定义类: oclint-rules/rules/basic/JumbledIncrementerRule.cpp
    说明:混乱的增量,多数出现在嵌套for循环中,如果不是因为笔误写错了,那么这种混乱的写法容易造成代码阅读的问题。

    void aMethod(int a) {
        for (int i = 0; i < a; i++) {
            for (int j = 0; j < a; i++) { // references both 'i' and 'j'
            }
        }
    }
    

    13.Misplaced Null Check
    定义类: oclint-rules/rules/basic/MisplacedNullCheckRule.cpp
    说明:错位的Null检查,Null Check被放错地方,在OC中向一个空指针发送消息并不会发生什么,但是在C或者C++中可能会引起crash,同时可能会造成代码阅读的困惑。

    void m(A *a, B *b)
    {
        if (a->bar(b) && a != NULL) // violation
        {
        }
    
        if (a->bar(b) || !a)        // violation
        {
        }
    }
    

    14.MisplacedNilCheck
    定义类: oclint-rules/rules/basic/MisplacedNilCheckRule.cpp
    说明:错位的Nil检查,空检查应该在其他运算之前

    + (void)compare:(A *)obj1 withOther:(A *)obj2
    {
        if ([obj1 isEqualTo:obj2] && obj1)
        {
        }
    
        if (![obj1 isEqualTo:obj2] || obj1 == nil)
        {
        }
    }
    

    15.Multiple Unary Operator
    定义类: oclint-rules/rules/basic/MultipleUnaryOperatorRule.cpp
    说明:多余运算符,多重一元操作很难被理解。多余的运算符应该简化,便于阅读

    void example()
    {
        int b = -(+(!(~1)));
    }
    

    16.Return From Finally Block
    定义类: oclint-rules/rules/basic/ReturnFromFinallyBlockRule.cpp
    说明:从Finally 返回,在最后一个block中return的做法是不推荐的。

    void example()
    {
        @try
        {
            foo();
        }
        @catch(id ex)
        {
            bar();
        }
        @finally
        {
            return;         // this can discard exceptions.
        }
    }
    

    17.Throw Exception From Finally Block
    定义类: oclint-rules/rules/basic/ThrowExceptionFromFinallyBlockRule.cpp
    说明:Finally抛出异常,不要在最后一个BLOCK中抛出异常,因为这样的情况可能会掩盖其他异常或者代码缺陷。

    void example()
    {
        @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(OC)

    1.Must Override Hash With IsEqual
    定义类: oclint-rules/rules/cocoa/ObjCVerifyIsEqualHashRule.cpp
    说明:重写isEqual必须重写Hash MustOverrideHashWithIsEqua,如果重写isEqual,一定也要重写hash,原名为ObjCVerifyIsEqualHash。

    @implementation BaseObject
    
    - (BOOL)isEqual:(id)obj {
        return YES;
    }
    
    /*
    - (int)hash is missing; If you override isEqual you must override hash too.
    */
    @end
    

    2.Must Call Super
    定义类: oclint-rules/rules/cocoa/ObjCVerifyMustCallSuperRule.cpp
    说明:提示需要增加call super的情况,例如layoutSubviews方法,需要添加[super layoutSubviews]. 当一个类使用 attribute((annotate("oclint:enforce[must call super]"))) 注解的时候, 他的所有实现(包括他自己和子类)都必须调用超类的实现

    @interface UIView (OCLintStaticChecks)
    - (void)layoutSubviews __attribute__((annotate("oclint:enforce[must call super]")));
    @end
    
    @interface CustomView : UIView
    @end
    
    @implementation CustomView
    
    - (void)layoutSubviews {
        // [super layoutSubviews]; is enforced here
    }
    
    @end
    

    3.Verify Prohibited Call
    定义类: oclint-rules/rules/cocoa/ObjCVerifyProhibitedCallRule.cpp
    说明:验证禁止引用,当一个方法声明时含有attribute((annotate("oclint:enforce[prohibited call]"))),它的所有调用都是被禁止的。

    @interface A : NSObject
    - (void)foo __attribute__((annotate("oclint:enforce[prohibited call]")));
    @end
    
    @implementation A
    - (void)foo {
    }
    - (void)bar {
        [self foo]; // calling method `foo` is prohibited.
    }
    @end
    

    4.Verify Protected Method
    说明:验证 Protected 方法。protected 标记 Objective-C 虽然没有语言级别的限制, 但是从设计角度有时候希望他只能被自己以及子类访问. 此规则当开发人员调用的时候给予一个警告。当一个方法声明含有attribute((annotate("oclint:enforce[protected method]")))时,只有它和它的子类可以调用,因为OC中没有Protected,可以用这种方式达到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
    

    5.Subclass Must Implement
    定义类: oclint-rules/rules/cocoa/ObjCVerifySubclassMustImplementRule.cpp
    说明:子类必须实现,哪怕是一个抽象方法。这条规则用来验证抽象方法是被子类实现的。

    @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(约定)
    1.Avoid Branching Statement As Last InLoop
    定义类:oclint-rules/rules/convention/AvoidBranchingStatementAsLastInLoopRule.cpp
    说明:表示不要在for循环或者其他循环语句的末尾使用break.在循环最后加入分支,理解起来会比较混乱,并且很有可能因为忘记而引起一些错误

    void example()
    {
        for (int i = 0; i < 10; i++)
        {
            if (foo(i))
            {
                continue;
            }
            break;      // this break is confusing
        }
    }
    

    2.Base Class Destructor Should Be Virtual Or Protected
    定义类: oclint-rules/rules/convention/BaseClassDestructorShouldBeVirtualOrProtectedRule.cpp
    说明:基类的析构函数要么是公共的虚函数,要么是保护性的非虚函数。

    class Base
    {
    public:
        ~Base(); // this should be either protected or virtual
    }
    class C : public Base
    {
        virtual ~C();
    }
    

    3.covered switch statements dont need default
    定义类: oclint-rules/rules/convention/CoveredSwitchStatementsDontNeedDefaultRule.cpp
    说明:全覆盖的Switch不需要默认值 ,因为已经覆盖了所有的switch分支,所以不需要写default break部分。

    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.
        }
    }
    

    4.Default Label Not Last In Switch Statement
    定义类: oclint-rules/rules/convention/DefaultLabelNotLastInSwitchStatementRule.cpp
    说明:默认值没有在Switch的最后 ,默认值应该在switch语句的最后,不然代码会很混乱。

    void example(int a)
    {
        switch (a) {
            case 1:
                break;
            default:  // the default case should be last
                break;
            case 2:
                break;
        }
    }
    

    5.Destructor Of VirtualClass
    定义类: oclint-rules/rules/convention/DestructorOfVirtualClassRule.cpp
    说明:虚拟类的析构函数,本规则强制要求虚类的析构函数必须也是虚函数。

    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
    };
    

    6.Inverted Logic
    定义类: oclint-rules/rules/convention/InvertedLogicRule.cpp
    说明:倒置逻辑,反转逻辑让人难以理解。一般是指用(!a)而非(a)来判断让人难以理解。

    int example(int a)
    {
        int i;
        if (a != 0)             // if (a == 0)
        {                       // {
            i = 1;              //      i = 0;
        }                       // }
        else                    // else
        {                       // {
            i = 0;              //      i = 1;
        }                       // }
    
        return !i ? -1 : 1;     // return i ? 1 : -1;
    }
    

    7.Missing Break In Switch Statement
    定义类: oclint-rules/rules/convention/MissingBreakInSwitchStatementRule.cpp
    说明:Switch语句丢失Break,在Switch中如果缺少break很容易引入bug.

    void example(int a)
    {
        switch (a) {
            case 1:
                break;
            case 2:
                // do something
            default:
                break;
        }
    }
    

    8.Non Case Label In Switch Statement
    定义类: oclint-rules/rules/convention/NonCaseLabelInSwitchStatementRule.cpp
    说明:标签作为Switch语句的一部分是无法让人理解,不要把label放到switch中。

    void example(int a)
    {
        switch (a) {
            case 1:
                break;
            label1:     // label in a switch statement in really confusing
                break;
            default:
                break;
        }
    }
    

    9.ivar assignment outside accessors or init
    定义类: oclint-rules/rules/convention/ObjCAssignIvarOutsideAccessorsRule.cpp
    说明:这个规则限制外部访问其直接访问或者初始化,意思是某些成员的初始化不在getter/setter或者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
    

    10.parameter reassignment
    定义类: oclint-rules/rules/convention/ParameterReassignmentRule.cpp
    说明:参数值重置,通常认为是赋值问题,具体问题需要具体判断,有的时候是因为对传来的参数进行了重新赋值,大多数时候不能修改。

    void example(int a)
    {
        if (a < 0)
        {
            a = 0; // reassign parameter a to 0
        }
    }
    

    11.use early exits and continue
    定义类: oclint-rules/rules/convention/PreferEarlyExitRule.cpp
    说明:用短判断退出然后继续执行,意思是,有其他出口时,先执行其他出口,再继续代码。

    int *doSomething(int a) {
      if (!foo(a) && bar(a) && doOtherThing(a)) {
        // ... some really long code ....
      }
    
      return 0;
    }
    
    // is preferred as
    
    int *doSomething(int a) {
      if (foo(a)) {
        return 0;
      }
    
      if (!bar(a)) {
        return 0;
      }
    
      if (!doOtherThing(a)) {
        return 0;
      }
    
      // ... some long code ....
    }
    

    12.Switch Statements Should Have Default
    定义类: oclint-rules/rules/convention/SwitchStatementsShouldHaveDefaultRule.cpp
    说明:Switch 语句应该有一个默认值 ,如果并不是每一个分支都有一条路径,那么switch重必须含有default.

    void example(int a)
    {
        switch (a) {
            case 1:
                break;
            case 2:
                break;
            // should have a default
        }
    }
    

    13.Too Few Branches In Switch Statement
    定义类: oclint-rules/rules/convention/TooFewBranchesInSwitchStatementRule.cpp
    说明:Switch中分支很少,可以用if代替。

    void example(int a)
    {
        switch (a) {
            case 1:
                break;
            default:
                break;
        } // Better to use an if statement and check if variable a equals 1.
    }
    

    Design(设计)

    1.Avoid Default Arguments On Virtual Methods
    定义类: oclint-rules/rules/design/AvoidDefaultArgumentsOnVirtualMethodsRule.cpp
    说明:避免给虚函数设置默认参数,给虚函数设置默认参数会破坏多样性和引起不必要的层次结构发杂性。

    class Foo
    {
    public:
        virtual ~Foo();
        virtual void a(int b = 3);
        // ...
    };
    
    class Bar : public Foo
    {
    public:
        void a(int b);
        // ...
    };
    
    Bar *bar = new Bar;
    Foo *foo = bar;
    foo->a();   // default of 3
    bar->a();   // compile time error!
    

    2.Avoid Private Static Members
    定义类: oclint-rules/rules/design/AvoidPrivateStaticMembersRule.cpp
    说明:避免使用私有静态成员,静态成员很容易破换封装性。

    class Foo
    {
        static int a;       // static field
    };
    class Bar
    {
        static int b();     // static method
    }
    

    Empty
    1.Empty Catch Statement
    定义类: oclint-rules/rules/empty/EmptyCatchStatementRule.cpp
    说明:主要发生在一个异常exception被catch到了,但是却没有对此做任何操作。

    void example()
    {
        try
        {
            int* m= new int[1000];
        }
        catch(...)                  // empty catch statement, this swallows an exception
        {
        }
    }
    

    2.Empty Do While Statement
    定义类: oclint-rules/rules/empty/EmptyDoWhileStatementRule.cpp
    说明:在do-while循环中没有做任何事情。

    void example()
    {
        do
        {                           // empty do-while statement
        } while(1);
    }
    

    3.Empty Else Block
    定义类: oclint-rules/rules/empty/EmptyElseBlockRule.cpp
    说明:空else语句,在if中有操作,else中却是空的,此时else可以被安全移除。

    int example(int a)
    {
        if (1)
        {
            return a + 1;
        }
        else                // empty else statement, can be safely removed
        {
        }
    }
    

    4.Empty Finally Statemen
    定义类: oclint-rules/rules/empty/EmptyFinallyStatementRule.cpp
    说明:空Finally语句,在@finally中没有进行任何操作。

    void example()
    {
        Foo *foo;
        @try
        {
            [foo bar];
        }
        @catch(NSException *e)
        {
            NSLog(@"Exception occurred: %@", [e description]);
        }
        @finally            // empty finally statement, probably forget to clean up?
        {
        }
    }
    

    5.Empty For Statement
    定义类: oclint-rules/rules/empty/EmptyForStatementRule.cpp
    说明:空for语句,for循环为空。

    void example(NSArray *array)
    {
        for (;;)                // empty for statement
        {
        }
    
        for (id it in array)    // empty for-each statement
        {
        }
    }
    

    6.Empty If Statement
    定义类: oclint-rules/rules/empty/EmptyIfStatementRule.cpp
    说明:空IF语句,if中代码为空。

    void example(int a)
    {
        if (a == 1)                  // empty if statement
        {
        }
    }
    

    7.Empty Switch Statement
    定义类: oclint-rules/rules/empty/EmptySwitchStatementRule.cpp
    说明:空Switch语句,Switch中代码为空。

    void example(int i)
    {
        switch (i)              // empty switch statement
        {
        }
    }
    

    8.Empty Try Statement
    定义类: oclint-rules/rules/empty/EmptyTryStatementRule.cpp
    说明:空Try语句检测,try中代码为空。

    void example()
    {
        try                     // but this try statement is empty
        {
        }
        catch(...)
        {
            cout << "Exception is caught!";
        }
    }
    

    9.Empty While Statement
    定义类: oclint-rules/rules/empty/EmptyWhileStatementRule.cpp
    说明:检测空的While语句,While循环中没有代码。

    void example(int a)
    {
        while(a--)              // empty while statement
        {
        }
    }
    

    Migration(迁移)

    1.Replace With Boxed Expression
    定义类: oclint-rules/rules/migration/ObjCBoxedExpressionsRule.cpp
    说明:可以迁移到oc的新的表达方式,用来说明umberWithInt和stringWithUTF8String:getenv的简写形式。

    void aMethod()
    {
        NSNumber *fortyTwo = [NSNumber numberWithInt:(43 - 1)];
        // NSNumber *fortyTwo = @(43 - 1);
    
        NSString *env = [NSString stringWithUTF8String:getenv("PATH")];
        // NSString *env = @(getenv("PATH"));
    }
    

    2.Replace With Container Literal
    定义类: oclint-rules/rules/migration/ObjCContainerLiteralsRule.cpp
    说明:用来说明arrayWithObjects和dictionaryWithObjects的简写形式。

    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 };
    }
    

    3.replace with number literal
    定义类: oclint-rules/rules/migration/ObjCNSNumberLiteralsRule.cpp
    说明:用来说明numberWithInt和numberWithBOOL的简写形式。

    void aMethod()
    {
        NSNumber *fortyTwo = [NSNumber numberWithInt:42];
        // NSNumber *fortyTwo = @42;
    
        NSNumber *yesBool = [NSNumber numberWithBool:YES];
        // NSNumber *yesBool = @YES;
    }
    

    4.replace with object subscripting
    定义类: oclint-rules/rules/migration/ObjCObjectSubscriptingRule.cpp
    说明:用来说明objectAtIndex和objectForKey的简写形式。

    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(命名)

    1.Long Variable Name
    定义类: oclint-rules/rules/naming/LongVariableNameRule.cpp
    说明:命名太长。
    default:20

    void aMethod()
    {
        int reallyReallyLongIntegerName;
    }
    

    2.Short Variable Name
    定义类: oclint-rules/rules/naming/ShortVariableNameRule.cpp
    说明:命名过短。
    default:3

    void aMethod(int i)  // i is short
    {
        int ii;          // ii is short
    }
    

    Redundant
    1.Redundant Conditional Operator
    定义类: oclint-rules/rules/redundant/RedundantConditionalOperatorRule.cpp
    说明:冗余的条件运算符,可以一步到位的判断,不需要进行多余比较。

    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;
    }
    

    2.Redundant If Statement
    定义类: oclint-rules/rules/redundant/RedundantIfStatementRule.cpp
    说明:if判断是多余的。

    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;
    }
    

    3.Redundant local variable
    定义类: oclint-rules/rules/redundant/RedundantLocalVariableRule.cpp
    说明:return中的参数可以使用一个表达式来表示,检测声明的本地变量直接返回的情况。

    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;
    

    4.RedundantNilCheck
    定义类: oclint-rules/rules/redundant/RedundantNilCheckRule.cpp
    说明:在C或者C++中适用的判空检查在OC中是多余的。因为在OC中向空对象发送消息会返回false值。

    + (void)compare:(A *)obj1 withOther:(A *)obj2
    {
        if (obj1 && [obj1 isEqualTo:obj2]) // if ([obj1 isEqualTo:obj2]) is okay
        {
        }
    }
    

    5.UnnecessaryElseStatement
    定义类: oclint-rules/rules/redundant/UnnecessaryElseStatementRule.cpp
    说明:如果if中已经带有return,则不需要写else语句。

    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."
        }                           //
    }
    

    6.Unnecessary Null Check For Dealloc
    定义类: oclint-rules/rules/redundant/UnnecessaryNullCheckForCXXDeallocRule.cpp
    说明:在Dealloc中不需要判空,就能Delete元素。

    void m(char* c) {
        if (c != nullptr) { // and be simplified to delete c;
            delete c;
        }
    }
    

    7.useless parentheses
    定义类: oclint-rules/rules/redundant/UselessParenthesesRule.cpp
    说明:用来表示有些括号是不必要的。

    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(大小)

    1.High Cyclomatic Complexity
    定义类: oclint-rules/rules/size/CyclomaticComplexityRule.cpp
    说明:圈复杂度过高。圈复杂度(CyclomaticComplexity)是很常用的一种度量软件代码复杂程度的标准。这里所指的“代码复杂程度”并非软件内在业务逻辑的复杂程度,而是指代码的实现方式的复杂程度。有很多研究统计指出,圈复杂度高的代码中错误的可能性更大,维护的成本更高。
    简单的说它就是统计一个函数有多少个分支(if, while,for,等等),没有的话复杂度为一,每增加一个分支复杂度加一。让很多人不解的是,无论这些分支是并列还是嵌套,统统都是加一。
    default:10
    禁止检查:

    __attribute__((annotate("oclint:suppress[high cyclomatic complexity]")))
    

    例如:

    void example(int a, int b, int c) // 1
    {
        if (a == b)                   // 2
        {
            if (b == c)               // 3
            {
            }
            else if (a == c)          // 3
            {
            }
            else
            {
            }
        }
        for (int i = 0; i < c; i++)   // 4
        {
        }
        switch(c)
        {
            case 1:                   // 5
                break;
            case 2:                   // 6
                break;
            default:                  // 7
                break;
        }
    }
    

    2.Long Class
    定义类: oclint-rules/rules/size/LongClassRule.cpp
    说明:类行数太多。
    default:1000

    class A
    {
        void bar()
        {
            // 1001 lines of code
        }
    }
    

    3.Long Line
    定义类: oclint-rules/rules/size/LongLineRule.cpp
    说明:一行字数过多。
    default:100

    4.Long Method
    定义类:oclint-rules/rules/size/LongMethodRule.cpp
    说明:在一个方法中试图完成很多事情,在一个方法中应该完成一个功能并把它做好。
    default:50

    void example()
    {
        NSLog ("hello world");
        NSLog ("hello world");
        // repeat 48 times
    }
    

    5.High Ncss Method
    定义类: oclint-rules/rules/size/NcssMethodCountRule.cpp
    说明:其实是指某个代码块中代码行数过多,查看代码块中代码是否能拆分,公共功能能否提供一个公共借口。
    有效代码行,系统只计算实际的有效语句。空语句,空块,右括号或分号后的右括号会被忽略。一个被分解成多行的语句只计算一行。
    default:30
    禁止检查:

    __attribute__((annotate("oclint:suppress[high ncss method]")))
    

    例如:

    void example()          // 1
    {
        if (1)              // 2
        {
        }
        else                // 3
        {
        }
    }
    

    6.Deep Nested Block
    定义类: oclint-rules/rules/size/NestedBlockDepthRule.cpp
    说明:层次太深,多层嵌套。
    default:5

    if (1)
    {               // 1
        {           // 2
            {       // 3
            }
        }
    }
    

    7.High NPath Complexity
    定义类: oclint-rules/rules/size/NPathComplexityRule.cpp
    说明:NPath复杂度是一个方法中各种可能的执行路径总和,一般把200作为考虑降低复杂度的临界点,这里提示NPath复杂度过高。
    default:200
    禁止检查:

    __attribute__((annotate("oclint:suppress[high npath complexity]")))
    

    例如:

    void example()
    {
        // complicated code that is hard to understand
    }
    

    8.Too Many Fields
    定义类: oclint-rules/rules/size/TooManyFieldsRule.cpp
    说明:一个类中有太多的域表示它的东西太多了,需要进行适当的抽象。
    default:20

    class c
    {
        int a, b;
        int c;
        // ...
        int l;
        int m, n;
        // ...
        int x, y, z;
    
        void m() {}
    };
    

    9.Too Many Methods
    定义类: oclint-rules/rules/size/TooManyMethodsRule.cpp
    说明:一个类中方法过多。
    default:30

    class c
    {
        int a();
        int b();
        int c();
       // 30个
    };
    

    10.Too Many Parameters
    定义类: oclint-rules/rules/size/TooManyParametersRule.cpp
    说明:一个方法中参数过多。方法中有太多的参数是难以理解和后期维护的。
    default:10

    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(无用)

    1.Unused Local Variable
    定义类: oclint-rules/rules/unused/UnusedMethodParameterRule.cpp
    说明:没有被使用的局部变量。
    禁止检查:

    __attribute__((annotate("oclint:suppress[unused local variable]")))
    

    例子:

    int example(int a)
    {
        int i;          //  variable i is declared, but not used
        return 0;
    }
    

    2.Unused Method Parameter
    定义类: oclint-rules/rules/unused/UnusedMethodParameterRule.cpp
    说明:没有被使用的方法参数,请谨慎修改
    禁止检查:

    __attribute__((annotate("oclint:suppress[unused method parameter]")))
    

    例子:

    int example(int a)  // parameter a is not used
    {
        return 0;
    }
    

    二.忽略 修改 禁止某些规则

    忽略: 使用命令:oclint-json-compilation-database的-e 参数忽略指定的文件,比如忽略Pods文件夹下面的检查:

    oclint-json-compilation-database -e Pods -- -o=report.html
    

    修改: -rc 改变检查规则的默认值:

    oclint-json-compilation-database  -- -rc=LONG_LINE=200 -o=report.html
    

    禁止:禁止某一个规则的使用可以使用命令-disable-rule:

    oclint-json-compilation-database -disable-rule=LongLine
    

    三.项目中某句代码或者某段代码不使用oclint

    1. 注解:可以使用注解的方法禁止OCLint的检查,语法是:
    __attribute__((annotate("oclint:suppress[unused method parameter]")))
    

    例如我们知道一个参数没有使用,而又不想产生警告信息就可以这样写:

    - (IBAction)turnValueChanged:
     (id) __attribute__((annotate("oclint:suppress[unused method parameter]"))) sender {
        int i;  // won't suppress this one
        [self test];
    }
    

    对于方法的注解可以这样写:

    bool __attribute__((annotate("oclint:suppress"))) aMethod(int aParameter) {
        // warnings within this method are suppressed at all
        // like unused aParameter variable and empty if statement
        if (1) {}
        return true;
    }
    
    1. !OCLint:通过//!OCLint注释的方式,不让OCLint检查。比如:
    void a() {
        int unusedLocalVariable;  //!OCLINT
    }
    

    对于空的if/else禁止检查的注释为:

    if (true)  //!OCLint  {
        // it is empty
    }
    

    相关文章

      网友评论

        本文标题:OCLint的规则

        本文链接:https://www.haomeiwen.com/subject/ddwztltx.html