Skip to main content

无需关心 C/C++ 头文件的代码分析器。它适用于 Java、C/C++、JavaScript、Python、Ruby、Swift、Objective C。指标包括圈复杂度数等。

项目描述

https://travis-ci.org/terryyin/lizard.png?branch=master https://badge.fury.io/py/lizard.svg

Lizard 是一个可扩展的圈复杂度分析器,适用于许多编程语言,包括 C/C++(不需要所有头文件或 Java 导入)。它还进行复制粘贴检测(代码克隆检测/代码重复检测)和许多其他形式的静态代码分析。

支持的语言列表:

  • C/C++(适用于 C++14)

  • 爪哇

  • C# (C 夏普)

  • JavaScript(使用 ES6 和 JSX)

  • 打字稿

  • Objective-C

  • 迅速

  • Python

  • 红宝石

  • TTCN-3

  • PHP

  • 斯卡拉

  • GDScript

  • 戈朗

  • 卢阿

  • Fortran

  • 科特林

默认情况下,lizard会搜索它知道的任何源代码并将所有结果混合在一起。这可能不是你想要的。您可以使用“-l”选项来选择语言。

它很重要

  • nloc(没有注释的代码行),

  • CCN(圈复杂度数),

  • 函数的令牌计数。

  • 函数的参数计数。

您可以设置 CCN (-C) 的限制,参数的数量 (-a)。超出这些限制的函数将生成警告。如果有警告,lizard的退出代码将非零。

这个工具实际上计算代码“看起来”的复杂程度,而不是代码真正的“复杂程度”。人们将需要此工具,因为当它们很复杂时,通常很难正确获取所有包含的文件夹和文件。但是对于圈复杂度,我们真的不需要那种精度。

需要python2.7以上(早期版本未验证)。

安装

lizard.py 可以用作独立的 Python 脚本,大部分功能都在那里。您可以随时使用它而无需任何安装。要获得lizard的所有功能,您需要正确安装。

python lizard.py

如果您想要正确安装:

[sudo] pip install lizard

或者,如果您有来源:

[sudo] python setup.py install --install-dir=/path/to/installation/directory/

用法

lizard [options] [PATH or FILE] [PATH] ...

运行当前文件夹下的代码(递归):

lizard

排除测试文件夹中的任何内容:

lizard mySource/ -x"./tests/*"

选项

-h, --help 显示此帮助信息并退出
--version 显示程序的版本号并退出
-l 语言,--语言语言
                      列出您要分析的编程语言。如果留空,它将
                      搜索它知道的所有语言。`lizard -l cpp -l java`搜索
                      C++ 和 Java 代码。可用的语言有:cpp、java、csharp、
                      javascript,python,objectivec,ttcn,ruby,php,swift,scala,GDScript,
                      去,lua,锈,打字稿
-V, --verbose 以详细模式输出(长函数名)
-C CCN, --CCN CCN 圈复杂度数警告的阈值。默认值为
                      15. CCN大于它的函数会产生警告
-f INPUT_FILE, --input_file INPUT_FILE
                      从给定文件中获取文件名列表
-o OUTPUT_FILE, --output_file OUTPUT_FILE
                      输出文件。输出格式是从文件扩展名推断出来的(例如
                      .html),除非明确指定(例如使用--xml)。
-L 长度,--长度长度
                      最大函数长度警告的阈值。默认值为 1000。
                      函数长度大于它会产生警告
-a 参数,--参数参数
                      参数数量限制
-w, --warnings_only 仅显示警告,使用 clang/gcc 的警告格式进行打印
                      警告。http://clang.llvm.org/docs/UsersManual.html#cmdoption-
                      fdiagnostics 格式
--warning-msvs 仅显示警告,使用 Visual Studio 的警告格式进行打印
                      警告。https://msdn.microsoft.com/en-us/library/yxkt8b26.aspx
-i NUMBER,--ignore_warnings NUMBER
                      如果警告的数量等于或小于该数量,该工具将
                      正常退出;否则会产生错误。如果号码是
                      负数,无论警告次数如何,工具都会正常退出。
                      在遗留代码的 makefile 中很有用。
