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. * In other words, it does not subclass any other Grape API class in source code.
*/ */
class RootApi extends GrapeApiClass { class RootApi extends GrapeApiClass {
RootApi() { RootApi() { not this = any(GrapeApiClass parent).getAnImmediateDescendent() }
not this = any(GrapeApiClass parent).getAnImmediateDescendent()
}
} }
/** /**
@@ -44,9 +42,7 @@ module Grape {
* ``` * ```
*/ */
class GrapeApiClass extends DataFlow::ClassNode { class GrapeApiClass extends DataFlow::ClassNode {
GrapeApiClass() { GrapeApiClass() { this = grapeApiBaseClass().getADescendentModule() }
this = grapeApiBaseClass().getADescendentModule()
}
/** /**
* Gets a `GrapeEndpoint` defined in this class. * Gets a `GrapeEndpoint` defined in this class.
@@ -63,6 +59,20 @@ module Grape {
// is invoked with an instance as the `self`. // is invoked with an instance as the `self`.
result = this.getModuleLevelSelf() 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() { private DataFlow::ConstRef grapeApiBaseClass() {
@@ -122,17 +132,12 @@ module Grape {
*/ */
private class GrapeParamsCall extends ParamsCallImpl { private class GrapeParamsCall extends ParamsCallImpl {
GrapeParamsCall() { GrapeParamsCall() {
// Params calls within endpoint blocks exists(API::Node n | this = n.getAMethodCall("params").asExpr().getExpr() |
exists(GrapeApiClass api | // Params calls within endpoint blocks
this.getMethodName() = "params" and n = grapeApiInstance()
this.getParent+() = api.getADeclaration() or
) // Params calls within helper methods (defined in helpers blocks)
or n = any(GrapeApiClass c).getHelperSelf().track()
// 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()
) )
} }
} }