-
Notifications
You must be signed in to change notification settings - Fork 2k
Expand file tree
/
Copy pathql_class.mustache
More file actions
147 lines (136 loc) · 4.5 KB
/
ql_class.mustache
File metadata and controls
147 lines (136 loc) · 4.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
// generated by {{generator}}
private import {{import_prefix}}.Synth
private import {{import_prefix}}.Raw
{{#imports}}
import {{.}}
{{/imports}}
module Generated {
{{#has_doc}}
/**
{{#ql_internal}}
* INTERNAL: Do not use.
{{/ql_internal}}
{{#doc}}
* {{.}}
{{/doc}}
*/
{{/has_doc}}
class {{name}} extends Synth::T{{name}}{{#bases}}, {{.}}{{/bases}} {
{{#root}}
/**
* Gets the string representation of this element.
*/
string toString() { none() } // overridden by subclasses
/**
* Gets the name of a primary CodeQL class to which this element belongs.
*
* This is the most precise syntactic category to which they belong; for
* example, `CallExpr` is a primary class, but `ApplyExpr` is not.
*
* There might be some corner cases when this returns multiple classes, or none.
*/
string getAPrimaryQlClass() { none() } // overridden by subclasses
/**
* Gets a comma-separated list of the names of the primary CodeQL classes to which this element belongs.
*/
final string getPrimaryQlClasses() { result = concat(this.getAPrimaryQlClass(), ",") }
/**
* Gets the most immediate element that should substitute this element in the explicit AST, if any.
* Classes can override this to indicate this node should be in the "hidden" AST, mostly reserved
* for conversions and syntactic sugar nodes like parentheses.
*/
{{name}} getResolveStep() { none() } // overridden by subclasses
/**
* Gets the element that should substitute this element in the explicit AST, applying `getResolveStep`
* transitively.
*/
final {{name}} resolve() {
not exists(this.getResolveStep()) and result = this
or
result = this.getResolveStep().resolve()
}
{{/root}}
{{#final}}
override string getAPrimaryQlClass() { result = "{{name}}" }
{{/final}}
{{#properties}}
{{#type_is_hideable}}
/**
* {{>ql_property_doc}} *
* This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the
* behavior of both the `Immediate` and non-`Immediate` versions.
*/
{{type}} get{{#is_unordered}}An{{/is_unordered}}Immediate{{singular}}({{#is_indexed}}int index{{/is_indexed}}) {
{{^synth}}
result = Synth::convert{{type}}FromRaw(Synth::convert{{name}}ToRaw(this){{^root}}.(Raw::{{name}}){{/root}}.{{getter}}({{#is_indexed}}index{{/is_indexed}}))
{{/synth}}
{{#synth}}
none()
{{/synth}}
}
/**
* {{>ql_property_doc}} *
{{#has_description}}
{{#description}}
* {{.}}
{{/description}}
{{/has_description}}
*/
final {{type}} {{getter}}({{#is_indexed}}int index{{/is_indexed}}) {
exists({{type}} immediate | immediate = this.get{{#is_unordered}}An{{/is_unordered}}Immediate{{singular}}({{#is_indexed}}index{{/is_indexed}}) and
{{#hideable}}if exists(this.getResolveStep()) then result = immediate else {{/hideable}}result = immediate.resolve())
}
{{/type_is_hideable}}
{{^type_is_hideable}}
/**
* {{>ql_property_doc}} *
{{#has_description}}
{{#description}}
* {{.}}
{{/description}}
{{/has_description}}
*/
{{type}} {{getter}}({{#is_indexed}}int index{{/is_indexed}}) {
{{^synth}}
{{^is_predicate}}result = {{/is_predicate}}{{#type_is_class}}Synth::convert{{type}}FromRaw({{/type_is_class}}Synth::convert{{name}}ToRaw(this){{^root}}.(Raw::{{name}}){{/root}}.{{getter}}({{#is_indexed}}index{{/is_indexed}}){{#type_is_class}}){{/type_is_class}}
{{/synth}}
{{#synth}}
none()
{{/synth}}
}
{{/type_is_hideable}}
{{#is_optional}}
/**
* Holds if `{{getter}}({{#is_repeated}}index{{/is_repeated}})` exists.
*/
final predicate has{{singular}}({{#is_repeated}}int index{{/is_repeated}}) {
exists(this.{{getter}}({{#is_repeated}}index{{/is_repeated}}))
}
{{/is_optional}}
{{#is_indexed}}
/**
* Gets any of the {{doc_plural}}.
*/
final {{type}} {{indefinite_getter}}() {
result = this.{{getter}}(_)
}
{{^is_optional}}
/**
* Gets the number of {{doc_plural}}.
*/
final int getNumberOf{{plural}}() {
result = count(int i | exists(this.{{getter}}(i)))
}
{{/is_optional}}
{{/is_indexed}}
{{#is_unordered}}
/**
* Gets the number of {{doc_plural}}.
*/
final int getNumberOf{{plural}}() {
result = count(this.{{getter}}())
}
{{/is_unordered}}
{{/properties}}
}
}