2121import javascript
2222private import internal.CallGraphs
2323private import internal.FlowSteps as FlowSteps
24+ private import internal.DataFlowNode
25+ private import internal.AnalyzedParameters
2426
2527module DataFlow {
26- cached
27- private newtype TNode =
28- TValueNode(AST::ValueNode nd) or
29- TSsaDefNode(SsaDefinition d) or
30- TCapturedVariableNode(LocalVariable v) { v.isCaptured() } or
31- TPropNode(@property p) or
32- TRestPatternNode(DestructuringPattern dp, Expr rest) { rest = dp.getRest() } or
33- TDestructuringPatternNode(DestructuringPattern dp) or
34- TElementPatternNode(ArrayPattern ap, Expr p) { p = ap.getElement(_) } or
35- TElementNode(ArrayExpr arr, Expr e) { e = arr.getAnElement() } or
36- TReflectiveCallNode(MethodCallExpr ce, string kind) {
37- ce.getMethodName() = kind and
38- (kind = "call" or kind = "apply")
39- } or
40- TThisNode(StmtContainer f) { f.(Function).getThisBinder() = f or f instanceof TopLevel } or
41- TUnusedParameterNode(SimpleParameter p) { not exists(SSA::definition(p)) } or
42- TDestructuredModuleImportNode(ImportDeclaration decl) {
43- exists(decl.getASpecifier().getImportedName())
44- } or
45- THtmlAttributeNode(HTML::Attribute attr) or
46- TExceptionalFunctionReturnNode(Function f) or
47- TExceptionalInvocationReturnNode(InvokeExpr e) or
48- TGlobalAccessPathRoot()
49-
5028 /**
5129 * A node in the data flow graph.
5230 */
@@ -90,13 +68,11 @@ module DataFlow {
9068 /**
9169 * Gets the expression enclosing this data flow node.
9270 * In most cases the result is the same as `asExpr()`, however this method
93- * additionally the `InvokeExpr` corresponding to reflective calls, and the `Parameter`
94- * for a `DataFlow::ParameterNode`.
71+ * additionally includes the `InvokeExpr` corresponding to reflective calls.
9572 */
9673 Expr getEnclosingExpr() {
9774 result = asExpr() or
98- this = DataFlow::reflectiveCallNode(result) or
99- result = this.(ParameterNode).getParameter()
75+ this = DataFlow::reflectiveCallNode(result)
10076 }
10177
10278 /** Gets the AST node corresponding to this data flow node, if any. */
@@ -251,7 +227,7 @@ module DataFlow {
251227 */
252228 private JSDocTypeExpr getFallbackTypeAnnotation() {
253229 exists(BindingPattern pattern |
254- this = lvalueNode (pattern) and
230+ this = valueNode (pattern) and
255231 not ast_node_type(pattern, _) and
256232 result = pattern.getTypeAnnotation()
257233 )
@@ -281,8 +257,8 @@ module DataFlow {
281257 }
282258
283259 /**
284- * An expression or a declaration of a function, class, namespace or enum ,
285- * viewed as a node in the data flow graph .
260+ * A node in the data flow graph which corresponds to an expression ,
261+ * destructuring pattern, or declaration of a function, class, namespace, or enum .
286262 *
287263 * Examples:
288264 * ```js
@@ -390,30 +366,6 @@ module DataFlow {
390366 override ASTNode getAstNode() { result = rest }
391367 }
392368
393- /**
394- * A node in the data flow graph which corresponds to the value destructured by an
395- * object or array pattern.
396- */
397- private class DestructuringPatternNode extends Node, TDestructuringPatternNode {
398- DestructuringPattern pattern;
399-
400- DestructuringPatternNode() { this = TDestructuringPatternNode(pattern) }
401-
402- override BasicBlock getBasicBlock() { result = pattern.getBasicBlock() }
403-
404- override predicate hasLocationInfo(
405- string filepath, int startline, int startcolumn, int endline, int endcolumn
406- ) {
407- pattern.getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
408- }
409-
410- override string toString() { result = pattern.toString() }
411-
412- override File getFile() { result = pattern.getFile() }
413-
414- override ASTNode getAstNode() { result = pattern }
415- }
416-
417369 /**
418370 * A node in the data flow graph which corresponds to an element pattern of an
419371 * array pattern.
@@ -759,10 +711,6 @@ module DataFlow {
759711 parameterNode(paramNode, param)
760712 |
761713 result = paramNode
762- or
763- // special case: there is no SSA flow step for unused parameters
764- paramNode instanceof UnusedParameterNode and
765- result = param.getDefault().flow()
766714 )
767715 }
768716
@@ -850,7 +798,7 @@ module DataFlow {
850798 /** Gets the value pattern of this property pattern. */
851799 Expr getValuePattern() { result = prop.getValuePattern() }
852800
853- override Node getBase() { result = TDestructuringPatternNode (prop.getObjectPattern()) }
801+ override Node getBase() { result = TValueNode (prop.getObjectPattern()) }
854802
855803 override Expr getPropertyNameExpr() { result = prop.getNameExpr() }
856804
@@ -863,7 +811,7 @@ module DataFlow {
863811 * for `[ ...elts ] = arr`.
864812 */
865813 private class RestPatternAsPropRead extends PropRead, RestPatternNode {
866- override Node getBase() { result = TDestructuringPatternNode (pattern) }
814+ override Node getBase() { result = TValueNode (pattern) }
867815
868816 override Expr getPropertyNameExpr() { none() }
869817
@@ -876,7 +824,7 @@ module DataFlow {
876824 * for `y`.
877825 */
878826 private class ElementPatternAsPropRead extends PropRead, ElementPatternNode {
879- override Node getBase() { result = TDestructuringPatternNode (pattern) }
827+ override Node getBase() { result = TValueNode (pattern) }
880828
881829 override Expr getPropertyNameExpr() { none() }
882830
@@ -923,32 +871,6 @@ module DataFlow {
923871 override string getPropertyName() { none() }
924872 }
925873
926- /**
927- * A data flow node representing an unused parameter.
928- *
929- * This case exists to ensure all parameters have a corresponding data-flow node.
930- * In most cases, parameters are represented by SSA definitions or destructuring pattern nodes.
931- */
932- private class UnusedParameterNode extends DataFlow::Node, TUnusedParameterNode {
933- SimpleParameter p;
934-
935- UnusedParameterNode() { this = TUnusedParameterNode(p) }
936-
937- override string toString() { result = p.toString() }
938-
939- override ASTNode getAstNode() { result = p }
940-
941- override BasicBlock getBasicBlock() { result = p.getBasicBlock() }
942-
943- override predicate hasLocationInfo(
944- string filepath, int startline, int startcolumn, int endline, int endcolumn
945- ) {
946- p.getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
947- }
948-
949- override File getFile() { result = p.getFile() }
950- }
951-
952874 /**
953875 * A data flow node representing an HTML attribute.
954876 */
@@ -1302,7 +1224,7 @@ module DataFlow {
13021224 /**
13031225 * INTERNAL: Use `parameterNode(Parameter)` instead.
13041226 */
1305- predicate parameterNode(DataFlow::Node nd, Parameter p) { nd = lvalueNode (p) }
1227+ predicate parameterNode(DataFlow::Node nd, Parameter p) { nd = valueNode (p) }
13061228
13071229 /**
13081230 * INTERNAL: Use `thisNode(StmtContainer container)` instead.
@@ -1354,9 +1276,7 @@ module DataFlow {
13541276 result = TSsaDefNode(ssa)
13551277 )
13561278 or
1357- result = TDestructuringPatternNode(lvalue)
1358- or
1359- result = TUnusedParameterNode(lvalue)
1279+ result = TValueNode(lvalue.(DestructuringPattern))
13601280 }
13611281
13621282 /**
@@ -1411,6 +1331,17 @@ module DataFlow {
14111331 succ = lvalueNode(def.getTarget())
14121332 )
14131333 or
1334+ exists(SimpleParameter param |
1335+ pred = valueNode(param) and // The value node represents the incoming argument
1336+ succ = lvalueNode(param) // The SSA node represents the parameters's local variable
1337+ )
1338+ or
1339+ exists(Expr arg, Parameter param |
1340+ localArgumentPassing(arg, param) and
1341+ pred = valueNode(arg) and
1342+ succ = valueNode(param)
1343+ )
1344+ or
14141345 exists(PropertyPattern pattern |
14151346 pred = TPropNode(pattern) and
14161347 succ = lvalueNode(pattern.getValuePattern())
@@ -1546,8 +1477,7 @@ module DataFlow {
15461477 */
15471478 private AST::ValueNode defSourceNode(VarDef def) {
15481479 result = def.getSource() or
1549- result = def.getDestructuringSource() or
1550- localArgumentPassing(result, def)
1480+ result = def.getDestructuringSource()
15511481 }
15521482
15531483 /**
@@ -1593,8 +1523,15 @@ module DataFlow {
15931523 e instanceof FunctionBindExpr
15941524 or
15951525 e instanceof TaggedTemplateExpr
1526+ or
1527+ e instanceof Parameter and
1528+ not localArgumentPassing(_, e) and
1529+ not isAnalyzedParameter(e) and
1530+ not e.(Parameter).isRestParameter()
15961531 )
15971532 or
1533+ nd.(AnalyzedNode).hasAdditionalIncompleteness(cause)
1534+ or
15981535 nd.asExpr() instanceof ExternalModuleReference and
15991536 cause = "import"
16001537 or
@@ -1622,18 +1559,12 @@ module DataFlow {
16221559 exists(PropertyPattern p | nd = TPropNode(p)) and cause = "heap"
16231560 or
16241561 nd instanceof TElementPatternNode and cause = "heap"
1625- or
1626- nd instanceof UnusedParameterNode and cause = "call"
16271562 }
16281563
16291564 /**
16301565 * Holds if definition `def` cannot be completely analyzed due to `cause`.
16311566 */
16321567 private predicate defIsIncomplete(VarDef def, Incompleteness cause) {
1633- def instanceof Parameter and
1634- not localArgumentPassing(_, def) and
1635- cause = "call"
1636- or
16371568 def instanceof ImportSpecifier and
16381569 cause = "import"
16391570 or
0 commit comments