swift/dart代码规范检查工具介绍

swift/dart代码规范检查工具介绍

简介:
本篇主要介绍swift和dart代码规范检查工具,以及他们的工作原理,操作过程,代码规范规则。

1 swift代码检查工具-swiftlint

1.1 介绍swiftlint

SwiftLint 是 realm 公司开发的一个插件,专门用于管理 Swift 代码的规范。

1.2 swiftlint工作原理

SwiftLint 的工作原理是检查 Swift 代码编译过程中的 AST 和 SourceKit 环节,从而可以摆脱不同版本 Swift 语法变化的影响。AST 是编译前端形成的抽象语法树(Abstract Symbolic Tree), SourceKit 过程用来对 AST 进行代码优化,减少内存开销,提高执行效率。如果对编译过程理解不太清楚,可以参考:Clang官方文档以及网络上两篇比较好的文章AST 和 LLVM优点以及戴铭的深入剖析 iOS 编译 Clang / LLVM

1.2.1 llvm编译过程

swift/dart代码规范检查工具介绍_第1张图片

编译过程

预处理 -> 词法分析 -> Token -> 语法分析 -> AST -> 代码生成 -> LLVM IR -> 优化 -> 生成汇编代码 -> Link -> 目标文件

1.2.2 SourceKit

SourceKit 是一套工具集,使得大多数 Swift 源代码层面的操作特性得以支持,例如源代码解析、语法高亮、排版(typesetting)、自动补全、跨语言头文件生成,等等
由于 SourceKit 是独立于Xcode之外的,所以可以利用以构建从 Swift IDE 到文档生成器等任何东西
例如第三方的工具

1.jazzy是一个命令行实用程序,可为Swift或Objective-C生成文档

1.3 swiftlint配置

1.3.1 swiftlint配置
具体环境安装配置详见官方文档,写的比较详细就不一一赘述了 swiftlint官方文档以及触发规则文档。

swiftlint操作大体流程:
->安装swiftlint
->配置工程脚本
->配置.swiftlint.yml规则文件到项目根目录
->编译代码
->触发规则的项目报error和warning
->通过命令行进行具体操作(见下文)
->根据触发的规则对比触发规则文档修改代码

看一下配置的文件.swiftlint.yml(通过配置.swiflint.yml,控制禁用/启用哪个规则,并为给定规则设置警告和错误的阈值)

disabled_rules: # 执行时排除掉的规则
  - colon
  - comma
  - control_statement
opt_in_rules: # 启用非默认设置的规则
  - empty_count
  - missing_docs
  # 可以通过执行如下指令来查找所有可用的规则:
  # swiftlint rules
included: # 执行 linting 时包含的路径。如果出现这个 `--path` 会被忽略。
  - Source
excluded: # 执行 linting 时忽略的路径。 优先级比 `included` 更高。
  - Carthage
  - Pods
  - Source/ExcludedFolder
  - Source/ExcludedFile.swift

# 可配置的规则可以通过这个配置文件来自定义
# 强制转换规则,可以设置他们的严重程度error,warning
force_cast: warning # 隐式
force_try:
  severity: warning # 显式
# 同时有警告和错误等级的规则,可以只设置它的警告等级
# 隐式
line_length: 110
# 可以通过一个数组同时进行隐式设置
type_body_length:
  - 300 # warning
  - 400 # error
# 或者也可以同时进行显式设置
file_length:
  warning: 500
  error: 1200
# 命名规则可以设置最小长度和最大程度的警告/错误
# 此外它们也可以设置排除在外的名字
type_name:
  min_length: 4 # 只是警告
  max_length: # 警告和错误
    warning: 40
    error: 50
  excluded: iPhone # 排除某个名字
identifier_name:
  min_length: # 只有最小长度
    error: 4 # 只有错误
  excluded: # 排除某些名字
    - id
    - URL
    - GlobalAPIKey
reporter: "xcode" # 报告类型 (xcode, json, csv, checkstyle, codeclimate, junit, html, emoji, sonarqube, markdown, github-actions-logging)

强制转换,严重级别设置warning和error两个等级

force_cast: warning # 隐式
force_try:
  severity: warning # 显式
可以查看规则文档SwiftLint-ruls示例

force_cast
非触发例子

NSNumber() as? Int

触发例子

NSNumber() as! Int

force_try 非触发例子

func a() throws {}
do {
  try a()
} catch {}

触发例子

func a() throws {}
try! a()

也可以自定义规则:

