Give DataFlowCallable a user-facing name (Callable), move to Scopes.qll

I removed asFunctionNode() because it would need an import, but it
doesn't seem to be used anywhere.
This commit is contained in:
Owen Mansel-Chan
2021-12-06 14:00:18 -05:00
parent a6532b988f
commit a01f90b903
3 changed files with 56 additions and 64 deletions

View File

@@ -591,6 +591,54 @@ class BuiltinFunction extends Function, BuiltinEntity, @builtinfunctionobject {
predicate isPure() { not this.mayHaveSideEffects() }
}
private newtype TCallable =
TFunctionCallable(Function f) or
TFuncLitCallable(FuncLit l)
/**
* This is either a `Function` or a `FuncLit`, because of limitations of both
* `Function` and `FuncDef`:
* - `Function` is an entity, and therefore does not include function literals, and
* - `FuncDef` is an AST node, and so is not extracted for functions from external libraries.
*/
class Callable extends TCallable {
/** Gets a textual representation of this callable. */
string toString() { result = [this.asFunction().toString(), this.asFuncLit().toString()] }
/** Gets this callable as a function, if it is one. */
Function asFunction() { this = TFunctionCallable(result) }
/** Gets this callable as a function literal, if it is one. */
FuncLit asFuncLit() { this = TFuncLitCallable(result) }
/** Gets this function's definition, if it exists. */
FuncDef getFuncDef() { result = [this.asFuncLit().(FuncDef), this.asFunction().getFuncDecl()] }
/** Gets the type of this callable. */
SignatureType getType() {
result = this.asFunction().getType() or
result = this.asFuncLit().getType()
}
/** Gets the name of this callable. */
string getName() {
result = this.asFunction().getName() or
result = this.asFuncLit().getName()
}
/**
* Holds if this element is at the specified location.
* The location spans column `sc` of line `sl` to
* column `ec` of line `el` in file `fp`.
* For more information, see
* [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
*/
predicate hasLocationInfo(string fp, int sl, int sc, int el, int ec) {
this.asFunction().hasLocationInfo(fp, sl, sc, el, ec) or
this.asFuncLit().hasLocationInfo(fp, sl, sc, el, ec)
}
}
/** A statement label. */
class Label extends Entity, @labelobject { }

View File

@@ -104,7 +104,7 @@ module Public {
ControlFlow::Root getRoot() { none() } // overridden in subclasses
/** INTERNAL: Use `getRoot()` instead. */
DataFlowCallable getEnclosingCallable() {
Callable getEnclosingCallable() {
result.getFuncDef() = this.getRoot()
or
this = MkSummarizedParameterNode(result, _)
@@ -457,7 +457,7 @@ module Public {
* For virtual calls, we look up possible targets in all types that implement the receiver
* interface type.
*/
DataFlowCallable getACalleeIncludingExternals() {
Callable getACalleeIncludingExternals() {
result.asFunction() = this.getTarget()
or
exists(DataFlow::Node calleeSource | calleeSource = this.getACalleeSource() |
@@ -558,7 +558,7 @@ module Public {
/** A representation of a parameter initialization. */
abstract class ParameterNode extends DataFlow::Node {
/** Holds if this node initializes the `i`th parameter of `fd`. */
abstract predicate isParameterOf(DataFlowCallable c, int i);
abstract predicate isParameterOf(Callable c, int i);
}
/**
@@ -566,7 +566,7 @@ module Public {
* already have a parameter nodes.
*/
class SummarizedParameterNode extends ParameterNode, MkSummarizedParameterNode {
DataFlowCallable c;
Callable c;
int i;
SummarizedParameterNode() { this = MkSummarizedParameterNode(c, i) }
@@ -582,7 +582,7 @@ module Public {
i = -1 and result = c.asFunction().(Method).getReceiverType()
}
override predicate isParameterOf(DataFlowCallable call, int idx) { c = call and i = idx }
override predicate isParameterOf(Callable call, int idx) { c = call and i = idx }
override string toString() { result = "parameter " + i + " of " + c.toString() }
@@ -601,9 +601,7 @@ module Public {
/** Gets the parameter this node initializes. */
override Parameter asParameter() { result = parm }
override predicate isParameterOf(DataFlowCallable c, int i) {
parm.isParameterOf(c.getFuncDef(), i)
}
override predicate isParameterOf(Callable c, int i) { parm.isParameterOf(c.getFuncDef(), i) }
}
/** A representation of a receiver initialization. */

View File

@@ -191,68 +191,14 @@ class CastNode extends ExprNode {
override ConversionExpr expr;
}
private newtype TCallable =
TFunctionCallable(Function f) or
TFuncLitCallable(FuncLit l)
/**
* A data-flow callable.
*
* This is either a `Function` or a `FuncLit`, because of limitations of both
* `Function` and `FuncDef`:
* - `Function` is an entity, and therefore does not include function literals, and
* - `FuncDef` is an AST node, and so is not extracted for functions from external libraries.
*/
class DataFlowCallable extends TCallable {
/** Gets a textual representation of this callable. */
string toString() { result = [this.asFunction().toString(), this.asFuncLit().toString()] }
FunctionNode asFunctionNode() {
this.asFunction() = result.getFunction()
or
this.asFuncLit() = result.asExpr()
}
/** Gets this callable as a function, if it is one. */
Function asFunction() { this = TFunctionCallable(result) }
/** Gets this callable as a function literal, if it is one. */
FuncLit asFuncLit() { this = TFuncLitCallable(result) }
/** Gets this function's definition, if it exists. */
FuncDef getFuncDef() { result = [this.asFuncLit().(FuncDef), this.asFunction().getFuncDecl()] }
/** Gets the type of this callable. */
SignatureType getType() {
result = this.asFunction().getType() or
result = this.asFuncLit().getType()
}
/** Gets the name of this callable. */
string getName() {
result = this.asFunction().getName() or
result = this.asFuncLit().getName()
}
/**
* Holds if this element is at the specified location.
* The location spans column `sc` of line `sl` to
* column `ec` of line `el` in file `fp`.
* For more information, see
* [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
*/
predicate hasLocationInfo(string fp, int sl, int sc, int el, int ec) {
this.asFunction().hasLocationInfo(fp, sl, sc, el, ec) or
this.asFuncLit().hasLocationInfo(fp, sl, sc, el, ec)
}
}
class DataFlowExpr = Expr;
class DataFlowType = Type;
class DataFlowLocation = Location;
class DataFlowCallable = Callable;
/** A function call relevant for data flow. */
class DataFlowCall extends Expr {
DataFlow::CallNode call;