瀏覽代碼

ast-grep: add a rule to find adjacent string literals in cmStrCat calls

Ben Boeckel 5 月之前
父節點
當前提交
61743471d9

+ 312 - 0
Utilities/ast-grep/rule-tests/__snapshots__/cmstrcat-adjacent-literals-snapshot.yml

@@ -0,0 +1,312 @@
+id: cmstrcat-adjacent-literals
+snapshots:
+  cmStrCat("literal", "literal"):
+    labels:
+    - source: '"literal"'
+      style: primary
+      start: 9
+      end: 18
+    - source: cmStrCat("literal", "literal")
+      style: secondary
+      start: 0
+      end: 30
+    - source: ','
+      style: secondary
+      start: 18
+      end: 19
+    - source: '"literal"'
+      style: secondary
+      start: 20
+      end: 29
+  cmStrCat("literal", "literal", "literal"):
+    labels:
+    - source: '"literal"'
+      style: primary
+      start: 9
+      end: 18
+    - source: cmStrCat("literal", "literal", "literal")
+      style: secondary
+      start: 0
+      end: 41
+    - source: ','
+      style: secondary
+      start: 18
+      end: 19
+    - source: '"literal"'
+      style: secondary
+      start: 20
+      end: 29
+  cmStrCat("literal", "literal", "literal", variable):
+    labels:
+    - source: '"literal"'
+      style: primary
+      start: 9
+      end: 18
+    - source: cmStrCat("literal", "literal", "literal", variable)
+      style: secondary
+      start: 0
+      end: 51
+    - source: '"literal"'
+      style: secondary
+      start: 20
+      end: 29
+  cmStrCat("literal", "literal", variable):
+    labels:
+    - source: '"literal"'
+      style: primary
+      start: 9
+      end: 18
+    - source: cmStrCat("literal", "literal", variable)
+      style: secondary
+      start: 0
+      end: 40
+    - source: ','
+      style: secondary
+      start: 18
+      end: 19
+    - source: '"literal"'
+      style: secondary
+      start: 20
+      end: 29
+  cmStrCat(variable, "literal", "literal" "literal"):
+    labels:
+    - source: '"literal"'
+      style: primary
+      start: 19
+      end: 28
+    - source: cmStrCat(variable, "literal", "literal" "literal")
+      style: secondary
+      start: 0
+      end: 50
+    - source: ','
+      style: secondary
+      start: 28
+      end: 29
+    - source: '"literal" "literal"'
+      style: secondary
+      start: 30
+      end: 49
+  cmStrCat(variable, "literal", "literal"):
+    labels:
+    - source: '"literal"'
+      style: primary
+      start: 19
+      end: 28
+    - source: cmStrCat(variable, "literal", "literal")
+      style: secondary
+      start: 0
+      end: 40
+    - source: ','
+      style: secondary
+      start: 28
+      end: 29
+    - source: '"literal"'
+      style: secondary
+      start: 30
+      end: 39
+  cmStrCat(variable, "literal", "literal", "literal"):
+    labels:
+    - source: '"literal"'
+      style: primary
+      start: 19
+      end: 28
+    - source: cmStrCat(variable, "literal", "literal", "literal")
+      style: secondary
+      start: 0
+      end: 51
+    - source: ','
+      style: secondary
+      start: 28
+      end: 29
+    - source: '"literal"'
+      style: secondary
+      start: 30
+      end: 39
+  cmStrCat(variable, "literal", "literal", "literal", variable, "literal"):
+    labels:
+    - source: '"literal"'
+      style: primary
+      start: 19
+      end: 28
+    - source: cmStrCat(variable, "literal", "literal", "literal", variable, "literal")
+      style: secondary
+      start: 0
+      end: 72
+    - source: ','
+      style: secondary
+      start: 28
+      end: 29
+    - source: '"literal"'
+      style: secondary
+      start: 30
+      end: 39
+  cmStrCat(variable, "literal", "literal", variable):
+    labels:
+    - source: '"literal"'
+      style: primary
+      start: 19
+      end: 28
+    - source: cmStrCat(variable, "literal", "literal", variable)
+      style: secondary
+      start: 0
+      end: 50
+    - source: ','
+      style: secondary
+      start: 28
+      end: 29
+    - source: '"literal"'
+      style: secondary
+      start: 30
+      end: 39
+  cmStrCat(variable, "literal", "string_view"_s, variable):
+    labels:
+    - source: '"literal"'
+      style: primary
+      start: 19
+      end: 28
+    - source: cmStrCat(variable, "literal", "string_view"_s, variable)
+      style: secondary
+      start: 0
+      end: 56
+    - source: _s
+      style: secondary
+      start: 43
+      end: 45
+    - source: ','
+      style: secondary
+      start: 28
+      end: 29
+    - source: '"string_view"_s'
+      style: secondary
+      start: 30
+      end: 45
+  cmStrCat(variable, "literal", 'l', variable):
+    labels:
+    - source: '"literal"'
+      style: primary
+      start: 19
+      end: 28
+    - source: cmStrCat(variable, "literal", 'l', variable)
+      style: secondary
+      start: 0
+      end: 44
+    - source: ','
+      style: secondary
+      start: 28
+      end: 29
+    - source: '''l'''
+      style: secondary
+      start: 30
+      end: 33
+  cmStrCat(variable, "literal", R"(raw_literal)", variable):
+    labels:
+    - source: '"literal"'
+      style: primary
+      start: 19
+      end: 28
+    - source: cmStrCat(variable, "literal", R"(raw_literal)", variable)
+      style: secondary
+      start: 0
+      end: 57
+    - source: ','
+      style: secondary
+      start: 28
+      end: 29
+    - source: R"(raw_literal)"
+      style: secondary
+      start: 30
+      end: 46
+  cmStrCat(variable, "string_view"_s, "literal", variable):
+    labels:
+    - source: '"string_view"_s'
+      style: primary
+      start: 19
+      end: 34
+    - source: _s
+      style: secondary
+      start: 32
+      end: 34
+    - source: cmStrCat(variable, "string_view"_s, "literal", variable)
+      style: secondary
+      start: 0
+      end: 56
+    - source: ','
+      style: secondary
+      start: 34
+      end: 35
+    - source: '"literal"'
+      style: secondary
+      start: 36
+      end: 45
+  cmStrCat(variable, 'c', "literal" "literal"):
+    labels:
+    - source: '''c'''
+      style: primary
+      start: 19
+      end: 22
+    - source: cmStrCat(variable, 'c', "literal" "literal")
+      style: secondary
+      start: 0
+      end: 44
+    - source: ','
+      style: secondary
+      start: 22
+      end: 23
+    - source: '"literal" "literal"'
+      style: secondary
+      start: 24
+      end: 43
+  cmStrCat(variable, 'c', "literal", variable):
+    labels:
+    - source: '''c'''
+      style: primary
+      start: 19
+      end: 22
+    - source: cmStrCat(variable, 'c', "literal", variable)
+      style: secondary
+      start: 0
+      end: 44
+    - source: ','
+      style: secondary
+      start: 22
+      end: 23
+    - source: '"literal"'
+      style: secondary
+      start: 24
+      end: 33
+  cmStrCat(variable, 'c', 'l', variable):
+    labels:
+    - source: '''c'''
+      style: primary
+      start: 19
+      end: 22
+    - source: cmStrCat(variable, 'c', 'l', variable)
+      style: secondary
+      start: 0
+      end: 38
+    - source: ','
+      style: secondary
+      start: 22
+      end: 23
+    - source: '''l'''
+      style: secondary
+      start: 24
+      end: 27
+  cmStrCat(variable, R"(raw_literal)", "literal", variable):
+    labels:
+    - source: R"(raw_literal)"
+      style: primary
+      start: 19
+      end: 35
+    - source: cmStrCat(variable, R"(raw_literal)", "literal", variable)
+      style: secondary
+      start: 0
+      end: 57
+    - source: ','
+      style: secondary
+      start: 35
+      end: 36
+    - source: '"literal"'
+      style: secondary
+      start: 37
+      end: 46

