Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 20 additions & 4 deletions javascript/ql/lib/semmle/javascript/ES2015Modules.qll
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ class ES2015Module extends Module {
override string getName() { result = this.getFile().getStem() }

/** Gets an export declaration in this module. */
pragma[nomagic]
ExportDeclaration getAnExport() { result.getTopLevel() = this }

overlay[global]
Expand All @@ -38,6 +39,7 @@ class ES2015Module extends Module {

/** Holds if this module exports variable `v` under the name `name`. */
overlay[global]
pragma[nomagic]
predicate exportsAs(LexicalName v, string name) { this.getAnExport().exportsAs(v, name) }

override predicate isStrict() {
Expand Down Expand Up @@ -345,6 +347,7 @@ abstract class ExportDeclaration extends Stmt, @export_declaration {

/** Holds if this export declaration exports variable `v` under the name `name`. */
overlay[global]
pragma[nomagic]
final predicate exportsAs(LexicalName v, string name) {
this.exportsDirectlyAs(v, name)
or
Expand Down Expand Up @@ -821,18 +824,31 @@ class SelectiveReExportDeclaration extends ReExportDeclaration, ExportNamedDecla
result = ExportNamedDeclaration.super.getImportedPath()
}

overlay[global]
pragma[nomagic]
private predicate reExportsFrom(ES2015Module mod, string originalName, string reExportedName) {
exists(ExportSpecifier spec |
spec = this.getASpecifier() and
reExportedName = spec.getExportedName() and
originalName = spec.getLocalName() and
mod = this.getReExportedES2015Module()
)
}

overlay[global]
override predicate reExportsAs(LexicalName v, string name) {
exists(ExportSpecifier spec | spec = this.getASpecifier() and name = spec.getExportedName() |
this.getReExportedES2015Module().exportsAs(v, spec.getLocalName())
exists(ES2015Module mod, string originalName |
this.reExportsFrom(mod, originalName, name) and
mod.exportsAs(v, originalName)
) and
not (this.isTypeOnly() and v instanceof Variable)
}

overlay[global]
override DataFlow::Node getReExportedSourceNode(string name) {
exists(ExportSpecifier spec | spec = this.getASpecifier() and name = spec.getExportedName() |
result = this.getReExportedES2015Module().getAnExport().getSourceNode(spec.getLocalName())
exists(ES2015Module mod, string originalName |
this.reExportsFrom(mod, originalName, name) and
result = mod.getAnExport().getSourceNode(originalName)
)
}
}
Expand Down