JS: extract getDefaultNode from DefaultRange

This commit is contained in:
Esben Sparre Andreasen
2019-04-17 15:18:06 +02:00
parent d2fa7aad1c
commit f74653be46
7 changed files with 37 additions and 31 deletions

View File

@@ -263,6 +263,13 @@ private class AmdDependencyImport extends Import {
not exists(super.getImportedModule()) and not exists(super.getImportedModule()) and
result = resolveByAbsolutePath() result = resolveByAbsolutePath()
} }
override DataFlow::Node getDefaultNode() {
exists(Parameter param |
any(AmdModuleDefinition def).dependencyParameter(this, param) and
result = DataFlow::parameterNode(param)
)
}
} }
/** /**

View File

@@ -43,6 +43,22 @@ class ImportDeclaration extends Stmt, Import, @importdeclaration {
/** Gets an import specifier of this import declaration. */ /** Gets an import specifier of this import declaration. */
ImportSpecifier getASpecifier() { result = getSpecifier(_) } ImportSpecifier getASpecifier() { result = getSpecifier(_) }
override DataFlow::Node getDefaultNode() {
// `import * as http from 'http'` or `import http from `http`'
exists(ImportSpecifier is |
is = getASpecifier() and
result = DataFlow::ssaDefinitionNode(SSA::definition(is))
|
is instanceof ImportNamespaceSpecifier and
count(getASpecifier()) = 1
or
is.getImportedName() = "default"
)
or
// `import { createServer } from 'http'`
result = DataFlow::destructuredModuleImportNode(this)
}
} }
/** A literal path expression appearing in an `import` declaration. */ /** A literal path expression appearing in an `import` declaration. */

View File

@@ -1562,6 +1562,8 @@ class DynamicImportExpr extends @dynamicimport, Expr, Import {
override PathExpr getImportedPath() { result = getSource() } override PathExpr getImportedPath() { result = getSource() }
override Module getEnclosingModule() { result = getTopLevel() } override Module getEnclosingModule() { result = getTopLevel() }
override DataFlow::Node getDefaultNode() { result = DataFlow::valueNode(this) }
} }
/** A literal path expression appearing in a dynamic import. */ /** A literal path expression appearing in a dynamic import. */

View File

@@ -160,6 +160,11 @@ abstract class Import extends ASTNode {
result = resolveFromTypeRoot() result = resolveFromTypeRoot()
) )
} }
/**
* Gets the data flow node that the default import of this import is available at.
*/
abstract DataFlow::Node getDefaultNode();
} }
/** /**

View File

@@ -234,6 +234,8 @@ class Require extends CallExpr, Import {
priority - (prioritiesPerCandidate() * r + numberOfExtensions() + 1)) priority - (prioritiesPerCandidate() * r + numberOfExtensions() + 1))
) )
} }
override DataFlow::Node getDefaultNode() { result = DataFlow::valueNode(this) }
} }
/** An argument to `require` or `require.resolve`, considered as a path expression. */ /** An argument to `require` or `require.resolve`, considered as a path expression. */

View File

@@ -212,6 +212,8 @@ class ExternalModuleReference extends Expr, Import, @externalmodulereference {
override ControlFlowNode getFirstControlFlowNode() { override ControlFlowNode getFirstControlFlowNode() {
result = getExpression().getFirstControlFlowNode() result = getExpression().getFirstControlFlowNode()
} }
override DataFlow::Node getDefaultNode() { result = DataFlow::valueNode(this) }
} }
/** A literal path expression appearing in an external module reference. */ /** A literal path expression appearing in an external module reference. */

View File

@@ -461,37 +461,9 @@ module ModuleImportNode {
string path; string path;
DefaultRange() { DefaultRange() {
// `require("http")` exists(Import i |
exists(Require req | req.getImportedPath().getValue() = path | this = i.getDefaultNode() and
this = DataFlow::valueNode(req) i.getImportedPath().getValue() = path
)
or
// `import http = require("http")`
exists(ExternalModuleReference req | req.getImportedPath().getValue() = path |
this = DataFlow::valueNode(req)
)
or
// `import * as http from 'http'` or `import http from `http`'
exists(ImportDeclaration id, ImportSpecifier is |
id.getImportedPath().getValue() = path and
is = id.getASpecifier() and
this = DataFlow::ssaDefinitionNode(SSA::definition(is))
|
is instanceof ImportNamespaceSpecifier and
count(id.getASpecifier()) = 1
or
is.getImportedName() = "default"
)
or
// `import { createServer } from 'http'`
exists(ImportDeclaration id |
this = DataFlow::destructuredModuleImportNode(id) and
id.getImportedPath().getValue() = path
)
or
// declared AMD dependency
exists(AmdModuleDefinition amd |
this = DataFlow::parameterNode(amd.getDependencyParameter(path))
) )
or or
// AMD require // AMD require