+ 39 - 0
Utilities/ast-grep/rule-tests/cmstrcat-adjacent-literals-test.yml

@@ -0,0 +1,39 @@
+---
+id: cmstrcat-adjacent-literals
+valid:
+  - 'cmStrCat("literal", variable)'
+  - 'cmStrCat(variable, "literal")'
+  - 'cmStrCat(variable, "literal", variable)'
+  - 'cmStrCat(variable, variable, "literal")'
+  - 'cmStrCat("literal", variable, variable)'
+  - 'cmStrCat(variable, "literal", variable)'
+  - 'cmStrCat("literal", binary + expr, "literal")'
+  - 'cmStrCat("literal", cond ? t : f, "literal")'
+  - 'cmStrCat("literal", field.expr, "literal")'
+  - 'cmStrCat("literal", identifier, "literal")'
+  - 'cmStrCat("literal", [lambda](){}, "literal")'
+  - 'cmStrCat("literal", 4, "literal")'
+  - 'cmStrCat("literal", (parens), "literal")'
+  - 'cmStrCat("literal", *ptr_expr, "literal")'
+  - 'cmStrCat("literal", qualified::ident, "literal")'
+  - 'cmStrCat("literal", subscript[expr], "literal")'
+  - 'cmStrCat("literal", +unary_expr, "literal")'
+  - 'cmStrCat("literal", ++update, "literal")'
+  - 'cmStrCat("literal", "udl"_unit, "literal")'
+invalid:
+  - 'cmStrCat("literal", "literal")'
+  - 'cmStrCat("literal", "literal", "literal")'
+  - 'cmStrCat("literal", "literal", variable)'
+  - 'cmStrCat(variable, "literal", "literal")'
+  - 'cmStrCat(variable, "literal", "literal", "literal")'
+  - 'cmStrCat(variable, "literal", "literal", "literal", variable, "literal")'
+  - 'cmStrCat(variable, "literal", "literal", variable)'
+  - "cmStrCat(variable, \"literal\", 'l', variable)"
+  - "cmStrCat(variable, 'c', 'l', variable)"
+  - "cmStrCat(variable, 'c', \"literal\", variable)"
+  - "cmStrCat(variable, 'c', \"literal\" \"literal\")"
+  - 'cmStrCat(variable, "literal", "literal" "literal")'
+  - 'cmStrCat(variable, "literal", R"(raw_literal)", variable)'
+  - 'cmStrCat(variable, R"(raw_literal)", "literal", variable)'
+  - 'cmStrCat(variable, "literal", "string_view"_s, variable)'
+  - 'cmStrCat(variable, "string_view"_s, "literal", variable)'

