Skip to content

Commit 7db9b7d

Browse files
Napalysasgerf
andcommitted
Now flag aliases with the 'get' or 'as' prefix that resolve to predicates lacking a return type.
Co-authored-by: asgerf <[email protected]>
1 parent 67745e6 commit 7db9b7d

File tree

3 files changed

+37
-10
lines changed

3 files changed

+37
-10
lines changed

ql/ql/src/queries/style/ValidatePredicateGetReturns.ql

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,18 +21,17 @@ predicate isGetPredicate(Predicate pred, string prefix) {
2121
}
2222

2323
/**
24-
* Checks if a predicate has a return type.
24+
* Checks if a predicate has a return type. This is phrased negatively to not flag unresolved aliases.
2525
*/
26-
predicate hasReturnType(Predicate pred) { exists(pred.getReturnTypeExpr()) }
27-
28-
/**
29-
* Checks if a predicate is an alias using getAlias().
30-
*/
31-
predicate isAlias(Predicate pred) { exists(pred.(ClasslessPredicate).getAlias()) }
26+
predicate hasNoReturnType(Predicate pred) {
27+
not exists(pred.getReturnTypeExpr()) and
28+
not pred.(ClasslessPredicate).getAlias() instanceof PredicateExpr
29+
or
30+
hasNoReturnType(pred.(ClasslessPredicate).getAlias().(PredicateExpr).getResolvedPredicate())
31+
}
3232

3333
from Predicate pred, string prefix
3434
where
3535
isGetPredicate(pred, prefix) and
36-
not hasReturnType(pred) and
37-
not isAlias(pred)
36+
hasNoReturnType(pred)
3837
select pred, "This predicate starts with '" + prefix + "' but does not return a value."
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
11
| test.qll:4:11:4:18 | ClasslessPredicate getValue | This predicate starts with 'get' but does not return a value. |
22
| test.qll:25:11:25:28 | ClasslessPredicate getImplementation2 | This predicate starts with 'get' but does not return a value. |
3+
| test.qll:28:11:28:19 | ClasslessPredicate getAlias2 | This predicate starts with 'get' but does not return a value. |
34
| test.qll:31:11:31:17 | ClasslessPredicate asValue | This predicate starts with 'as' but does not return a value. |
5+
| test.qll:48:11:48:19 | ClasslessPredicate getAlias4 | This predicate starts with 'get' but does not return a value. |
6+
| test.qll:61:11:61:22 | ClasslessPredicate getDistance2 | This predicate starts with 'get' but does not return a value. |

ql/ql/test/queries/style/ValidatePredicateGetReturns/test.qll

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ predicate retrieveValue() { none() }
2424
// NOT OK -- starts with get and does not return value
2525
predicate getImplementation2() { none() }
2626

27-
// OK -- is an alias
27+
// NOT OK -- is an alias for a predicate which does not have a return value
2828
predicate getAlias2 = getImplementation2/0;
2929

3030
// NOT OK -- starts with as and does not return value
@@ -40,3 +40,28 @@ string asString() { result = "string" }
4040
HiddenType getInjectableCompositeActionNode() {
4141
exists(HiddenType hidden | result = hidden.toString())
4242
}
43+
44+
// OK
45+
predicate implementation4() { none() }
46+
47+
// NOT OK -- is an alias
48+
predicate getAlias4 = implementation4/0;
49+
50+
// OK -- is an alias
51+
predicate alias5 = implementation4/0;
52+
53+
int root() { none() }
54+
55+
predicate edge(int x, int y) { none() }
56+
57+
// OK -- Higher-order predicate
58+
int getDistance(int x) = shortestDistances(root/0, edge/2)(_, x, result)
59+
60+
// NOT OK -- Higher-order predicate that does not return a value even though has 'get' in the name
61+
predicate getDistance2(int x, int y) = shortestDistances(root/0, edge/2)(_, x, y)
62+
63+
// OK
64+
predicate unresolvedAlias = unresolved/0;
65+
66+
// OK -- unresolved alias
67+
predicate getUnresolvedAlias = unresolved/0;

0 commit comments

Comments
 (0)