Skip to content

Commit b77d77d

Browse files
authored
Merge pull request #10209 from erik-krogh/caseConsistency
QL: add query detecting consistent casing of names
2 parents b38ad13 + 196dfd9 commit b77d77d

File tree

3 files changed

+68
-5
lines changed

3 files changed

+68
-5
lines changed

ql/ql/src/codeql_ql/style/NodeName.qll

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,13 @@ string getName(AstNode node, string kind) {
99
or
1010
// not including CharPreds or db relations. The remaining are: classlessPredicate, classPredicate, newTypeBranch.
1111
result = node.(ClasslessPredicate).getName() and
12-
kind = "classlessPredicate"
12+
kind = "predicate"
1313
or
1414
result = node.(ClassPredicate).getName() and
15-
kind = "classPredicate"
15+
kind = "predicate"
1616
or
1717
result = node.(NewTypeBranch).getName() and
18-
kind = "newtypeBranch"
18+
kind = "newtype"
1919
or
2020
result = node.(NewType).getName() and
2121
kind = "newtype"
@@ -28,5 +28,5 @@ string getName(AstNode node, string kind) {
2828
or
2929
result = node.(Module).getName() and kind = "module"
3030
or
31-
result = node.(Import).importedAs() and kind = "import"
31+
result = node.(Import).importedAs() and kind = "module"
3232
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/**
2+
* @name Names only differing by case
3+
* @description Names only differing by case can cause confusion.
4+
* @kind problem
5+
* @problem.severity warning
6+
* @id ql/names-only-differing-by-case
7+
* @tags correctness
8+
* maintainability
9+
* @precision high
10+
*/
11+
12+
import ql
13+
import codeql_ql.style.AcronymsShouldBeCamelCaseQuery as Acronyms
14+
private import codeql_ql.style.NodeName as NodeName
15+
16+
string getName(AstNode node, string kind, YAML::QLPack pack) {
17+
result = NodeName::getName(node, kind) and
18+
node.getLocation().getFile() = pack.getAFileInPack() and
19+
not node.hasAnnotation("deprecated") and // deprecated nodes are not interesting
20+
not node.getLocation().getFile().getBaseName() = "TreeSitter.qll" and // auto-generated, is sometimes bad.
21+
not node.getLocation().getFile().getExtension() = "ql" // .ql files cannot be imported, so no risk of conflict
22+
}
23+
24+
// get better join-order by getting all the relevant information in a single utility predicate
25+
pragma[nomagic]
26+
string getNameAndPack(AstNode node, string kind, string lower, YAML::QLPack pack) {
27+
result = getName(node, kind, pack) and lower = result.toLowerCase()
28+
}
29+
30+
predicate problem(string name1, AstNode node1, string name2, string kind) {
31+
exists(string lower, YAML::QLPack pack1, YAML::QLPack pack2 |
32+
name1 = getNameAndPack(node1, kind, lower, pack1) and
33+
name1.length() >= 2 and
34+
pack2 = pack1.getADependency*() and
35+
name2 = getNameAndPack(_, kind, lower, pack2) and // TODO: Get if it's a dependency pack in the alert-message.
36+
name1 != name2 and
37+
kind != "variable" // these are benign, and plentyful...
38+
)
39+
}
40+
41+
string prettyPluralKind(string kind) {
42+
kind = "class" and result = "classes"
43+
or
44+
kind = "classlessPredicate" and result = "predicates"
45+
or
46+
kind = "classPredicate" and result = "class predicates"
47+
or
48+
kind = "newtypeBranch" and result = "newtype branches"
49+
or
50+
kind = "newtype" and result = "newtypes"
51+
or
52+
kind = "variable" and result = "variables"
53+
or
54+
kind = "field" and result = "fields"
55+
or
56+
kind = "module" and result = "modules"
57+
}
58+
59+
from string name1, AstNode node, string name2, string kind
60+
where problem(name1, node, name2, kind) and not name1.toLowerCase() = "geturl"
61+
select node,
62+
name1 + " is only different by casing from " + name2 + " that is used elsewhere for " +
63+
prettyPluralKind(kind) + "."
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
| Test.qll:1:1:3:3 | QLDoc | This comment contains the common misspelling 'mispelled', which should instead be 'misspelled'. |
22
| Test.qll:4:7:4:26 | Class PublicallyAccessible | This class name contains the common misspelling 'publically', which should instead be 'publicly'. |
33
| Test.qll:5:3:5:20 | FieldDecl | This field name contains the common misspelling 'occurences', which should instead be 'occurrences'. |
4-
| Test.qll:10:13:10:23 | ClassPredicate hasAgrument | This classPredicate name contains the common misspelling 'agrument', which should instead be 'argument'. |
4+
| Test.qll:10:13:10:23 | ClassPredicate hasAgrument | This predicate name contains the common misspelling 'agrument', which should instead be 'argument'. |
55
| Test.qll:13:1:16:3 | QLDoc | This comment contains the non-US spelling 'colour', which should instead be 'color'. |
66
| Test.qll:17:7:17:17 | Class AnalysedInt | This class name contains the non-US spelling 'analysed', which should instead be 'analyzed'. |

0 commit comments

Comments
 (0)