Files
codeql/javascript/ql/lib/semmle/javascript/Constants.qll
Erik Krogh Kristensen f39872e649 cache more predicates
2021-11-22 09:03:36 +01:00

155 lines
3.7 KiB
Plaintext

/**
* Provides classes for working with expressions that evaluate to constant values.
*/
import javascript
private import semmle.javascript.internal.CachedStages
/**
* An expression that evaluates to a constant primitive value.
*/
cached
abstract class ConstantExpr extends Expr { }
/**
* Provides classes for expressions that evaluate to constant values according to a bottom-up syntactic analysis.
*/
module SyntacticConstants {
/**
* An expression that evaluates to a constant value according to a bottom-up syntactic analysis.
*/
cached
abstract class SyntacticConstant extends ConstantExpr { }
/**
* A literal primitive expression.
*
* Note that `undefined`, `NaN` and `Infinity` are global variables, and are not covered by this class.
*/
cached
class PrimitiveLiteralConstant extends SyntacticConstant {
cached
PrimitiveLiteralConstant() {
Stages::Ast::ref() and
this instanceof NumberLiteral
or
this instanceof StringLiteral
or
this instanceof BooleanLiteral
or
exists(TemplateLiteral lit | lit = this |
lit.getNumChildExpr() = 0
or
lit.getNumChildExpr() = 1 and
lit.getElement(0) instanceof TemplateElement
)
}
}
/**
* A literal null expression.
*/
cached
class NullConstant extends SyntacticConstant, NullLiteral {
cached
NullConstant() { Stages::Ast::ref() and this = this }
}
/**
* A unary operation on a syntactic constant.
*/
cached
class UnaryConstant extends SyntacticConstant, UnaryExpr {
cached
UnaryConstant() { getOperand() instanceof SyntacticConstant }
}
/**
* A binary operation on syntactic constants.
*/
cached
class BinaryConstant extends SyntacticConstant, BinaryExpr {
cached
BinaryConstant() {
getLeftOperand() instanceof SyntacticConstant and
getRightOperand() instanceof SyntacticConstant
}
}
/**
* A conditional expression on syntactic constants.
*/
cached
class ConditionalConstant extends SyntacticConstant, ConditionalExpr {
cached
ConditionalConstant() {
getCondition() instanceof SyntacticConstant and
getConsequent() instanceof SyntacticConstant and
getAlternate() instanceof SyntacticConstant
}
}
/**
* A use of the global variable `undefined` or `void e`.
*/
cached
class UndefinedConstant extends SyntacticConstant {
cached
UndefinedConstant() {
this.(GlobalVarAccess).getName() = "undefined" or
this instanceof VoidExpr
}
}
/**
* A use of the global variable `NaN`.
*/
cached
class NaNConstant extends SyntacticConstant {
cached
NaNConstant() { this.(GlobalVarAccess).getName() = "NaN" }
}
/**
* A use of the global variable `Infinity`.
*/
cached
class InfinityConstant extends SyntacticConstant {
cached
InfinityConstant() { this.(GlobalVarAccess).getName() = "Infinity" }
}
/**
* An expression that wraps the syntactic constant it evaluates to.
*/
cached
class WrappedConstant extends SyntacticConstant {
cached
WrappedConstant() { getUnderlyingValue() instanceof SyntacticConstant }
}
/**
* Holds if `c` evaluates to `undefined`.
*/
predicate isUndefined(SyntacticConstant c) { c.getUnderlyingValue() instanceof UndefinedConstant }
/**
* Holds if `c` evaluates to `null`.
*/
predicate isNull(SyntacticConstant c) { c.getUnderlyingValue() instanceof NullConstant }
/**
* Holds if `c` evaluates to `null` or `undefined`.
*/
predicate isNullOrUndefined(SyntacticConstant c) { isUndefined(c) or isNull(c) }
}
/**
* An expression that evaluates to a constant string.
*/
cached
class ConstantString extends ConstantExpr {
cached
ConstantString() { exists(getStringValue()) }
}