-
構文解析器: PPI
-
ポリシーはオブジェクト:
Perl::Critic::Policy
-
違反もオブジェクト:
Perl::Critic::Violation
-
処理の流れ
- 有効な検査ポリシーが設定される
- 検査ポリシーごとに以下を繰り返す(
Perl::Critic#_gather_violations $doc : @violations
)- 検査ポリシーが解析に必要な要素名を宣言する(
Perl::Critic::Policy#applies_to : String[]
) - 該当要素ごとに以下が繰り返される
- この検査ポリシーにこの該当要素とドキュメント全体が渡される(
Perl::Critic::Policy#violates $element $doc: @violations
) - この検査ポリシーが違反項目を配列で返す
- この検査ポリシーが違反項目をひとつの配列にまとめる
- この検査ポリシーにこの該当要素とドキュメント全体が渡される(
- この検査ポリシーが発見したすべての違反項目を返す
- 検査ポリシーが解析に必要な要素名を宣言する(
- 検査ポリシーが発見したすべての違反項目をひとつの配列にまとめる
- すべての違反項目に対して統計項目がまとめられる(
Perl::Critic::Statistics#accumlate $doc $violations
) - 表示のための処理(違反項目表示数制限・ソート)がおこなわれる
- 表示される
-
Perl::Critic::Policy
の責務- 判定に必要な要素名の宣言
- 違反判定
- 違反の重要度(severity)の保持
- 違反項目情報の作成(違反項目名・説明・該当要素)
- 項目名:
Variable declared in conditional statement
- 説明:
Declare variables outside of the condition
- 該当要素:
PPI::Element
- 項目名:
-
Perl::Critic::Violation
の責務- 違反項目名の保持
- 違反項目に関する説明の保持(Perl Best Practiceのページ番号)
- 違反位置の取得
- 違反情報の表示文字列化(各情報をsprintfでフォーマット)[cool!]
-
設定ファイル: .perlcritic
[-NamingConventions::Capitalization] [-TestingAndDebugging::RequireUseWarnings] [BuiltinFunctions::RequireBlockGrep] severity = 2 [CodeLayout::ProhibitHardTabs] severity = 1
-
構文解析器: Parser
-
闇が深く断念
- 命名が闇
- ところどころ
TODO: bad design
という素敵なお言葉
-
設定ファイル: rubocop.yml
Style/VariableName: EnforcedStyle: snake_case SupportedStyles: - snake_case - camelCase Style/WhileUntilModifier: MaxLineLength: 80
-
構文解析器:自前
-
エラー出力関数は
warning(code, t, a, b, c, d)
-
メインルーチンが構文木をなめていく過程で、違反を判定
-
設定ファイル: .jshintrc
{ "maxcomplexity" : false, // {int} Max cyclomatic complexity per function "maxlen" : false, // {int} Max number of characters per line }
- 構文解析器:自前
- メインルーチンからエラー出力関数までの仕組みはほぼ JSHint と同じ
- 設定ファイルでは変更出来なさそう
- かわりに
/*jslint*/
/*properties*/
ディレクティブがある
- かわりに
-
構文解析器:esprima(木の巡回にestraverse使ってる)
-
ルールは
lib/rules
以下に定義されている関数-
引数は context
-
esprima の解析した AST ノード名をキーとした関数を持つオブジェクトを返す
-
この関数が出力までの責任を持つ
return { "CallExpression": function(node) { var result; if (result) { report(context, node, result); } } };
-
-
処理の流れ
- すべてのルールが読み込まれる
- 無効設定されたルールを除去され、有効なルールのみが残る
- 有効なルールについて以下を繰り返す
- ルールが要求しているAST要素名を取得する
- このAST要素名について、 estraverse による AST 要素の訪問/脱出イベントを listen する
- estraverse によって AST が巡回される
- ルールが要求しているAST要素名を訪問したとき、ルールの判定メソッドが実行される
- 違反が見つかった場合は、違反項目情報(説明・該当要素)を報告する
- 報告された違反を配列にまとめていく
- まとめられた違反を
formater
を使って表示する
-
rule
の責務- 判定に必要なトークン名の宣言
- 違反判定
- 違反項目情報の作成(説明・該当要素)
- 説明:
Expected '===' and instead saw '=='.
- 該当位置: (要素が位置をもっていなければ)
- 該当要素:
Esprima.Node
- 説明:
ruleId
は RuleCreator によって割り当てられる
-
設定ファイル:.eslintrc, eslint.json
module.exports = { rules: { semi: 2 } };
- 構文解析器:vim-vimlparser
- ルールは autoload/vimlinter.vim の関数群
- トークンの種類ごとに1つの検査メソッドが走って解析される
- 構文解析機:compile(標準)
- ルールは 3 つに分類された静的関数群:
- 物理行(正規表現)
- 論理行(正規表現)
- AST(構文エラーのみをチェック)
- それぞれの静的関数はtoken列の処理と混同されている
- ルールをオブジェクトにしたい