custom_rules:
  pirates_beat_ninjas: # 规则标识符
    name: "Pirates Beat Ninjas" # 规则名称,可选
    regex: "([nN]inja)" # 匹配的模式
    match_kinds: # 需要匹配的语法类型,可选
      - comment
      - identifier
    message: "Pirates are better than ninjas." # 提示信息,可选
    severity: error # 提示的级别,可选
  no_hiding_in_strings:
    regex: "([nN]inja)"
    match_kinds: string

输出样式:

swift/dart代码规范检查工具介绍_第2张图片

1.3.2 swiftlint 命令

swift/dart代码规范检查工具介绍_第3张图片

// 输出所有的警告和错误

swiftlint lint

生成错误报告
swiftlint lint  --path ~/Desktop --reporter html > swiftlint.html

// 自动修复已知的Error和Warning

swiftlint autocorrect

// 打开swiftlint文档,直接打开 SwiftLint官方文档

swiftlint docs

// 为所有规则生成文档

swiftlint generate-docs --path

swift/dart代码规范检查工具介绍_第4张图片

// 输出swiftlint的所有规则以及目前工程配置情况

swiftlint rules

swift/dart代码规范检查工具介绍_第5张图片

identifier:规则名称
Opt-in:启用非默认设置的规则
correctable:可纠正的规则
enabled in your config:配置中已经启用
Kind:规则的种类

1.3.3 fastlane支持

也可以用fastlane官方的SwiftLint功能来运行SwiftLint作为你的Fastlane程序的一部分

swiftlint(
    mode: :lint,                            # SwiftLint模式: :lint (默认) 或者 :autocorrect
    executable: "Pods/SwiftLint/swiftlint", # SwiftLint的程序路径 (可选的). 对于用CocoaPods集成SwiftLint时很重要
    path: "/path/to/lint",                  # 特殊的检查路径 (可选的)
    output_file: "swiftlint.result.json",   # 检查结果输出路径 (可选的)
    reporter: "json",                       # 输出格式 (可选的)
    config_file: ".swiftlint-ci.yml",       # 配置文件的路径 (可选的)
    files: [                                # 指定检查文件列表 (可选的)
        "AppDelegate.swift",
        "path/to/project/Model.swift"
    ],
    ignore_exit_status: true,               # 允许fastlane可以继续执行甚至是Swiftlint返回一个非0的退出状态(默认值: false)
    quiet: true,                            # 不输出像‘Linting’和‘Done Linting’的状态日志 (默认值: false)
    strict: true                            # 发现警告时报错? (默认值: false)
)

2.dart代码规范检查

2.1 都有哪些代码规范检查的工具

1.Flutter工程沿用Dart的静态代码检查器dartanalyzer, 并使用内置在Flutter Tools内的终端工具进行代码扫描和分析, 相关代码位于:commands

2.2 如何使用

一般情况下, 在工程文件下配有分析脚本的情况下, 可以直接使用flutter analyze命令进行静态检查, 这和开发工具Android Studio自带的检查插件的效果是一样的, 最终结果会显示在AS下方的Dart Analysis Tab下.

swift/dart代码规范检查工具介绍_第6张图片

2.2.1 分析脚本长啥样放在哪

检查器会根据项目根目录下的分析脚本执行检查, 该文件通常会与pubspec文件处于同一层级.
老版本的分析脚本命名为.analysis_options, 没有yaml后缀, 新版本统一命名为:analysis_options.yaml

swift/dart代码规范检查工具介绍_第7张图片

除了这么放还能怎么放,如果遇到更加复杂的情况怎么办,比如说不同的文件夹下适应不同的规则,见下图:

swift/dart代码规范检查工具介绍_第8张图片

检查器会使用#1检查other package和other other package, 使用#2检查my package.

2.2.2 分析脚本怎么写

1). 默认使用官方

在flutter 1.22 版本后有默认的分析脚本,内置在flutter包中analysis_options_user.yml

2). 集成其他的分析脚本

如果不想使用默认的分析脚本,当然也可以自己进行配置,如果嫌一条条配置lint规则麻烦, 可以直接集成Google的开源项目pedantic或者effective dart(二选一).

  • pedantic: Google内部执行的规则.
  • effective_dart : 与 effective-dart指南 相对应的规则.

2.2.3 定制分析脚本 analysis_options.yaml

analysis_options.yaml配置

dart语言的代码规范以及相关触发规则详见linter

如果嫌一条条配置lint规则麻烦, 可以直接集成下面的

1). pedantic: Google内部执行的规则

