-
Notifications
You must be signed in to change notification settings - Fork 3
Description
Port classes that model UI5's JavaScript APIs to MaD as much as possible. Take the characteristic predicate of ControlReference for example:
/**
* A JS reference to a `UI5Control`, commonly obtained via its ID.
*/
class ControlReference extends Reference {
string controlId;
ControlReference() {
this.getArgument(0).getALocalSource().getStringValue() = controlId and
(
exists(CustomController controller |
this = controller.getAViewReference().getAMemberCall("byId") or
this = controller.getAThisNode().getAMemberCall("byId")
)
or
exists(SapUiCore sapUiCore | this = sapUiCore.getAMemberCall("byId"))
)
}
...
}This will break the controller's view reference this.getView() (where this denotes the controller) is stored in a property of the controller (e.g. this.myView = this.getView()) in a method f and later that gets used in another method g instead of calling this.getView() again. (The #258 PR gives an excellent example of this.)
MaD can solve these cases easily. In ui5.model.yml we already have:
extensions:
- addsTo:
pack: codeql/javascript-all
extensible: "typeModel"
data:
- ["Controller", "sap/ui/core/mvc/Controller", ""]
- ["ViewReference", "CustomController", "Member[getView].ReturnValue"]
- ["ControlReference", "ViewReference", "Member[byId].ReturnValue"]Now, we'd just have to connect them in QL.
ControlReference() {
/* ... */
exists(API::Node controlReferenceAbstract, API::Node customControllerAbstract, CustomController customController |
controlReferenceAbstract = ModelOutput::getATypeNode("ControlReference") and
customControllerAbstract = ModelOutput::getATypeNode("CustomController") and
controlReferenceAbstract = customControllerAbstract.getASuccessor+() and
this = controlReferenceAbstract.getInducingNode() and
customController = customControllerAbstract.getInducingNode()
)
}(The controlReferenceAbstract = customControllerAbstract.getASuccessor+() may not even be necessary as API::Nodes are closely tied to DataFlow::Nodes.) Anyways, the API graph library takes the MaD strings above in the typeModel, performs interprocedural tracking all the way to the hypothetical this.myView property read in a different method.
Therefore, use the above MaD + API graph method whenever such interprocedural tracking is needed, instead of using .getAMemberCall/1 which only tracks local flows.