-x 排除,--排除排除
                      排除与模式匹配的文件。* 匹配所有内容,?匹配任何
                      单个字符,“./folder/*”排除文件夹中的所有内容
                      递归地。可以指定多个模式。不要忘记添加“”
                      图案周围。
-t WORKING_THREADS,--working_threads WORKING_THREADS
                      工作线程数。默认值为 1。使用更大的数字
                      可以充分利用 CPU,而且速度通常更快。
-X, --xml 以 cppncss 样式生成 XML,而不是表格输出。有用的
                      在 Jenkins 服务器中生成报告
--csv 生成 CSV 输出作为默认输出的转换
-H, --html 输出 HTML 报告
-m, --modified 计算修改后的圈复杂度数,计算一个
                      多个case作为一个CCN的switch/case。
-E 扩展,--扩展扩展
                      使用扩展。可用的扩展是: -Ecpre:它将忽略
                      #else 分支中的代码。-Ewordcount:计算词频和
                      生成标签云。-Eoutside:将全局代码作为一个函数包含在内。
                      -EIgnoreAssert:忽略断言中的所有代码。-ENS:计数嵌套控件
                      结构。
-s 排序,--排序排序
                      使用字段对警告进行排序。该字段可以是nloc,
                      cyclomatic_complexity、token_count、parameter_count 等或自定义字段。
-T 阈值,--阈值阈值
                      设置字段的限制。该字段可以是 nloc、cyclomatic_complexity、
                      token_count、parameter_count 等。或者自定义文件。lizard会
                      如果函数超出限制,则报告警告
-W WHITELIST, --whitelist WHITELIST
                      白名单文件的路径和文件名。它是 './whitelizard.txt' 由
                      默认。在自述文件中查找更多信息。

示例使用

递归分析文件夹:lizard mahjong_game/src

==============================================================
  NLOC    CCN  token  param    function@line@file
--------------------------------------------------------------
    10      2     29      2    start_new_player@26@./html_game.c
   ...
     6      1      3      0    set_shutdown_flag@449@./httpd.c
    24      3     61      1    server_main@454@./httpd.c
--------------------------------------------------------------
2 file analyzed.
==============================================================
LOC    Avg.NLOC AvgCCN Avg.ttoken  function_cnt    file
--------------------------------------------------------------
    191     15      3        51        12     ./html_game.c
    363     24      4        86        15     ./httpd.c

======================================
!!!! Warnings (CCN > 15) !!!!
======================================
    66     19    247      1    accept_request@64@./httpd.c
=================================================================================
Total NLOC  Avg.NLOC  Avg CCN  Avg token  Fun Cnt  Warning cnt   Fun Rt   NLOC Rt
--------------------------------------------------------------------------------
       554        20     4.07      71.15       27            1      0.04    0.12

仅警告(以 clang/gcc 形式):lizard -w mahjong_game

./src/html_ui/httpd.c:64: warning: accept_request has 19 CCN and 1 params (66 NLOC, 247 tokens)
./src/mahjong_game/mj_table.c:109: warning: mj_table_update_state has 20 CCN and 1 params (72 NLOC, 255 tokens)

为任何字段设置警告阈值:lizard -T nloc=25

选项-Tcyclomatic_complexity=10等于-C10。选项-Tlength=10等于-L10。选项-Tparameter_count=10等于-a10

您也可以执行-Tnloc=10来设置 NLOC 的限制。NLOC 大于 10 的任何函数都会生成警告。

生成的代码

Lizard 有一个生成代码的简单解决方案。源文件中任何跟在包含“生成代码”的注释后面的代码都将被完全忽略。忽略的代码不会生成任何数据,除了文件计数。

代码重复检测器

lizard -Eduplicate <path to your code>

为您的代码生成标签云

您可以通过以下命令生成代码的“标签云”。它计算代码中的标识符(忽略注释)。

lizard -EWordCount <path to your code>

使用lizard作为 Python 模块

您还可以在代码中使用 lizard 作为 Python 模块:

>>> import lizard
>>> i = lizard.analyze_file("../cpputest/tests/AllTests.cpp")
>>> print i.__dict__
{'nloc': 9, 'function_list': [<lizard.FunctionInfo object at 0x10bf7af10>], 'filename': '../cpputest/tests/AllTests.cpp'}
>>> print i.function_list[0].__dict__
{'cyclomatic_complexity': 1, 'token_count': 22, 'name': 'main', 'parameter_count': 2, 'nloc': 3, 'long_name': 'main( int ac , const char ** av )', 'start_line': 30}

您也可以使用源代码字符串代替文件。但是您需要提供一个文件名(以识别语言)。

>>> i = lizard.analyze_file.analyze_source_code("AllTests.cpp", "int foo(){}")

白名单

如果由于某种原因您想忽略警告,您可以使用白名单。将'whitelizard.txt'添加到当前文件夹(或使用-W指向白名单文件),则文件中定义的函数将被忽略。请注意,如果您指定文件路径名,它需要与 Lizard 完全相同的相对路径才能找到文件。获取文件路径名的一种简单方法是从 Lizard 警告输出中复制它。这是一个示例白名单:

#whitelizard.txt
#The file name can only be whitelizard.txt and put it in the current folder.
#You may have commented lines begin with #.
function_name1, function_name2 # list function names in multiple lines or split with comma.
file/path/name:function1, function2  # you can also specify the filename

评论中的选项

您可以使用源代码注释中的选项来更改lizard的行为。通过将“#lizard forgets”放在函数内部或函数之前,它将抑制该函数的警告。

int foo() {
    // #lizard forgives the complexity
    ...
}

限制

Lizard 需要语法正确的代码。在处理语法不正确或未知的输入时:

  • Lizard 保证在没有硬故障(例如退出、崩溃、异常)的情况下最终终止(即没有永远循环、挂起)。

  • 可能会同时出现以下软故障:

    • 省略

    • 误解

    • 不正确的分析/统计

    • 成功(考虑中的代码不相关,例如 C 中的全局宏)

这种方法使 Lizard 实现更简单,更专注于各种语言的部分解析器。Lizard 的开发人员试图将软故障的可能性降到最低。硬故障是 Lizard 代码中的错误,而软故障是权衡或潜在错误。

除了断言正确的代码之外,Lizard 可能会选择不处理一些高级或复杂的语言特性:

  • 无法识别 C/C++ 二合字母和三合字母。

  • 不执行 C/C++ 预处理或宏扩展。例如,使用宏而不是括号(或宏中的部分语句)可能会混淆 Lizard 的括号堆栈。

  • 一些 C++ 复杂模板可能会导致与匹配尖括号和处理模板参数内的小于<或大于>运算符混淆。

提到lizard的文献

Lizard 经常用于软件相关的研究。如果您使用它来支持您的工作,您可以联系lizard作者将您的工作添加到以下列表中。

Lizard 还用作 fastlane 的插件,以帮助检查代码复杂性并将 xml 报告提交给声纳。