Skip to content

Commit b223049

Browse files
committed
JS: Add getComponentRef()
1 parent b9d1b55 commit b223049

File tree

1 file changed

+47
-0
lines changed
  • javascript/ql/lib/semmle/javascript/frameworks

1 file changed

+47
-0
lines changed

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

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,11 @@ module Vue {
139139
endcolumn = 0
140140
}
141141

142+
/**
143+
* Gets an API node referring to the component itself, such as the return value of `new Vue()`.
144+
*/
145+
API::Node getComponentRef() { none() } // overridden in subclass
146+
142147
/**
143148
* Gets an API node referring to the options passed to the Vue object,
144149
* such as the object literal `{...}` in `new Vue{{...})` or the default export of a single-file component.
@@ -374,6 +379,8 @@ module Vue {
374379
def.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
375380
}
376381

382+
override API::Node getComponentRef() { result = def.getReturn() }
383+
377384
override API::Node getOwnOptions() { result = def.getParameter(0) }
378385

379386
override DataFlow::Node getOwnOptionsObject() { result = def.getArgument(0) }
@@ -397,6 +404,8 @@ module Vue {
397404
extend.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
398405
}
399406

407+
override API::Node getComponentRef() { result = extend.getReturn() }
408+
400409
override API::Node getOwnOptions() { result = extend.getParameter(0) }
401410

402411
override DataFlow::Node getOwnOptionsObject() { result = extend.getArgument(0) }
@@ -421,6 +430,8 @@ module Vue {
421430
sub.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
422431
}
423432

433+
override API::Node getComponentRef() { result = sub.getReturn() }
434+
424435
override API::Node getOwnOptions() { result = sub.getParameter(0) }
425436

426437
override DataFlow::Node getOwnOptionsObject() { result = sub.getArgument(0) }
@@ -450,13 +461,40 @@ module Vue {
450461
def.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
451462
}
452463

464+
override API::Node getComponentRef() {
465+
// The component can be obtained via 1-argument calls to `Vue.component()` with the
466+
// same name, but we don't model this at the moment.
467+
none()
468+
}
469+
453470
override API::Node getOwnOptions() { result = def.getParameter(1) }
454471

455472
override DataFlow::Node getOwnOptionsObject() { result = def.getArgument(1) }
456473

457474
override Template::Element getTemplateElement() { none() }
458475
}
459476

477+
/**
478+
* An import referring to a `.vue` file, seen as an API entry point.
479+
*
480+
* Concretely, such an import receives the Vue component generated from the .vue file,
481+
* not the actual exports of the script tag in the file.
482+
*/
483+
private class VueFileImportEntryPoint extends API::EntryPoint {
484+
VueFileImportEntryPoint() { this = "VueFileImportEntryPoint" }
485+
486+
override DataFlow::SourceNode getAUse() {
487+
exists(Import imprt |
488+
imprt.getImportedPath().resolve() instanceof VueFile and
489+
result = imprt.getImportedModuleNode()
490+
)
491+
}
492+
493+
override DataFlow::Node getARhs() {
494+
none()
495+
}
496+
}
497+
460498
/**
461499
* A single file Vue component in a `.vue` file.
462500
*/
@@ -490,6 +528,15 @@ module Vue {
490528
)
491529
}
492530

531+
override API::Node getComponentRef() {
532+
// There is no explicit `new Vue()` call in .vue files, so instead get all the imports
533+
// of the .vue file.
534+
exists(Import imprt |
535+
imprt.getImportedPath().resolve() = file and
536+
result.getAnImmediateUse() = imprt.getImportedModuleNode()
537+
)
538+
}
539+
493540
override API::Node getOwnOptions() {
494541
exists(ExportDefaultDeclaration decl |
495542
decl.getTopLevel() = getModule() and

0 commit comments

Comments
 (0)