Skip to content

Commit b3aa358

Browse files
committed
outline callee computation - to avoid many joins on getACall
1 parent aa6cde2 commit b3aa358

File tree

1 file changed

+48
-45
lines changed

1 file changed

+48
-45
lines changed

javascript/ql/src/semmle/javascript/frameworks/PropertyProjection.qll

Lines changed: 48 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,53 @@ module PropertyProjection {
6565

6666
deprecated class CustomPropertyProjection = PropertyProjection::Range;
6767

68+
/**
69+
* Gets a callee of a simple property projection call.
70+
* This predicate is used exclusively in `SimplePropertyProjection`.
71+
*/
72+
pragma[noinline]
73+
private DataFlow::SourceNode getASimplePropertyProjectionCallee(
74+
boolean singleton, int selectorIndex, int objectIndex
75+
) {
76+
singleton = false and
77+
(
78+
result = LodashUnderscore::member("pick") and
79+
objectIndex = 0 and
80+
selectorIndex = [1 .. max(result.getACall().getNumArgument())]
81+
or
82+
result = LodashUnderscore::member("pickBy") and
83+
objectIndex = 0 and
84+
selectorIndex = 1
85+
or
86+
result = DataFlow::moduleMember("ramda", ["pick", "pickAll", "pickBy"]) and
87+
objectIndex = 1 and
88+
selectorIndex = 0
89+
or
90+
result = DataFlow::moduleMember("dotty", "search") and
91+
objectIndex = 0 and
92+
selectorIndex = 1
93+
)
94+
or
95+
singleton = true and
96+
(
97+
result = LodashUnderscore::member("get") and
98+
objectIndex = 0 and
99+
selectorIndex = 1
100+
or
101+
result = DataFlow::moduleMember("ramda", "path") and
102+
objectIndex = 1 and
103+
selectorIndex = 0
104+
or
105+
result = DataFlow::moduleMember("dottie", "get") and
106+
objectIndex = 0 and
107+
selectorIndex = 1
108+
or
109+
result = DataFlow::moduleMember("dotty", "get") and
110+
objectIndex = 0 and
111+
selectorIndex = 1
112+
)
113+
}
114+
68115
/**
69116
* A simple model of common property projection functions.
70117
*/
@@ -74,51 +121,7 @@ private class SimplePropertyProjection extends PropertyProjection::Range {
74121
boolean singleton;
75122

76123
SimplePropertyProjection() {
77-
exists(DataFlow::SourceNode callee | this = callee.getACall() |
78-
singleton = false and
79-
(
80-
callee = LodashUnderscore::member("pick") and
81-
objectIndex = 0 and
82-
selectorIndex = [1 .. getNumArgument()]
83-
or
84-
callee = LodashUnderscore::member("pickBy") and
85-
objectIndex = 0 and
86-
selectorIndex = 1
87-
or
88-
exists(string name |
89-
name = "pick" or
90-
name = "pickAll" or
91-
name = "pickBy"
92-
|
93-
callee = DataFlow::moduleMember("ramda", name) and
94-
objectIndex = 1 and
95-
selectorIndex = 0
96-
)
97-
or
98-
callee = DataFlow::moduleMember("dotty", "search") and
99-
objectIndex = 0 and
100-
selectorIndex = 1
101-
)
102-
or
103-
singleton = true and
104-
(
105-
callee = LodashUnderscore::member("get") and
106-
objectIndex = 0 and
107-
selectorIndex = 1
108-
or
109-
callee = DataFlow::moduleMember("ramda", "path") and
110-
objectIndex = 1 and
111-
selectorIndex = 0
112-
or
113-
callee = DataFlow::moduleMember("dottie", "get") and
114-
objectIndex = 0 and
115-
selectorIndex = 1
116-
or
117-
callee = DataFlow::moduleMember("dotty", "get") and
118-
objectIndex = 0 and
119-
selectorIndex = 1
120-
)
121-
)
124+
this = getASimplePropertyProjectionCallee(singleton, selectorIndex, objectIndex).getACall()
122125
}
123126

124127
override DataFlow::Node getObject() { result = getArgument(objectIndex) }

0 commit comments

Comments
 (0)