mirror of
https://github.com/github/codeql.git
synced 2026-04-29 02:35:15 +02:00
Merge pull request #9932 from alexrford/ruby/rbi-typegraph-fixes
Ruby: RBI library changes to support models-as-data model generation
This commit is contained in:
@@ -150,22 +150,14 @@ module Rbi {
|
||||
class ProcCall extends RbiType, SignatureCall, MethodCallAgainstT {
|
||||
ProcCall() { this.getMethodName() = "proc" }
|
||||
|
||||
private ProcReturnsTypeCall getReturnsTypeCall() { result.getProcCall() = this }
|
||||
|
||||
private ProcParamsCall getParamsCall() { result.getProcCall() = this }
|
||||
|
||||
/**
|
||||
* Gets the return type of this type signature.
|
||||
*/
|
||||
override ReturnType getReturnType() { result = this.getReturnsTypeCall().getReturnType() }
|
||||
|
||||
/**
|
||||
* Gets the type of a parameter of this type signature.
|
||||
*/
|
||||
override ParameterType getAParameterType() {
|
||||
result = this.getParamsCall().getAParameterType()
|
||||
override ReturnsTypeCall getReturnsTypeCall() {
|
||||
result.(ProcReturnsTypeCall).getProcCall() = this
|
||||
}
|
||||
// TODO: get associated method to which this can be passed
|
||||
|
||||
override ProcParamsCall getParamsCall() { result.getProcCall() = this }
|
||||
|
||||
// TODO: widen type for procs/blocks
|
||||
override MethodBase getAssociatedMethod() { none() }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -207,15 +199,11 @@ module Rbi {
|
||||
* A call that defines a type signature for a method or proc.
|
||||
*/
|
||||
abstract class SignatureCall extends MethodCall {
|
||||
/**
|
||||
* Gets the return type of this type signature.
|
||||
*/
|
||||
abstract ReturnType getReturnType();
|
||||
abstract ParamsCall getParamsCall();
|
||||
|
||||
/**
|
||||
* Gets the type of a parameter of this type signature.
|
||||
*/
|
||||
abstract ParameterType getAParameterType();
|
||||
abstract ReturnsTypeCall getReturnsTypeCall();
|
||||
|
||||
abstract MethodBase getAssociatedMethod();
|
||||
}
|
||||
|
||||
private predicate isMethodSignatureCallNode(CfgNode n) {
|
||||
@@ -240,20 +228,35 @@ module Rbi {
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* A call to a method named `attr_reader` or `attr_accessor`, used to define
|
||||
* attribute reader methods for a named attribute.
|
||||
*/
|
||||
class AttrReaderMethodCall extends MethodCall {
|
||||
AttrReaderMethodCall() { this.getMethodName() = ["attr_reader", "attr_accessor"] }
|
||||
|
||||
/** Gets a name of an attribute defined by this call. */
|
||||
string getAnAttributeName() {
|
||||
result = this.getAnArgument().getConstantValue().getStringlikeValue()
|
||||
}
|
||||
}
|
||||
|
||||
/** A call to `sig` to define the type signature of a method. */
|
||||
class MethodSignatureCall extends SignatureCall {
|
||||
MethodSignatureCall() { this.getMethodName() = "sig" }
|
||||
|
||||
private MethodReturnsTypeCall getReturnsTypeCall() { result.getMethodSignatureCall() = this }
|
||||
override ReturnsTypeCall getReturnsTypeCall() {
|
||||
result.(MethodReturnsTypeCall).getMethodSignatureCall() = this
|
||||
}
|
||||
|
||||
private MethodParamsCall getParamsCall() { result.getMethodSignatureCall() = this }
|
||||
override MethodParamsCall getParamsCall() { result.getMethodSignatureCall() = this }
|
||||
|
||||
private ExprCfgNode getCfgNode() { result.getExpr() = this }
|
||||
|
||||
/**
|
||||
* Gets the method whose type signature is defined by this call.
|
||||
*/
|
||||
MethodBase getAssociatedMethod() {
|
||||
override MethodBase getAssociatedMethod() {
|
||||
result =
|
||||
min(ExprCfgNode methodCfgNode, int i |
|
||||
methodSignatureSuccessorNodeRanked(this.getCfgNode(), methodCfgNode, i) and
|
||||
@@ -267,10 +270,10 @@ module Rbi {
|
||||
* Gets a call to `attr_reader` or `attr_accessor` where the return type of
|
||||
* the generated method is described by this call.
|
||||
*/
|
||||
MethodCall getAssociatedAttrReaderCall() {
|
||||
AttrReaderMethodCall getAssociatedAttrReaderCall() {
|
||||
result =
|
||||
min(ExprNodes::MethodCallCfgNode c, int i |
|
||||
c.getExpr().getMethodName() = ["attr_reader", "attr_accessor"] and
|
||||
c.getExpr() instanceof AttrReaderMethodCall and
|
||||
methodSignatureSuccessorNodeRanked(this.getCfgNode(), c, i)
|
||||
|
|
||||
c order by i
|
||||
@@ -280,12 +283,7 @@ module Rbi {
|
||||
/**
|
||||
* Gets the return type of this type signature.
|
||||
*/
|
||||
override ReturnType getReturnType() { result = this.getReturnsTypeCall().getReturnType() }
|
||||
|
||||
/**
|
||||
* Gets the type of a parameter of this type signature.
|
||||
*/
|
||||
override ParameterType getAParameterType() { result = this.getParamsCall().getAParameterType() }
|
||||
ReturnType getReturnType() { result = this.getReturnsTypeCall().getReturnType() }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -320,12 +318,54 @@ module Rbi {
|
||||
ParamsCall() { this.getMethodName() = "params" }
|
||||
|
||||
/**
|
||||
* Gets the type of a parameter defined by this call.
|
||||
* Gets the type of a positional parameter defined by this call.
|
||||
*/
|
||||
ParameterType getAParameterType() { result = this.getArgument(_) }
|
||||
ParameterType getPositionalParameterType(int i) {
|
||||
result = this.getArgument(i) and
|
||||
// explicitly exclude keyword parameters
|
||||
not this.getAssociatedParameter(result.getName()) instanceof KeywordParameter and
|
||||
// and exclude block arguments
|
||||
not this.getAssociatedParameter(result.getName()) instanceof BlockParameter
|
||||
}
|
||||
|
||||
/** Gets the type of the keyword parameter named `keyword`. */
|
||||
ParameterType getKeywordParameterType(string keyword) {
|
||||
exists(KeywordParameter kp |
|
||||
kp = this.getAssociatedParameter(keyword) and
|
||||
kp.getName() = keyword and
|
||||
result.getType() = this.getKeywordArgument(keyword)
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets the type of the block parameter to the associated method. */
|
||||
ParameterType getBlockParameterType() {
|
||||
this.getAssociatedParameter(result.getName()) instanceof BlockParameter and
|
||||
result = this.getArgument(_)
|
||||
}
|
||||
|
||||
/** Gets the parameter with the given name. */
|
||||
NamedParameter getAssociatedParameter(string name) {
|
||||
result = this.getSignatureCall().getAssociatedMethod().getAParameter() and
|
||||
result.getName() = name
|
||||
}
|
||||
|
||||
/** Gets the signature call which this params call belongs to. */
|
||||
SignatureCall getSignatureCall() { this = result.getParamsCall() }
|
||||
|
||||
/** Gets a parameter type associated with this call */
|
||||
ParameterType getAParameterType() {
|
||||
result = this.getPositionalParameterType(_) or
|
||||
result = this.getKeywordParameterType(_) or
|
||||
result = this.getBlockParameterType()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A call that defines a return type for an associated method.
|
||||
* The return type is either a specific type, or the void type (i.e. "don't care").
|
||||
*/
|
||||
abstract class ReturnsTypeCall extends MethodCall {
|
||||
/** Get the `ReturnType` corresponding to this call. */
|
||||
abstract ReturnType getReturnType();
|
||||
}
|
||||
|
||||
@@ -391,6 +431,7 @@ module Rbi {
|
||||
abstract class ProcReturnsTypeCall extends ReturnsTypeCall, ProcSignatureDefiningCall { }
|
||||
|
||||
/** A call that defines the parameter types of a proc or block. */
|
||||
// TODO: there is currently no way to map from this to parameter types with actual associated parameters
|
||||
class ProcParamsCall extends ParamsCall, ProcSignatureDefiningCall { }
|
||||
|
||||
/** A call that defines the return type of a non-void proc or block. */
|
||||
@@ -408,25 +449,30 @@ module Rbi {
|
||||
|
||||
/**
|
||||
* A pair defining the type of a parameter to a method.
|
||||
*
|
||||
* This is an argument to some call to `params`.
|
||||
*/
|
||||
class ParameterType extends Pair {
|
||||
private RbiType t;
|
||||
private ParamsCall paramsCall;
|
||||
|
||||
ParameterType() { t = this.getValue() }
|
||||
ParameterType() { paramsCall.getAnArgument() = this }
|
||||
|
||||
/** Gets the `RbiType` of this parameter. */
|
||||
RbiType getType() { result = t }
|
||||
|
||||
private SignatureCall getOuterMethodSignatureCall() { this = result.getAParameterType() }
|
||||
private SignatureCall getMethodSignatureCall() { paramsCall = result.getParamsCall() }
|
||||
|
||||
private MethodBase getAssociatedMethod() {
|
||||
result = this.getOuterMethodSignatureCall().(MethodSignatureCall).getAssociatedMethod()
|
||||
result = this.getMethodSignatureCall().(MethodSignatureCall).getAssociatedMethod()
|
||||
}
|
||||
|
||||
/** Gets the parameter to which this type applies. */
|
||||
/** Gets the `RbiType` of this parameter. */
|
||||
RbiType getType() { result = this.getValue() }
|
||||
|
||||
/** Gets the name of this parameter. */
|
||||
string getName() { result = this.getKey().getConstantValue().getStringlikeValue() }
|
||||
|
||||
/** Gets the `NamedParameter` to which this type applies. */
|
||||
NamedParameter getParameter() {
|
||||
result = this.getAssociatedMethod().getAParameter() and
|
||||
result.getName() = this.getKey().getConstantValue().getStringlikeValue()
|
||||
result.getName() = this.getName()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,9 @@ query predicate hashTypes(RbiHashType ht, RbiType kt, RbiType vt) {
|
||||
kt = ht.getKeyType() and vt = ht.getValueType()
|
||||
}
|
||||
|
||||
query predicate signatureCalls(SignatureCall c, ReturnType r) { r = c.getReturnType() }
|
||||
query predicate signatureCalls(SignatureCall c, ReturnType r) {
|
||||
r = c.getReturnsTypeCall().getReturnType()
|
||||
}
|
||||
|
||||
query predicate paramsCalls(ParamsCall c) { any() }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user