21
21
import javascript
22
22
private import internal.CallGraphs
23
23
private import internal.FlowSteps as FlowSteps
24
+ private import internal.DataFlowNode
25
+ private import internal.AnalyzedParameters
24
26
25
27
module 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
-
50
28
/**
51
29
* A node in the data flow graph.
52
30
*/
@@ -90,13 +68,11 @@ module DataFlow {
90
68
/**
91
69
* Gets the expression enclosing this data flow node.
92
70
* 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.
95
72
*/
96
73
Expr getEnclosingExpr ( ) {
97
74
result = asExpr ( ) or
98
- this = DataFlow:: reflectiveCallNode ( result ) or
99
- result = this .( ParameterNode ) .getParameter ( )
75
+ this = DataFlow:: reflectiveCallNode ( result )
100
76
}
101
77
102
78
/** Gets the AST node corresponding to this data flow node, if any. */
@@ -251,7 +227,7 @@ module DataFlow {
251
227
*/
252
228
private JSDocTypeExpr getFallbackTypeAnnotation ( ) {
253
229
exists ( BindingPattern pattern |
254
- this = lvalueNode ( pattern ) and
230
+ this = valueNode ( pattern ) and
255
231
not ast_node_type ( pattern , _) and
256
232
result = pattern .getTypeAnnotation ( )
257
233
)
@@ -281,8 +257,8 @@ module DataFlow {
281
257
}
282
258
283
259
/**
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 .
286
262
*
287
263
* Examples:
288
264
* ```js
@@ -390,30 +366,6 @@ module DataFlow {
390
366
override ASTNode getAstNode ( ) { result = rest }
391
367
}
392
368
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
-
417
369
/**
418
370
* A node in the data flow graph which corresponds to an element pattern of an
419
371
* array pattern.
@@ -759,10 +711,6 @@ module DataFlow {
759
711
parameterNode ( paramNode , param )
760
712
|
761
713
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 ( )
766
714
)
767
715
}
768
716
@@ -850,7 +798,7 @@ module DataFlow {
850
798
/** Gets the value pattern of this property pattern. */
851
799
Expr getValuePattern ( ) { result = prop .getValuePattern ( ) }
852
800
853
- override Node getBase ( ) { result = TDestructuringPatternNode ( prop .getObjectPattern ( ) ) }
801
+ override Node getBase ( ) { result = TValueNode ( prop .getObjectPattern ( ) ) }
854
802
855
803
override Expr getPropertyNameExpr ( ) { result = prop .getNameExpr ( ) }
856
804
@@ -863,7 +811,7 @@ module DataFlow {
863
811
* for `[ ...elts ] = arr`.
864
812
*/
865
813
private class RestPatternAsPropRead extends PropRead , RestPatternNode {
866
- override Node getBase ( ) { result = TDestructuringPatternNode ( pattern ) }
814
+ override Node getBase ( ) { result = TValueNode ( pattern ) }
867
815
868
816
override Expr getPropertyNameExpr ( ) { none ( ) }
869
817
@@ -876,7 +824,7 @@ module DataFlow {
876
824
* for `y`.
877
825
*/
878
826
private class ElementPatternAsPropRead extends PropRead , ElementPatternNode {
879
- override Node getBase ( ) { result = TDestructuringPatternNode ( pattern ) }
827
+ override Node getBase ( ) { result = TValueNode ( pattern ) }
880
828
881
829
override Expr getPropertyNameExpr ( ) { none ( ) }
882
830
@@ -923,32 +871,6 @@ module DataFlow {
923
871
override string getPropertyName ( ) { none ( ) }
924
872
}
925
873
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
-
952
874
/**
953
875
* A data flow node representing an HTML attribute.
954
876
*/
@@ -1302,7 +1224,7 @@ module DataFlow {
1302
1224
/**
1303
1225
* INTERNAL: Use `parameterNode(Parameter)` instead.
1304
1226
*/
1305
- predicate parameterNode ( DataFlow:: Node nd , Parameter p ) { nd = lvalueNode ( p ) }
1227
+ predicate parameterNode ( DataFlow:: Node nd , Parameter p ) { nd = valueNode ( p ) }
1306
1228
1307
1229
/**
1308
1230
* INTERNAL: Use `thisNode(StmtContainer container)` instead.
@@ -1354,9 +1276,7 @@ module DataFlow {
1354
1276
result = TSsaDefNode ( ssa )
1355
1277
)
1356
1278
or
1357
- result = TDestructuringPatternNode ( lvalue )
1358
- or
1359
- result = TUnusedParameterNode ( lvalue )
1279
+ result = TValueNode ( lvalue .( DestructuringPattern ) )
1360
1280
}
1361
1281
1362
1282
/**
@@ -1411,6 +1331,17 @@ module DataFlow {
1411
1331
succ = lvalueNode ( def .getTarget ( ) )
1412
1332
)
1413
1333
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
1414
1345
exists ( PropertyPattern pattern |
1415
1346
pred = TPropNode ( pattern ) and
1416
1347
succ = lvalueNode ( pattern .getValuePattern ( ) )
@@ -1546,8 +1477,7 @@ module DataFlow {
1546
1477
*/
1547
1478
private AST:: ValueNode defSourceNode ( VarDef def ) {
1548
1479
result = def .getSource ( ) or
1549
- result = def .getDestructuringSource ( ) or
1550
- localArgumentPassing ( result , def )
1480
+ result = def .getDestructuringSource ( )
1551
1481
}
1552
1482
1553
1483
/**
@@ -1593,8 +1523,15 @@ module DataFlow {
1593
1523
e instanceof FunctionBindExpr
1594
1524
or
1595
1525
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 ( )
1596
1531
)
1597
1532
or
1533
+ nd .( AnalyzedNode ) .hasAdditionalIncompleteness ( cause )
1534
+ or
1598
1535
nd .asExpr ( ) instanceof ExternalModuleReference and
1599
1536
cause = "import"
1600
1537
or
@@ -1622,18 +1559,12 @@ module DataFlow {
1622
1559
exists ( PropertyPattern p | nd = TPropNode ( p ) ) and cause = "heap"
1623
1560
or
1624
1561
nd instanceof TElementPatternNode and cause = "heap"
1625
- or
1626
- nd instanceof UnusedParameterNode and cause = "call"
1627
1562
}
1628
1563
1629
1564
/**
1630
1565
* Holds if definition `def` cannot be completely analyzed due to `cause`.
1631
1566
*/
1632
1567
private predicate defIsIncomplete ( VarDef def , Incompleteness cause ) {
1633
- def instanceof Parameter and
1634
- not localArgumentPassing ( _, def ) and
1635
- cause = "call"
1636
- or
1637
1568
def instanceof ImportSpecifier and
1638
1569
cause = "import"
1639
1570
or
0 commit comments