1+ /**
2+ * Provides classes for working with defensive programming patterns.
3+ */
4+
15import javascript
6+ private import semmle.javascript.dataflow.InferredTypes
27
38/**
4- * A defensive truthiness check that may be worth keeping, even if it
5- * is strictly speaking useless.
6- *
7- * We currently recognize three patterns:
8- *
9- * - the first `x` in `x || (x = e)`
10- * - the second `x` in `x = (x || e)`
11- * - the second `x` in `var x = x || e`
9+ * The test in a defensive programming pattern.
1210 */
13- class DefensiveInit extends DataFlow:: ValueNode {
14- DefensiveInit ( ) {
15- exists ( VarAccess va , LogOrExpr o , VarRef va2 |
16- va = astNode and
17- va = o .getLeftOperand ( ) .stripParens ( ) and va2 .getVariable ( ) = va .getVariable ( ) |
18- exists ( AssignExpr assgn | va2 = assgn .getTarget ( ) |
19- assgn = o .getRightOperand ( ) .stripParens ( ) or
20- o = assgn .getRhs ( ) .stripParens ( )
11+ abstract class DefensiveExpression extends DataFlow:: ValueNode {
12+ /** Gets the unique Boolean value that this test evaluates to, if any. */
13+ abstract boolean getTheTestResult ( ) ;
14+ }
15+
16+ /**
17+ * INTERNAL: Do not use directly; use `DefensiveExpression` instead.
18+ */
19+ module Internal {
20+ /**
21+ * A defensive truthiness check that may be worth keeping, even if it
22+ * is strictly speaking useless.
23+ *
24+ * We currently recognize three patterns:
25+ *
26+ * - the first `x` in `x || (x = e)`
27+ * - the second `x` in `x = (x || e)`
28+ * - the second `x` in `var x = x || e`
29+ */
30+ class DefensiveInit extends DefensiveExpression {
31+ DefensiveInit ( ) {
32+ exists ( VarAccess va , LogOrExpr o , VarRef va2 |
33+ va = astNode and
34+ va = o .getLeftOperand ( ) .stripParens ( ) and va2 .getVariable ( ) = va .getVariable ( ) |
35+ exists ( AssignExpr assgn | va2 = assgn .getTarget ( ) |
36+ assgn = o .getRightOperand ( ) .stripParens ( ) or
37+ o = assgn .getRhs ( ) .stripParens ( )
38+ )
39+ or
40+ exists ( VariableDeclarator vd | va2 = vd .getBindingPattern ( ) | o = vd .getInit ( ) .stripParens ( ) )
2141 )
22- or
23- exists ( VariableDeclarator vd | va2 = vd .getBindingPattern ( ) | o = vd .getInit ( ) .stripParens ( ) )
24- )
42+ }
43+
44+ override boolean getTheTestResult ( ) {
45+ result = analyze ( ) .getTheBooleanValue ( )
46+ }
2547 }
2648
2749}
0 commit comments