Skip to content

Commit 9ec17e6

Browse files
committed
Shared: Pull out the shared parts of Java's type flow library into a shared module.
1 parent 2683e40 commit 9ec17e6

File tree

3 files changed

+570
-0
lines changed

3 files changed

+570
-0
lines changed
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
/**
2+
* Provides predicates for giving improved type bounds on expressions.
3+
*
4+
* An inferred bound on the runtime type of an expression can be either exact
5+
* or merely an upper bound. Bounds are only reported if they are likely to be
6+
* better than the static bound, which can happen either if an inferred exact
7+
* type has a subtype or if an inferred upper bound passed through at least one
8+
* explicit or implicit cast that lost type information.
9+
*/
10+
11+
/** Provides the input specification. */
12+
signature module TypeFlowInput {
13+
/**
14+
* A node for which type information is available. For example, expressions
15+
* and method declarations.
16+
*/
17+
class TypeFlowNode {
18+
/** Gets a textual representation of this node. */
19+
string toString();
20+
21+
/** Gets the type of this node. */
22+
Type getType();
23+
24+
/**
25+
* Holds if this element is at the specified location.
26+
* The location spans column `startcolumn` of line `startline` to
27+
* column `endcolumn` of line `endline` in file `filepath`.
28+
* For more information, see
29+
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
30+
*/
31+
predicate hasLocationInfo(
32+
string filepath, int startline, int startcolumn, int endline, int endcolumn
33+
);
34+
}
35+
36+
/**
37+
* Holds if data can flow from `n1` to `n2` in one step, and `n1` is not
38+
* necessarily functionally determined by `n2`.
39+
*/
40+
predicate joinStep0(TypeFlowNode n1, TypeFlowNode n2);
41+
42+
/**
43+
* Holds if data can flow from `n1` to `n2` in one step, and `n1` is
44+
* functionally determined by `n2`.
45+
*/
46+
predicate step(TypeFlowNode n1, TypeFlowNode n2);
47+
48+
/**
49+
* Holds if `null` is the only value that flows to `n`.
50+
*/
51+
predicate isNull(TypeFlowNode n);
52+
53+
/** A type. */
54+
class Type {
55+
/** Gets a textual representation of this type. */
56+
string toString();
57+
58+
/** Gets a direct super type of this type. */
59+
Type getASupertype();
60+
}
61+
62+
/**
63+
* Gets the source declaration of this type, or `t` if `t` is already a
64+
* source declaration.
65+
*/
66+
default Type getSourceDeclaration(Type t) { result = t }
67+
68+
/**
69+
* Gets the erased version of this type. The erasure of a erasure of a
70+
* parameterized type is its generic counterpart, or `t` if `t` is already
71+
* fully erased.
72+
*/
73+
default Type getErasure(Type t) { result = t }
74+
75+
/** Gets a direct or indirect supertype of this type, including itself. */
76+
default Type getAnAncestor(Type sub) {
77+
result = sub
78+
or
79+
exists(Type mid | result = mid.getASupertype() and sub = getAnAncestor(mid))
80+
}
81+
82+
/**
83+
* Holds if `t` is the most precise type of `n`, if any.
84+
*/
85+
predicate exactTypeBase(TypeFlowNode n, Type t);
86+
87+
/**
88+
* Holds if `n` has type `t` and this information is discarded, such that `t`
89+
* might be a better type bound for nodes where `n` flows to. This might include
90+
* multiple bounds for a single node.
91+
*/
92+
predicate typeFlowBaseCand(TypeFlowNode n, Type t);
93+
94+
/**
95+
* Holds if `n` is a value that is guarded by a disjunction of a dynamic type
96+
* check that checks if `n` is an instance of type `t_i` where `t` is one of
97+
* those `t_i`.
98+
*/
99+
default predicate instanceofDisjunctionGuarded(TypeFlowNode n, Type t) { none() }
100+
101+
/**
102+
* Holds if `t` is a raw type or parameterised type with unrestricted type
103+
* arguments.
104+
*
105+
* By default, no types are unbound.
106+
*/
107+
default predicate unbound(Type t) { none() }
108+
}
109+
110+
private import internal.TypeFlowImpl as Impl
111+
112+
/**
113+
* Provides an implementation of type-flow using input `I`.
114+
*/
115+
cached
116+
module Make<TypeFlowInput I> {
117+
import Impl::TypeFlow<I>
118+
}

0 commit comments

Comments
 (0)