+ 19 - 0
Utilities/ast-grep/rules/cmstrcat-adjacent-literals.yml

@@ -0,0 +1,19 @@
+---
+id: cmstrcat-adjacent-literals
+language: Cpp
+severity: warning
+message: Adjacent `cmStrCat` arguments which are string literals should be combined
+ignores:
+  - Utilities/ClangTidyModule/Tests/**
+rule:
+  matches: string-literal
+  inside:
+    matches: cmstrcat-call
+    stopBy:
+      kind: call_expression
+  precedes:
+    matches: string-literal
+    follows:
+      pattern: ','
+    stopBy:
+      matches: cmstrcat-arg

+ 23 - 0
Utilities/ast-grep/utils/cmstrcat-arg.yml

@@ -0,0 +1,23 @@
+---
+id: cmstrcat-arg
+language: Cpp
+rule:
+  any:
+    - kind: binary_expression
+    - kind: call_expression
+    - kind: char_literal
+    - kind: concatenated_string
+    - kind: conditional_expression
+    - kind: field_expression
+    - kind: identifier
+    - kind: lambda_expression
+    - kind: number_literal
+    - kind: parenthesized_expression
+    - kind: pointer_expression
+    - kind: qualified_identifier
+    - kind: raw_string_literal
+    - kind: string_literal
+    - kind: subscript_expression
+    - kind: unary_expression
+    - kind: update_expression
+    - kind: user_defined_literal

+ 5 - 0
Utilities/ast-grep/utils/cmstrcat-call.yml

@@ -0,0 +1,5 @@
+---
+id: cmstrcat-call
+language: Cpp
+rule:
+  pattern: cmStrCat($$$)

+ 13 - 0
Utilities/ast-grep/utils/string-literal.yml

@@ -0,0 +1,13 @@
+---
+id: string-literal
+language: Cpp
+rule:
+  any:
+    - kind: char_literal
+    - kind: concatenated_string
+    - kind: raw_string_literal
+    - kind: string_literal
+    - kind: user_defined_literal
+      has:
+        kind: literal_suffix
+        regex: '^_s$'

+ 6 - 0
sgconfig.yml

@@ -0,0 +1,6 @@
+ruleDirs:
+- Utilities/ast-grep/rules
+testConfigs:
+- testDir: Utilities/ast-grep/rule-tests
+utilDirs:
+- Utilities/ast-grep/utils