|
152 | 152 | ]
|
153 | 153 | },
|
154 | 154 |
|
| 155 | + "Type tracking class": { |
| 156 | + "scope": "ql", |
| 157 | + "prefix": "type tracking class", |
| 158 | + "body": [ |
| 159 | + "/**", |
| 160 | + " * Provides models for the `${TM_SELECTED_TEXT}` class", |
| 161 | + " *", |
| 162 | + " * See ${1:https://apiref (TODO)}.", |
| 163 | + " */", |
| 164 | + "module ${TM_SELECTED_TEXT/^(.*)\\.([^.]+)$/$2/} {", |
| 165 | + " /** Gets a reference to the `${TM_SELECTED_TEXT}` class. */", |
| 166 | + " private API::Node classRef() {", |
| 167 | + " result = API::moduleImport(\"${TM_SELECTED_TEXT/\\.([^.]+)/\").getMember(\"$1/g}\")", |
| 168 | + " }", |
| 169 | + "", |
| 170 | + " /**", |
| 171 | + " * A source of instances of `${TM_SELECTED_TEXT}`, extend this class to model new instances.", |
| 172 | + " *", |
| 173 | + " * This can include instantiations of the class, return values from function", |
| 174 | + " * calls, or a special parameter that will be set when functions are called by an external", |
| 175 | + " * library.", |
| 176 | + " *", |
| 177 | + " * Use the predicate `${TM_SELECTED_TEXT/^(.*)\\.([^.]+)$/$2/}::instance()` to get references to instances of `${TM_SELECTED_TEXT}`.", |
| 178 | + " */", |
| 179 | + " abstract class InstanceSource extends DataFlow::LocalSourceNode { }", |
| 180 | + "", |
| 181 | + " /** A direct instantiation of `${TM_SELECTED_TEXT}`. */", |
| 182 | + " private class ClassInstantiation extends InstanceSource, DataFlow::CallCfgNode {", |
| 183 | + " override CallNode node;", |
| 184 | + "", |
| 185 | + " ClassInstantiation() { this = classRef().getACall() }", |
| 186 | + " }", |
| 187 | + "", |
| 188 | + " /** Gets a reference to an instance of `${TM_SELECTED_TEXT}`. */", |
| 189 | + " private DataFlow::TypeTrackingNode instance(DataFlow::TypeTracker t) {", |
| 190 | + " t.start() and", |
| 191 | + " result instanceof InstanceSource", |
| 192 | + " or", |
| 193 | + " exists(DataFlow::TypeTracker t2 | result = instance(t2).track(t2, t))", |
| 194 | + " }", |
| 195 | + "", |
| 196 | + " /** Gets a reference to an instance of `${TM_SELECTED_TEXT}`. */", |
| 197 | + " DataFlow::Node instance() { instance(DataFlow::TypeTracker::end()).flowsTo(result) }", |
| 198 | + "", |
| 199 | + " DataFlow::Node instance() { instance(DataFlow::TypeTracker::end()).flowsTo(result) }", |
| 200 | + "}", |
| 201 | + ], |
| 202 | + "description": "Type tracking class (select full class path before inserting)", |
| 203 | + }, |
| 204 | + |
| 205 | + "API graph .getMember chain": { |
| 206 | + "scope": "ql", |
| 207 | + "prefix": "api graph .getMember chain", |
| 208 | + "body": [ |
| 209 | + "API::moduleImport(\"${TM_SELECTED_TEXT/\\.([^.]+)/\").getMember(\"$1/g}\")" |
| 210 | + ], |
| 211 | + "description": "API graph .getMember chain (select full path before inserting)", |
| 212 | + }, |
155 | 213 | }
|
0 commit comments