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