|
15 | 15 | * `namespace; type; subtypes; name; signature; ext; output; kind; provenance` |
16 | 16 | * - BarrierGuards: |
17 | 17 | * `namespace; type; subtypes; name; signature; ext; input; acceptingValue; kind; provenance` |
| 18 | + * - Forwards: |
| 19 | + * `namespace; type; subtypes; name; signature; ext; start; constructor; provenance` |
18 | 20 | * |
19 | 21 | * The interpretation of a row is similar to API-graphs with a left-to-right |
20 | 22 | * reading. |
@@ -160,6 +162,20 @@ predicate summaryModel( |
160 | 162 | ) |
161 | 163 | } |
162 | 164 |
|
| 165 | +/** |
| 166 | + * Holds if a forward model exists for the given parameters. |
| 167 | + */ |
| 168 | +predicate forwardsModel( |
| 169 | + string namespace, string type, boolean subtypes, string name, string signature, string ext, |
| 170 | + string start, string constructor, string provenance, string model |
| 171 | +) { |
| 172 | + exists(QlBuiltins::ExtensionId madId | |
| 173 | + Extensions::forwardsModel(namespace, type, subtypes, name, signature, ext, start, constructor, |
| 174 | + provenance, madId) and |
| 175 | + model = madId.toString() |
| 176 | + ) |
| 177 | +} |
| 178 | + |
163 | 179 | /** Provides a query predicate to check the data for validation errors. */ |
164 | 180 | module ModelValidation { |
165 | 181 | private string getInvalidModelInput() { |
@@ -259,7 +275,8 @@ private predicate elementSpec( |
259 | 275 | sinkModel(namespace, type, subtypes, name, signature, ext, _, _, _, _) or |
260 | 276 | barrierModel(namespace, type, subtypes, name, signature, ext, _, _, _, _) or |
261 | 277 | barrierGuardModel(namespace, type, subtypes, name, signature, ext, _, _, _, _, _) or |
262 | | - summaryModel(namespace, type, subtypes, name, signature, ext, _, _, _, _, _) |
| 278 | + summaryModel(namespace, type, subtypes, name, signature, ext, _, _, _, _, _) or |
| 279 | + forwardsModel(namespace, type, subtypes, name, signature, ext, _, _, _, _) |
263 | 280 | } |
264 | 281 |
|
265 | 282 | /** |
@@ -1054,6 +1071,46 @@ private module Cached { |
1054 | 1071 |
|
1055 | 1072 | import Cached |
1056 | 1073 |
|
| 1074 | +/** Gets the constructor type selected by `constructorType` in a forwarding model. */ |
| 1075 | +bindingset[forwarder, type, name, constructorType] |
| 1076 | +private Type getForwardedConstructorType( |
| 1077 | + Function forwarder, string type, string name, string constructorType |
| 1078 | +) { |
| 1079 | + exists(string typeArguments, int index | |
| 1080 | + parseAngles(type, _, typeArguments, "") and |
| 1081 | + constructorType = getAtIndex(typeArguments, index) and |
| 1082 | + result = forwarder.getDeclaringType().getTemplateArgument(index) |
| 1083 | + ) |
| 1084 | + or |
| 1085 | + exists(string nameArguments, int index | |
| 1086 | + parseAngles(name, _, nameArguments, "") and |
| 1087 | + constructorType = getAtIndex(nameArguments, index) and |
| 1088 | + result = forwarder.getTemplateArgument(index) |
| 1089 | + ) |
| 1090 | +} |
| 1091 | + |
| 1092 | +/** Holds if `forwarder` forwards its arguments starting at `start` to `constructor`. */ |
| 1093 | +predicate forwards(Function forwarder, Constructor constructor, int start) { |
| 1094 | + exists( |
| 1095 | + string namespace, string type, boolean subtypes, string name, string signature, string ext, |
| 1096 | + string startString, string constructorType |
| 1097 | + | |
| 1098 | + forwardsModel(namespace, type, subtypes, name, signature, ext, startString, constructorType, _, |
| 1099 | + _) and |
| 1100 | + forwarder = interpretElement(namespace, type, subtypes, name, signature, ext) and |
| 1101 | + start = startString.toInt() |
| 1102 | + | |
| 1103 | + // Either the row specifies forwarding to a type given by the type or |
| 1104 | + // function template, in which case we need to resolve that from the type |
| 1105 | + // or function name. |
| 1106 | + constructor.getDeclaringType() = |
| 1107 | + getForwardedConstructorType(forwarder, type, name, constructorType).getUnspecifiedType() |
| 1108 | + or |
| 1109 | + // Or the row specifies forwarding to a specific type. |
| 1110 | + classHasQualifiedName(constructor.getDeclaringType(), namespace, constructorType) |
| 1111 | + ) |
| 1112 | +} |
| 1113 | + |
1057 | 1114 | /** |
1058 | 1115 | * Holds if `node` is specified as a source with the given kind in a MaD flow |
1059 | 1116 | * model. |
|
0 commit comments