Skip to content

Commit c47e6e3

Browse files
Add qldoc
1 parent f1026e4 commit c47e6e3

File tree

1 file changed

+21
-0
lines changed

1 file changed

+21
-0
lines changed

python/ql/src/Classes/CallsToInitDel/MethodCallOrder.qll

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import semmle.python.ApiGraphs
55
import semmle.python.dataflow.new.internal.DataFlowDispatch
66
import codeql.util.Option
77

8+
/** Holds if `meth` is a method named `name` that transitively calls `calledMulti` of the same name via the calls `call1` and `call2`. */
89
predicate multipleCallsToSuperclassMethod(
910
Function meth, Function calledMulti, DataFlow::MethodCallNode call1,
1011
DataFlow::MethodCallNode call2, string name
@@ -19,6 +20,7 @@ predicate multipleCallsToSuperclassMethod(
1920
)
2021
}
2122

23+
/** Gets a method transitively called by `meth` named `name` with `call` that it overrides, with `mroBase` as the type determining the MRO to search. */
2224
Function getASuperCallTargetFromCall(
2325
Class mroBase, Function meth, DataFlow::MethodCallNode call, string name
2426
) {
@@ -29,6 +31,7 @@ Function getASuperCallTargetFromCall(
2931
)
3032
}
3133

34+
/** Gets the method called by `meth` named `name` with `call`, with `mroBase` as the type determining the MRO to search. */
3235
Function getDirectSuperCallTargetFromCall(
3336
Class mroBase, Function meth, DataFlow::MethodCallNode call, string name
3437
) {
@@ -51,6 +54,7 @@ Function getDirectSuperCallTargetFromCall(
5154
)
5255
}
5356

57+
/** Gets a method that is transitively called by a call to `cls.<name>`, with `mroBase` as the type determining the MRO to search. */
5458
Function getASuperCallTargetFromClass(Class mroBase, Class cls, string name) {
5559
exists(Function target |
5660
target = findFunctionAccordingToMroKnownStartingClass(cls, mroBase, name) and
@@ -62,6 +66,7 @@ Function getASuperCallTargetFromClass(Class mroBase, Class cls, string name) {
6266
)
6367
}
6468

69+
/** Holds if `meth` does something besides calling a superclass method. */
6570
predicate nonTrivial(Function meth) {
6671
exists(Stmt s | s = meth.getAStmt() |
6772
not s instanceof Pass and
@@ -74,20 +79,23 @@ predicate nonTrivial(Function meth) {
7479
exists(meth.getANormalExit()) // doesn't always raise an exception
7580
}
7681

82+
/** Holds if `call` is a call to `super().<name>`. No distinction is made btween 0- and 2- arg super calls. */
7783
predicate superCall(DataFlow::MethodCallNode call, string name) {
7884
exists(DataFlow::Node sup |
7985
call.calls(sup, name) and
8086
sup = API::builtin("super").getACall()
8187
)
8288
}
8389

90+
/** Holds if `meth` calls `super().<name>` where `name` is the name of the method. */
8491
predicate callsSuper(Function meth) {
8592
exists(DataFlow::MethodCallNode call |
8693
call.getScope() = meth and
8794
superCall(call, meth.getName())
8895
)
8996
}
9097

98+
/** Holds if `meth` calls `target.<name>(self, ...)` with the call `call`. */
9199
predicate callsMethodOnClassWithSelf(
92100
Function meth, DataFlow::MethodCallNode call, Class target, string name
93101
) {
@@ -99,6 +107,7 @@ predicate callsMethodOnClassWithSelf(
99107
)
100108
}
101109

110+
/** Holds if `meth` calls a method named `name` passing its `self` argument as its first parameter, but the class it refers to is unknown. */
102111
predicate callsMethodOnUnknownClassWithSelf(Function meth, string name) {
103112
exists(DataFlow::MethodCallNode call, DataFlow::Node callTarget, DataFlow::ParameterNode self |
104113
call.calls(callTarget, name) and
@@ -108,6 +117,7 @@ predicate callsMethodOnUnknownClassWithSelf(Function meth, string name) {
108117
)
109118
}
110119

120+
/** Holds if `base` does not call a superclass method `shouldCall` named `name` when it appears it should. */
111121
predicate missingCallToSuperclassMethod(Class base, Function shouldCall, string name) {
112122
shouldCall.getName() = name and
113123
shouldCall.getScope() = getADirectSuperclass+(base) and
@@ -117,6 +127,9 @@ predicate missingCallToSuperclassMethod(Class base, Function shouldCall, string
117127
not callsMethodOnUnknownClassWithSelf(getASuperCallTargetFromClass(base, base, name), name)
118128
}
119129

130+
/** Holds if `base` does not call a superclass method `shouldCall` named `name` when it appears it should.
131+
* Results are restricted to hold only for the highest `base` class and the lowest `shouldCall` method in the heirarchy for which this applies.
132+
*/
120133
predicate missingCallToSuperclassMethodRestricted(Class base, Function shouldCall, string name) {
121134
missingCallToSuperclassMethod(base, shouldCall, name) and
122135
not exists(Class superBase |
@@ -131,6 +144,11 @@ predicate missingCallToSuperclassMethodRestricted(Class base, Function shouldCal
131144
)
132145
}
133146

147+
/**
148+
* If `base` contains a `super()` call, gets a method in the inheritence heirarchy of `name` in the MRO of `base`
149+
* that does not contain a `super()` call, but would call `shouldCall` if it did, which does not otherwise get called
150+
* during a call to `base.<name>`.
151+
* */
134152
Function getPossibleMissingSuper(Class base, Function shouldCall, string name) {
135153
missingCallToSuperclassMethod(base, shouldCall, name) and
136154
exists(Function baseMethod |
@@ -151,6 +169,7 @@ Function getPossibleMissingSuper(Class base, Function shouldCall, string name) {
151169

152170
private module FunctionOption = Option<Function>;
153171

172+
/** An optional `Function`. */
154173
class FunctionOption extends FunctionOption::Option {
155174
/**
156175
* Holds if this element is at the specified location.
@@ -174,6 +193,7 @@ class FunctionOption extends FunctionOption::Option {
174193
endcolumn = 0
175194
}
176195

196+
/** Gets the qualified name of this function. */
177197
string getQualifiedName() {
178198
result = this.asSome().getQualifiedName()
179199
or
@@ -182,6 +202,7 @@ class FunctionOption extends FunctionOption::Option {
182202
}
183203
}
184204

205+
/** Gets the result of `getPossibleMissingSuper`, or None if none exists. */
185206
bindingset[name]
186207
FunctionOption getPossibleMissingSuperOption(Class base, Function shouldCall, string name) {
187208
result.asSome() = getPossibleMissingSuper(base, shouldCall, name)

0 commit comments

Comments
 (0)