mirror of
https://github.com/github/codeql.git
synced 2026-04-29 10:45:15 +02:00
JavaScript: Refactor a few predicates to avoid materialisations.
This commit is contained in:
@@ -254,22 +254,18 @@ class AnalyzedFunction extends DataFlow::AnalyzedValueNode {
|
||||
* Gets a return value for a call to this function.
|
||||
*/
|
||||
AbstractValue getAReturnValue() {
|
||||
if astNode.isGenerator() or astNode.isAsync() then
|
||||
result = TAbstractOtherObject()
|
||||
else (
|
||||
// explicit return value
|
||||
result = astNode.getAReturnedExpr().analyze().getALocalValue()
|
||||
// explicit return value
|
||||
result = astNode.getAReturnedExpr().analyze().getALocalValue()
|
||||
or
|
||||
// implicit return value
|
||||
(
|
||||
// either because execution of the function may terminate normally
|
||||
mayReturnImplicitly()
|
||||
or
|
||||
// implicit return value
|
||||
(
|
||||
// either because execution of the function may terminate normally
|
||||
mayReturnImplicitly()
|
||||
or
|
||||
// or because there is a bare `return;` statement
|
||||
exists (ReturnStmt ret | ret = astNode.getAReturnStmt() | not exists(ret.getExpr()))
|
||||
) and
|
||||
result = TAbstractUndefined()
|
||||
)
|
||||
// or because there is a bare `return;` statement
|
||||
exists (ReturnStmt ret | ret = astNode.getAReturnStmt() | not exists(ret.getExpr()))
|
||||
) and
|
||||
result = TAbstractUndefined()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -288,5 +284,26 @@ class AnalyzedFunction extends DataFlow::AnalyzedValueNode {
|
||||
not final instanceof ThrowStmt
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Flow analysis for generator functions.
|
||||
*/
|
||||
private class AnalyzedGeneratorFunction extends AnalyzedFunction {
|
||||
AnalyzedGeneratorFunction() { astNode.isGenerator() }
|
||||
|
||||
override AbstractValue getAReturnValue() {
|
||||
result = TAbstractOtherObject()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Flow analysis for async functions.
|
||||
*/
|
||||
private class AnalyzedAsyncFunction extends AnalyzedFunction {
|
||||
AnalyzedAsyncFunction() { astNode.isAsync() }
|
||||
|
||||
override AbstractValue getAReturnValue() {
|
||||
result = TAbstractOtherObject()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,16 +39,7 @@ AbstractValue getAnInitialPropertyValue(DefiniteAbstractValue baseVal, string pr
|
||||
)
|
||||
or
|
||||
// class members
|
||||
exists (ClassDefinition c, DataFlow::AnalyzedNode init, MemberDefinition m |
|
||||
m = c.getMember(propertyName) and
|
||||
not m instanceof AccessorMethodDefinition and
|
||||
init = m.getInit().analyze() and
|
||||
result = init.getALocalValue() |
|
||||
if m.isStatic() then
|
||||
baseVal = TAbstractClass(c)
|
||||
else
|
||||
baseVal = AbstractInstance::of(c)
|
||||
)
|
||||
result = getAnInitialMemberValue(getMember(baseVal, propertyName))
|
||||
or
|
||||
// object properties
|
||||
exists (ValueProperty p |
|
||||
@@ -63,6 +54,30 @@ AbstractValue getAnInitialPropertyValue(DefiniteAbstractValue baseVal, string pr
|
||||
result = TAbstractInstance(baseVal)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a class member definition that we abstractly represent as a property of `baseVal`
|
||||
* with the given `name`.
|
||||
*/
|
||||
private MemberDefinition getMember(DefiniteAbstractValue baseVal, string name) {
|
||||
exists (ClassDefinition c | result = c.getMember(name) |
|
||||
if result.isStatic() then
|
||||
baseVal = TAbstractClass(c)
|
||||
else
|
||||
baseVal = AbstractInstance::of(c)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an abstract representation of the initial value of member definition `m`.
|
||||
*
|
||||
* For (non-accessor) methods, this is the abstract function corresponding to the
|
||||
* method. For fields, it is an abstract representation of their initial value(s).
|
||||
*/
|
||||
private AbstractValue getAnInitialMemberValue(MemberDefinition m) {
|
||||
not m instanceof AccessorMethodDefinition and
|
||||
result = m.getInit().analyze().getALocalValue()
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `baseVal` is an abstract value whose properties we track for the purposes
|
||||
* of `getALocalValue`.
|
||||
|
||||
Reference in New Issue
Block a user