OCLint 自定义规则

可能OCLint官方提供的检测规则不能满足我们的日常需求,OCLint也是支持自定义规则滴。

OCLint环境安装

参考:OCLint 安装使用

OCLint源码下载

OCLint 源码下载
下载下来之后,直接在 oclint-0.15/oclint-scripts下执行

./make

大概过程是下载LLVM、clang的源代码,编译LLVM、clang与OCLint预计OCLint的默认规则。
需要科学上网执行,即使是科学上网了也会有很大概率的失败。我的同事在家里科学上网失败了N次,好不容易成功一次,耗时小一天的时间。

为了大家快速方便,直接到gitHub下载我编译好的文件即可。大概5.8个G吧。大是大了点,比下不下来强。
https://github.com/yan998/oclint-0.15

开始开发

1、创建开发类
为了方便,OCLint提供了一个叫scaffoldRule的脚本,它在oclint-scripts目录下,我们通过他传入要生成的规则名,级别,类型,脚本就会在目录oclint-rules/rules/custom/自动帮我们生成一个模板代码,并且加入编译路径中。
命名的时候,不用写rule后缀,他自己会给你加上。

# 生成一个名为 JRMethodLint 类型是ASTVisitor的规则模板
oclint-scripts/scaffoldRule JRMethodLint -t ASTVisitor
image.png

2、生成Xcode开发项目

2.1、新建oclint-xcoderules文件夹
2.2、创建生成Xcode项目脚本
为了方便创建,我们新建脚本。
脚本使用cmake创建Xcode项目,cmake一款跨平台的编译工具,使用它构建的工程,既可以生成linux上的makefile,也可以生成Xcode的工程文件

#! /bin/sh -e

cmake -G Xcode -D CMAKE_CXX_COMPILER=../build/llvm-install/bin/clang++  -D CMAKE_C_COMPILER=../build/llvm-install/bin/clang -D OCLINT_BUILD_DIR=../build/oclint-core -D OCLINT_SOURCE_DIR=../oclint-core -D OCLINT_METRICS_SOURCE_DIR=../oclint-metrics -D OCLINT_METRICS_BUILD_DIR=../build/oclint-metrics -D LLVM_ROOT=../build/llvm-install/ ../oclint-rules

2.3、执行脚本生成Xcode项目

image.png

2.4、找到为我们创建的类和target
image.png

3、开始写代码了

3.1、简介
当前生成的类是一个cpp文件,当然我们也要用 c++进行开发。
W3C - C++ 教程 ,简单的看一下,能上手即可

也可以参考官方文档 OCLint 自定义规则文档

映入眼帘的是一堆被注释的方法。这些方法是干啥的呢?
这些以Visit开头的百十个函数都是OCLint提供给开发者的回调函数。

/* Visit ObjCMethodDecl
    bool VisitObjCMethodDecl(ObjCMethodDecl *node)
    {
        return true;
    }
     */

    /* Visit ObjCContainerDecl
    bool VisitObjCContainerDecl(ObjCContainerDecl *node)
    {
        return true;
    }
     */

    /* Visit ObjCCategoryDecl
    bool VisitObjCCategoryDecl(ObjCCategoryDecl *node)
    {
        return true;
    }
     */
。。。。。。。。

当OCLint分析到相关AST的时候就会调用相关的回调方法。

方法的返回值:
这些visit方法的返回布尔值用于控制遍历。AST访问者将在访问当前节点返回true时继续其子节点或同级节点,反之亦然,当当前visit方法返回false 时它将停止。

举个例子:
分析一个类所有的方法,如果在检测方法的回调方法返回false,那么就只会检测一个方法,不会继续往下检测。

我们来看下相关类的语法树,对应一下

clang -fmodules -fsyntax-only -Xclang -ast-dump student.m

可以看到AST中的节点,在OCLint中的回调方法都是可以找到的。


image.png

