refactor FunctionStyleClass to get a better join-order

This commit is contained in:
Erik Krogh Kristensen
2021-03-02 15:22:38 +01:00
parent 4d33407f6c
commit 95a1edcabc

View File

@@ -1172,6 +1172,16 @@ module ClassNode {
result.getFile() = f
}
/**
* Gets a reference to the function `func`, where there exists a read/write of the "prototype" property on that reference.
*/
pragma[noinline]
private DataFlow::SourceNode getAFunctionValueWithPrototype(AbstractValue func) {
exists(result.getAPropertyReference("prototype")) and
result.analyze().getAValue() = pragma[only_bind_into](func) and
func instanceof AbstractFunction // the join-order goes bad if `func` has type `AbstractFunction`.
}
/**
* A function definition with prototype manipulation as a `ClassNode` instance.
*/
@@ -1182,10 +1192,7 @@ module ClassNode {
FunctionStyleClass() {
function.getFunction() = astNode and
(
exists(DataFlow::PropRef read |
read.getPropertyName() = "prototype" and
read.getBase().analyze().getAValue() = function
)
exists(getAFunctionValueWithPrototype(function))
or
exists(string name |
this = AccessPath::getAnAssignmentTo(name) and
@@ -1246,7 +1253,7 @@ module ClassNode {
* Gets a reference to the prototype of this class.
*/
DataFlow::SourceNode getAPrototypeReference() {
exists(DataFlow::SourceNode base | base.analyze().getAValue() = function |
exists(DataFlow::SourceNode base | base = getAFunctionValueWithPrototype(function) |
result = base.getAPropertyRead("prototype")
or
result = base.getAPropertySource("prototype")