Skip to content

Commit c58947d

Browse files
committed
JS: Refactor Vue::Instance to lead to better join orders
1 parent 5264d24 commit c58947d

File tree

1 file changed

+41
-45
lines changed
  • javascript/ql/src/semmle/javascript/frameworks

1 file changed

+41
-45
lines changed

javascript/ql/src/semmle/javascript/frameworks/Vue.qll

Lines changed: 41 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,15 @@ module Vue {
163163
result = getAsClassComponent().getDecoratorOption(name)
164164
}
165165

166+
/**
167+
* Gets a source node flowing into the option `name` of this instance, including those from
168+
* extended objects and mixins.
169+
*/
170+
pragma[nomagic]
171+
DataFlow::SourceNode getOptionSource(string name) {
172+
result = getOption(name).getALocalSource()
173+
}
174+
166175
/**
167176
* Gets the template element used by this instance, if any.
168177
*/
@@ -190,38 +199,43 @@ module Vue {
190199
/**
191200
* Gets the node for the `template` option of this instance.
192201
*/
193-
DataFlow::Node getTemplate() { result = getOption("template") }
202+
pragma[nomagic]
203+
DataFlow::SourceNode getTemplate() { result = getOptionSource("template") }
194204

195205
/**
196206
* Gets the node for the `render` option of this instance.
197207
*/
198-
DataFlow::Node getRender() {
199-
result = getOption("render")
208+
pragma[nomagic]
209+
DataFlow::SourceNode getRender() {
210+
result = getOptionSource("render")
200211
or
201212
result = getAsClassComponent().getInstanceMethod("render")
202213
}
203214

204215
/**
205216
* Gets the node for the `methods` option of this instance.
206217
*/
207-
DataFlow::Node getMethods() { result = getOption("methods") }
218+
pragma[nomagic]
219+
DataFlow::SourceNode getMethods() { result = getOptionSource("methods") }
208220

209221
/**
210222
* Gets the node for the `computed` option of this instance.
211223
*/
212-
DataFlow::Node getComputed() { result = getOption("computed") }
224+
pragma[nomagic]
225+
DataFlow::SourceNode getComputed() { result = getOptionSource("computed") }
213226

214227
/**
215228
* Gets the node for the `watch` option of this instance.
216229
*/
217-
DataFlow::Node getWatch() { result = getOption("watch") }
230+
pragma[nomagic]
231+
DataFlow::SourceNode getWatch() { result = getOptionSource("watch") }
218232

219233
/**
220234
* Gets the function responding to changes to the given `propName`.
221235
*/
222236
DataFlow::FunctionNode getWatchHandler(string propName) {
223237
exists(DataFlow::SourceNode watcher |
224-
watcher = getWatch().getALocalSource().getAPropertySource(propName)
238+
watcher = getWatch().getAPropertySource(propName)
225239
|
226240
result = watcher
227241
or
@@ -232,12 +246,9 @@ module Vue {
232246
/**
233247
* Gets a node for a member of the `methods` option of this instance.
234248
*/
235-
pragma[noinline]
236-
private DataFlow::Node getAMethod() {
237-
exists(DataFlow::ObjectLiteralNode methods |
238-
methods.flowsTo(getMethods()) and
239-
result = methods.getAPropertyWrite().getRhs()
240-
)
249+
pragma[nomagic]
250+
private DataFlow::SourceNode getAMethod() {
251+
result = getMethods().getAPropertySource()
241252
or
242253
result = getAsClassComponent().getAnInstanceMethod() and
243254
not result = getAsClassComponent().getInstanceMethod([lifecycleHookName(), "render", "data"])
@@ -246,19 +257,11 @@ module Vue {
246257
/**
247258
* Gets a node for a member of the `computed` option of this instance that matches `kind`.
248259
*/
249-
pragma[noinline]
250-
private DataFlow::Node getAnAccessor(DataFlow::MemberKind kind) {
251-
exists(DataFlow::ObjectLiteralNode computedObj, DataFlow::Node accessorObjOrGetter |
252-
computedObj.flowsTo(getComputed()) and
253-
computedObj.getAPropertyWrite().getRhs() = accessorObjOrGetter
254-
|
255-
result = accessorObjOrGetter and kind = DataFlow::MemberKind::getter()
256-
or
257-
exists(DataFlow::ObjectLiteralNode accessorObj |
258-
accessorObj.flowsTo(accessorObjOrGetter) and
259-
result = accessorObj.getAPropertyWrite(memberKindVerb(kind)).getRhs()
260-
)
261-
)
260+
pragma[nomagic]
261+
private DataFlow::SourceNode getAnAccessor(DataFlow::MemberKind kind) {
262+
result = getComputed().getAPropertySource() and kind = DataFlow::MemberKind::getter()
263+
or
264+
result = getComputed().getAPropertySource().getAPropertySource(memberKindVerb(kind))
262265
or
263266
result = getAsClassComponent().getAnInstanceMember(kind) and
264267
kind.isAccessor()
@@ -267,18 +270,10 @@ module Vue {
267270
/**
268271
* Gets a node for a member `name` of the `computed` option of this instance that matches `kind`.
269272
*/
270-
private DataFlow::Node getAccessor(string name, DataFlow::MemberKind kind) {
271-
exists(DataFlow::ObjectLiteralNode computedObj, DataFlow::SourceNode accessorObjOrGetter |
272-
computedObj.flowsTo(getComputed()) and
273-
accessorObjOrGetter.flowsTo(computedObj.getAPropertyWrite(name).getRhs())
274-
|
275-
result = accessorObjOrGetter and kind = DataFlow::MemberKind::getter()
276-
or
277-
exists(DataFlow::ObjectLiteralNode accessorObj |
278-
accessorObj.flowsTo(accessorObjOrGetter) and
279-
result = accessorObj.getAPropertyWrite(memberKindVerb(kind)).getRhs()
280-
)
281-
)
273+
private DataFlow::SourceNode getAccessor(string name, DataFlow::MemberKind kind) {
274+
result = getComputed().getAPropertySource(name) and kind = DataFlow::MemberKind::getter()
275+
or
276+
result = getComputed().getAPropertySource(name).getAPropertySource(memberKindVerb(kind))
282277
or
283278
result = getAsClassComponent().getInstanceMember(name, kind) and
284279
kind.isAccessor()
@@ -287,11 +282,11 @@ module Vue {
287282
/**
288283
* Gets the node for the life cycle hook of the `hookName` option of this instance.
289284
*/
290-
pragma[noinline]
291-
DataFlow::Node getALifecycleHook(string hookName) {
285+
pragma[nomagic]
286+
DataFlow::SourceNode getALifecycleHook(string hookName) {
292287
hookName = lifecycleHookName() and
293288
(
294-
result = getOption(hookName)
289+
result = getOptionSource(hookName)
295290
or
296291
result = getAsClassComponent().getInstanceMethod(hookName)
297292
)
@@ -300,20 +295,21 @@ module Vue {
300295
/**
301296
* Gets a node for a function that will be invoked with `this` bound to this instance.
302297
*/
303-
DataFlow::Node getABoundFunction() {
298+
DataFlow::FunctionNode getABoundFunction() {
304299
result = getAMethod()
305300
or
306301
result = getAnAccessor(_)
307302
or
308303
result = getALifecycleHook(_)
309304
or
310-
result = getOption(_).(DataFlow::FunctionNode)
305+
result = getOptionSource(_)
311306
or
312-
result = getOption(_).getALocalSource().getAPropertySource().(DataFlow::FunctionNode)
307+
result = getOptionSource(_).getAPropertySource()
313308
}
314309

315310
/**
316-
* Gets a node for the value for property `name` of this instance.
311+
* Gets the data flow node that flows into the property `name` of this instance, or is
312+
* returned form a getter defining that property.
317313
*/
318314
DataFlow::Node getAPropertyValue(string name) {
319315
exists(DataFlow::SourceNode obj | obj.getAPropertyWrite(name).getRhs() = result |

0 commit comments

Comments
 (0)