pubspec.yaml 中添加如下,再flutter pub get

dev_dependencies:
  pedantic: ^1.11.0

analysis_options.yaml 中引入

include: package:pedantic/analysis_options.yaml

2). effective_dart : 与 effective-dart指南 相对应的规则

在pubspec.yaml中

dev_dependencies:
  effective_dart: ^1.0.0

执行 flutter pub get 然后在 analysis_options.yaml 中引入

include: package:effective_dart/analysis_options.yaml

3). Flutter官方在1.22版本默认使用的分析脚本 : analysis_options_user.yml

在flutter 1.22 版本默认使用的分析脚本 (注:flutter版本查看 flutter --version)当然也可以导入之后进行自定义,如下

include: package:flutter/analysis_options_user.yaml

示例一个以google的pedantic为例 自定义 analysis_options.yaml

# 指定引用第三方库中预设文件的路径
include: package:pedantic/analysis_options.1.8.0.yaml

## analyzer : 配置static analysis的条目,包括启用更严格的类型检查,排除文件,忽略特定规则,更改规则的严重程度等。

## exclude 排除文件
analyzer:
  exclude:
    - [build/**]
    - lib/http_client.dart
    - lib/models/*.g.dart
    - lib/mock/**

  strong-mode:
    implicit-casts: false 
    implicit-dynamic: false 

  errors:
    todo: ignore

## linter : 配置linter规则
linter:
  rules:
      - camel_case_types
      - cancel_subscriptions
严格类型检查

我们知道dart使用语法糖实现了伪动态类型 - dynamic, 可以在编译器不确定类型时, 使用dynamic代替, implicit-dynamic可以阻止这种操作. implicit-casts表示禁止Object类型隐式转换为其他类型.

analyzer:
  strong-mode:
    implicit-casts: false
    implicit-dynamic: false

lint规则有两种配置方式一种是list方式 另一种是key-value方式,两者不能混用
list方式

linter:
  rules:
    -- annotate_overrides
    -- await_only_futures
    

key-value方式

linter:
  rules:
    annotate_overrides: false #禁用规则
    await_only_futures: true #开启规则

对于具体规则什么意思呢,咱们以上文中提到的 annotate_overrides和await_only_futures为例

swift/dart代码规范检查工具介绍_第9张图片

swift/dart代码规范检查工具介绍_第10张图片

可以看到文档写的非常清楚,其他规则触发详见 dart语言的代码规范以及相关触发规则linter

忽略特定文件或者代码行

1).忽略文件
要忽略特定文件的特定非错误规则,请在文件中添加ignore_for_file注释

// ignore_for_file: unnecessary_new

这在注释之前或之后对整个文件起作用,并且对于生成的代码特别有用。

忽略多个规则

// ignore_for_file: unnecessary_new, unused_import, unused_local_variable

忽略单行

// ignore: unnecessary_new

忽略单行-1

忽略单行-2

自定义规则

每个linter规则都有默认的严重性。您可以使用分析选项文件来更改单个规则的严重性,或者始终忽略某些规则。
支持三种严重性级别:

  • info
    不会导致分析失败的参考消息。例子:todo
  • warning
    警告,例如:analysis_option_deprecated
  • error
    严重错误,导致失败的错误,例如:invalid_assignment

忽略规则

analyzer:
  errors:
    todo: ignore
    

更改规则的严重性

analyzer:
  errors:
    invalid_assignment: warning
    missing_return: error
    dead_code: info

2.2.4 进行代码规范检查 - dart analyzer 命令

万事具备只欠东风 通过 dart analyze

swift/dart代码规范检查工具介绍_第11张图片

挑出其中两条.

1).第一条 info 级别的.

触发规则

info • Unnecessary new keyword at lib/business/home/home_page.dart:36:40 • (unnecessary_new)

具体代码

swift/dart代码规范检查工具介绍_第12张图片

查看规则文档可知unnecessary_new应避免使用new关键字创建实例。

2).第二条 error级别的
error • Missing return type for 'saveStringList' at lib/core/storage/shared_preferences_storage.dart:25:3 • (implicit_dynamic_return)

具体代码

swift/dart代码规范检查工具介绍_第13张图片

查看所给的提示可知没有添加函数的返回值,找了规则文档没有找到这条implicit_dynamic_return规则。
原来我启用了更为严格的类型检查,所以才会触发这个error级别的错误。

严格类型检查

上文说过这里就不多解释了。

你可能感兴趣的:(Flutter,iOS,ios,dart)