mirror of
https://github.com/github/codeql.git
synced 2025-12-16 16:53:25 +01:00
199 lines
5.3 KiB
Plaintext
199 lines
5.3 KiB
Plaintext
// generated by {{generator}}, do not edit
|
|
/**
|
|
* This module provides generated wrappers around the `CfgNode` type.
|
|
*
|
|
* INTERNAL: Do not import directly.
|
|
*/
|
|
|
|
private import codeql.util.Location
|
|
private import codeql.util.Unit
|
|
private import {{include_file_import}}
|
|
|
|
/** Provides the input to `MakeCfgNodes` */
|
|
signature module InputSig<LocationSig Loc> {
|
|
class CfgNode {
|
|
AstNode getAstNode();
|
|
|
|
string toString();
|
|
|
|
Loc getLocation();
|
|
}
|
|
|
|
AstNode getDesugared(AstNode n);
|
|
}
|
|
|
|
/**
|
|
* Given a `CfgNode` implementation, provides the module `Nodes` that
|
|
* contains wrappers around `CfgNode` for relevant classes.
|
|
*/
|
|
module MakeCfgNodes<LocationSig Loc, InputSig<Loc> Input> {
|
|
private import Input
|
|
|
|
final private class AstNodeFinal = AstNode;
|
|
|
|
final private class CfgNodeFinal = CfgNode;
|
|
|
|
/**
|
|
* INTERNAL: Do not expose.
|
|
*/
|
|
abstract class ParentAstNode extends AstNodeFinal {
|
|
/**
|
|
* Holds if `child` is a (possibly nested) child of this AST node
|
|
* for which we would like to find a matching CFG child.
|
|
*/
|
|
abstract predicate relevantChild(AstNode child);
|
|
}
|
|
|
|
/**
|
|
* INTERNAL: Do not expose.
|
|
*/
|
|
abstract class ChildMapping extends Unit {
|
|
/**
|
|
* Holds if `child` is a (possibly nested) child of AST node `parent`
|
|
* for which we would like to find a matching CFG child.
|
|
*/
|
|
final predicate relevantChild(AstNode parent, AstNode child) {
|
|
parent.(ParentAstNode).relevantChild(child)
|
|
}
|
|
|
|
/**
|
|
* Holds if there is a control flow path from `cfn` to `cfnChild`, where `cfn`
|
|
* is a control flow node for this AST node, and `cfnChild` is a control flow
|
|
* node for `child`.
|
|
*
|
|
* This predicate should be implemented at the place where `MakeCfgNodes` is
|
|
* invoked. Ideally, `MakeCfgNodes` should be a higher-order parameterized
|
|
* module, but since that is currently not supported, we achieve the "callback"
|
|
* effect using this `abstract` class instead.
|
|
*/
|
|
cached
|
|
abstract predicate hasCfgChild(AstNode parent, AstNode child, CfgNode cfn, CfgNode cfnChild);
|
|
}
|
|
|
|
/** Provides sub classes of `CfgNode`. */
|
|
module Nodes {
|
|
{{#classes}}
|
|
private final class Parent{{name}} extends ParentAstNode, {{name}} {
|
|
override predicate relevantChild(AstNode child) {
|
|
none()
|
|
{{#properties}}
|
|
{{#cfg}}
|
|
or
|
|
child = this.{{getter}}({{#is_indexed}}_{{/is_indexed}})
|
|
{{/cfg}}
|
|
{{/properties}}
|
|
}
|
|
}
|
|
|
|
/**
|
|
{{#doc}}
|
|
* {{.}}
|
|
{{/doc}}
|
|
*/
|
|
final class {{name}}CfgNode extends CfgNodeFinal{{#bases}}, {{.}}CfgNode{{/bases}} {
|
|
private {{name}} node;
|
|
|
|
{{name}}CfgNode() {
|
|
node = this.getAstNode()
|
|
}
|
|
|
|
/** Gets the underlying `{{name}}`. */
|
|
{{name}} get{{name}}() { result = node }
|
|
|
|
{{#properties}}
|
|
/**
|
|
* {{>ql_property_doc}} *
|
|
{{#description}}
|
|
* {{.}}
|
|
{{/description}}
|
|
{{#internal}}
|
|
* INTERNAL: Do not use.
|
|
{{/internal}}
|
|
*/
|
|
{{type}}{{#cfg}}CfgNode{{/cfg}} {{getter}}({{#is_indexed}}int index{{/is_indexed}}) {
|
|
{{#cfg}}
|
|
any(ChildMapping mapping).hasCfgChild(node, node.{{getter}}({{#is_indexed}}index{{/is_indexed}}), this, result)
|
|
{{/cfg}}
|
|
{{^cfg}}
|
|
{{^is_predicate}}result = {{/is_predicate}}node.{{getter}}({{#is_indexed}}index{{/is_indexed}})
|
|
{{/cfg}}
|
|
}
|
|
|
|
{{#is_optional}}
|
|
/**
|
|
* Holds if `{{getter}}({{#is_repeated}}index{{/is_repeated}})` exists.
|
|
{{#internal}}
|
|
* INTERNAL: Do not use.
|
|
{{/internal}}
|
|
*/
|
|
predicate has{{singular}}({{#is_repeated}}int index{{/is_repeated}}) {
|
|
exists(this.{{getter}}({{#is_repeated}}index{{/is_repeated}}))
|
|
}
|
|
{{/is_optional}}
|
|
{{#is_indexed}}
|
|
|
|
/**
|
|
* Gets any of the {{doc_plural}}.
|
|
{{#internal}}
|
|
* INTERNAL: Do not use.
|
|
{{/internal}}
|
|
*/
|
|
{{type}}{{#cfg}}CfgNode{{/cfg}} {{indefinite_getter}}() {
|
|
result = this.{{getter}}(_)
|
|
}
|
|
{{^is_optional}}
|
|
|
|
/**
|
|
* Gets the number of {{doc_plural}}.
|
|
{{#internal}}
|
|
* INTERNAL: Do not use.
|
|
{{/internal}}
|
|
*/
|
|
int getNumberOf{{plural}}() {
|
|
result = count(int i | exists(this.{{getter}}(i)))
|
|
}
|
|
{{/is_optional}}
|
|
{{/is_indexed}}
|
|
{{#is_unordered}}
|
|
/**
|
|
* Gets the number of {{doc_plural}}.
|
|
{{#internal}}
|
|
* INTERNAL: Do not use.
|
|
{{/internal}}
|
|
*/
|
|
int getNumberOf{{plural}}() {
|
|
result = count(this.{{getter}}())
|
|
}
|
|
{{/is_unordered}}
|
|
{{/properties}}
|
|
}
|
|
{{/classes}}
|
|
}
|
|
|
|
module Consistency {
|
|
private predicate hasCfgNode(AstNode astNode) {
|
|
astNode = any(CfgNode cfgNode).getAstNode()
|
|
}
|
|
|
|
query predicate missingCfgChild(CfgNode parent, string pred, int i, AstNode child) {
|
|
none()
|
|
{{#classes}}
|
|
{{#properties}}
|
|
{{#cfg}}
|
|
or
|
|
pred = "{{getter}}" and
|
|
parent = any(Nodes::{{name}}CfgNode cfgNode, {{name}} astNode |
|
|
astNode = cfgNode.get{{name}}() and
|
|
child = getDesugared(astNode.{{getter}}({{#is_indexed}}i{{/is_indexed}}))
|
|
{{^is_indexed}}and i = -1{{/is_indexed}} and
|
|
hasCfgNode(child) and
|
|
not child = cfgNode.{{getter}}({{#is_indexed}}i{{/is_indexed}}).getAstNode()
|
|
|
|
|
cfgNode
|
|
)
|
|
{{/cfg}}
|
|
{{/properties}}
|
|
{{/classes}}
|
|
}
|
|
}
|
|
} |