Refactor RootApi and GrapeApiClass constructors for improved readability; add getHelperSelf method to retrieve self parameter in helpers block.

This commit is contained in:
Chad Bentz
2025-09-22 10:13:33 -04:00
parent 1bf6101967
commit b837c56bec

View File

@@ -25,9 +25,7 @@ module Grape {
* In other words, it does not subclass any other Grape API class in source code.
*/
class RootApi extends GrapeApiClass {
RootApi() {
not this = any(GrapeApiClass parent).getAnImmediateDescendent()
}
RootApi() { not this = any(GrapeApiClass parent).getAnImmediateDescendent() }
}
/**
@@ -44,9 +42,7 @@ module Grape {
* ```
*/
class GrapeApiClass extends DataFlow::ClassNode {
GrapeApiClass() {
this = grapeApiBaseClass().getADescendentModule()
}
GrapeApiClass() { this = grapeApiBaseClass().getADescendentModule() }
/**
* Gets a `GrapeEndpoint` defined in this class.
@@ -63,6 +59,20 @@ module Grape {
// is invoked with an instance as the `self`.
result = this.getModuleLevelSelf()
}
/**
* Gets the `self` parameter belonging to a method defined within a
* `helpers` block in this API class.
*
* These methods become available in endpoint contexts through Grape's DSL.
*/
DataFlow::SelfParameterNode getHelperSelf() {
exists(DataFlow::CallNode helpersCall |
helpersCall = this.getAModuleLevelCall("helpers") and
result.getSelfVariable().getDeclaringScope().getOuterScope+() =
helpersCall.getBlock().asExpr().getExpr()
)
}
}
private DataFlow::ConstRef grapeApiBaseClass() {
@@ -122,17 +132,12 @@ module Grape {
*/
private class GrapeParamsCall extends ParamsCallImpl {
GrapeParamsCall() {
// Params calls within endpoint blocks
exists(GrapeApiClass api |
this.getMethodName() = "params" and
this.getParent+() = api.getADeclaration()
)
or
// Params calls within helper methods (defined in helpers blocks)
exists(GrapeApiClass api, DataFlow::CallNode helpersCall |
helpersCall = api.getAModuleLevelCall("helpers") and
this.getMethodName() = "params" and
this.getParent+() = helpersCall.getBlock().asExpr().getExpr()
exists(API::Node n | this = n.getAMethodCall("params").asExpr().getExpr() |
// Params calls within endpoint blocks
n = grapeApiInstance()
or
// Params calls within helper methods (defined in helpers blocks)
n = any(GrapeApiClass c).getHelperSelf().track()
)
}
}