OCLint 如何自定义规则

一 、准备开发环境

  • mac系统安装有Xcode,git,ruby(一般都会有),还有要会科学上网

  • 在OCLint的github上clone下代码 https://github.com/oclint/oclint 。(不要下载官方网站的代码),目录如下:

    ├── README.md
    ├── oclint-core
    ├── oclint-driver
    ├── oclint-metrics
    ├── oclint-reporters
    ├── oclint-rules
    └── oclint-scripts
  • cd进入oclint-scripts文件加,执行./make。大约30分钟后编译完成,大概过程是下载LLVM、clang的源代码,编译LLVM、clang与OCLint预计OCLint的默认规则。(如果通过官网下载的OCLint代码,执行make时会通过SVN下载LLVM的代码,然而即便我科学上网了还是总是下载不成功,建议直接同git上下载OCLint的源码)

  • 编译成功后就可以写规则并且编译执行了。为了方便,OCLint提供了一个叫scaffoldRule的脚本程序,它在oclint-rules目录下。我们通过他传入要生成的规则名,级别,类型,脚本就会在目录oclint-rules/rules/custom/自动帮我们生成一个模板代码,并且加入编译路径中。举个例子:

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

    生成两个文件:

    
    # CMakeLists.txt 是对规则HdwTestRule的编译描述,由make程序在编译时使用。HdwTestRule.cpp的内容之后再分析。
    
    ├── custom
    │   ├── CMakeLists.txt
    │   └── HdwTestRule.cpp
  • 接着就可以对新添加的内容进行编译了,不过相比于重新执行oclint-scripts/make来说有一个更加优雅的办法,就是将规则相关的内容整合成一个Xcode工程,并且我们的每个规则都是一个scheme,编译时可以只选择编译那个选择的规则生成对应的dylib。做饭很简单,OCLint工程使用CMakeLists的方式维护各个文件的依赖关系,我们可以使用CMake自带的功能将这些CMakeLists生成一个xcodeproj工程文件。but how?下面栗子:

    
    # 在OCLint源码目录下建立一个文件夹,我这里命名为oclint-xcoderules
    
    mkdir oclint-xcoderules
    cd oclint-xcoderules
    
    # 创建一个脚本(代码如下段),并执行它(我写的方便修改参数,其实里面就一句命令,直接执行也行)(PS:刚创建的文件是没有执行权限的,不要忘了chmod)
    
    ./create-xcode-rules.sh
    
    #! /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

    于是我们就得到了xcode工程:

    ├── CMakeCache.txt
    ├── CMakeFiles
    ├── CMakeScripts
    ├── OCLINT_RULES.build
    ├── OCLINT_RULES.xcodeproj
    ├── cmake_install.cmake
    ├── create-xcode-rules.sh
    ├── lib
    ├── rules
    └── rules.dl

    打开OCLINT_RULES.xcodeproj:

    这里写图片描述

  • 选择自己的规则,编译,成功后就可以在Products下看到生成的dylib啦,想想还有点小激动呢

二、开发规则

上面准备环境的一些步骤其实都是来自对OCLint官网的总结,同样如何去写自定义的规则还是要去看文档 http://docs.oclint.org/en/stable/ ,甚至于还要看clang的文档 http://clang.llvm.org/docs/IntroductionToTheClangAST.html 。我这里只能给出一些小建议,大概就是如何123去完成自定义的规则,希望再你阅读完文档但是不知道如何下手的时候能够帮到忙。

寓言故事

小明看了OCLint的官方文档,了解了一下clang AST的知识,并读了一些OCLint AST的源码,大概知道OCLint调用clang 的API把一个个源文件生成一个一个AST,然后遍历树中的每个节点传入各个规则的整个过程。然后小明按照与上面类似的步骤最终生成并打开了OCLINT_RULES.xcodeproj。他觉得最好的学习方式是先阅读OCLint给出的默认规则的代码,大概读了几个后他似有所悟,于是就打开了之前自定义自动生成的HdwTestRule.cpp文件开始自己编写。

小明决定写一个规则用于检查代码中“含有self的block中没有使用strongify”的那些block。

小明打开HdwTestRule.cpp,他看到一大堆(大概有两千行)注释代码,类似于:

class MissingStrongifyInCatchSelfBlockRule : public AbstractASTVisitorRule<MissingStrongifyInCatchSelfBlockRule>
    {
      /* Visit NullStmt
    bool VisitNullStmt(NullStmt *node)
    {
        return true;
    }
     */

    /* Visit CompoundStmt
    bool VisitCompoundStmt(CompoundStmt *node)
    {
        return true;
    }
     */

    /* Visit LabelStmt
    bool VisitLabelStmt(LabelStmt *node)
    {
        return true;
    }
     */

    /* Visit AttributedStmt
    bool VisitAttributedStmt(AttributedStmt *node)
    {
        return true;
    }
     */

    /* Visit IfStmt
    bool VisitIfStmt(IfStmt *node)
    {
        return true;
    }
     */

    /* Visit SwitchStmt
    bool VisitSwitchStmt(SwitchStmt *node)
    {
        return true;
    }
     */

    /* Visit WhileStmt
    bool VisitWhileStmt(WhileStmt *node)
    {
        return true;
    }
     */
    }

小明嘴角微微一笑,因为他知道,就在上午他刚读过的OCLint的源码中表明这些以Visit开头的百十个函数都是OCLint提供给开发者的回调函数。小明机智的按下了command + f输入了block,结果他找到了两个回调:

bool VisitBlockExpr(BlockExpr *node)
{
    return true;
}
bool VisitBlockDecl(BlockDecl *node)
{
    return true;
}
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值