3.2、上手开发

     bool VisitObjCMethodDecl(ObjCMethodDecl *node)
    {
        //检查名称的每部分,都不允许以大写字母开头
        Selector sel = node -> getSelector();
        int selectorPartCount = node -> getNumSelectorLocs();
        
        for (int i = 0; i < selectorPartCount; i++) {
            // 方法参数名称
            StringRef selName = sel.getNameForSlot(i);
            if (selName.size() == 0) {
                return true;
            }
            char c = selName[0];
            if (isUppercase(c)) {
                // 提示
                // 获取将要报错的位置
                SourceLocation loc = node->getSelectorLoc(i);
                addViolation(loc, loc, this, "方法名/方法参数 建议小写开头");
            }
            if (c == '_') {
                // 提示
                // 获取将要报错的位置
                SourceLocation loc = node->getSelectorLoc(i);
                addViolation(loc, loc, this, "方法名/方法参数 不要以下划线开头");
            }
        }
        return true;
    }

4、动态调试

代码编写完了,怎么知道好不好使呢?可以不可以打印相关属性或者直接打断点进行调试呢?

4.1、配置 Executable
Edit sheme -->info --> Executable

编译好的 OCLint 的可执行文件
oclint-0.15/build/oclint-release/bin/oclintexe


image.png

4.2、配置 Arguments Passed On Launch
选择我们自定义的 ClassNameLintRule,添加启动参数。-R 传入自定义的规则名,这里使用调试工程生成的 Debug 目录。接着传入一个随便写的测试用文档 student.m,此文档所依赖的 Framework 等环境参数也需要传入。

-R /Users/a58/Desktop/Xcode_Plugin/oclint-0.15/oclint-xcoderules/rules.dl/Debug  /Users/a58/Desktop/smallDemo/XcodePlugin/OCLint/OCLintDemo001/OCLintDemo001/student.m  -- -x objective-c
-isystem /Users/a58/Desktop/Xcode_Plugin/oclint-0.15/build/oclint-release/lib/clang/9.0.0/include
-iframework /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/System/Library/Frameworks
-isystem /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/usr/include
image.png

run

image.png

发现已经发生作用了

4.3、编译成dylib,放到OCLint规则目录下,进行检测,生成报告
我们正常编译我们的JRMethodLintRule,就会生成dylib。不过我们需要修改成release模式进行编译

image.png

编译完成之后,将dylib放到/usr/local/lib/oclint/rules

image.png

4.4、编译项目的OClint

Xcode实现效果.png

生成报告一样,也会跑我们自定义的规则

5、遇到的问题

5.1、.h文件没有有被检测到

image.png

查询发现有网友也遇到了相关的问题
OCLint doesn't run rules against header files?

关于作者的回复

不检查头文件的原因是为了消除系统头带来的各种潜在问题。我们目前无法区分特定标头是来自Apple,来自第三方库/框架还是由用户编写。

还说他们是通过这句逻辑进行相关文件过滤的
https://github.com/oclint/oclint/blob/master/oclint-rules/include/oclint/AbstractASTVisitorRule.h#L31

那么我们可以把他的过滤条件给修改下,让他可以检测我们的.h文件

image.png

重新将新生成的dylib,放到/usr/local/lib/oclint/rules
搞定

image.png

5.2、在开发中遇到Expected unqualified-id错误

image.png

刚开始开发项目能正常的运行,不知道操作了啥,就不行了。不管是重新生成Xcode项目还是怎么滴,就是不行了,查了很多的资料,也没有能解决。
然后就想可能是Xcode的某个配置的问题,但是又不好找。Xcode缓存也删了,没啥用。
最终重新下载了Xcode,用新版Xcode 重试好了。

5.3、有些检测规则不想用,怎么删除
可能有以下官方的检测规则,不想使用,这个根据个人的项目来。
5.3.1、首先根据规则的报错信息,找到相关规则的动态库
比如我们想干掉 unused method parameter这个规则

image.png

因为一个方法里面有没有用到的参数,情况还是很多的,比如代理

来到我们的自定义规则开发项目,直接查询该警告的前面语句<他的这个报错内容是拼接起来的>

image.png

也就是这个类 UnusedMethodParameterRule。他最终编译的动态库的名字,应该就是 libUnusedMethodParameterRule
进入 /usr/local/lib/oclint/rules,删除即可
image.png

再次检测,就看不到相关警告了

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,463评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,868评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,213评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,666评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,759评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,725评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,716评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,484评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,928评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,233评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,393评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,073评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,718评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,308评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,538评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,338评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,260评论 2 352

推荐阅读更多精彩内容