[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
orx % 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
- [OCLint]OCLint代码检查规则
- oclint规则
- oclint 规则选择
- oclint规则 Cocoa
- oclint规则 Empty
- oclint规则 Migration(迁移)
- oclint规则 Naming(命名)
- oclint规则 索引
- OCLint 如何自定义规则
- 静态代码扫描--OCLint
- 【指导】iOS代码静态检查 -- oclint (+ xcodebuild + xcpretty + jenkins)
- oclint 基本规则介绍 Basic
- oclint规则 Convention(公约)
- oclint规则 Size(大小)
- oclint规则 Unused(无用)
- [OCLint]OCLint 介绍
- [OCLint]OCLint安装
- [OCLint]OCLint教程
- Android开发记录16-友盟第三方登录、分享实现
- 80x86汇编语言编程:在屏幕上显示彩色 ASCII 码
- 北美崔哥博文: 外国移民说--“世界末日”就是中国人来了!
- [Java并发包学习八]深度剖析ConcurrentHashMap
- 单片机 AT89C51 汇编语言编写报警信号程序
- [OCLint]OCLint代码检查规则
- 拨盘开关输入方法
- 阿里云绿网怎么关闭
- 键盘编码芯片 MM74C922
- 用 LCD1602 显示的秒表
- ngnix 启动,停止和信号控制
- PROTEUS 仿真中的总线
- 工作感悟(1)
- 用 Python 脚本实现对 Linux 服务器的监控