// generated by {{generator}} private import {{import_prefix}}.Synth private import {{import_prefix}}.Raw {{#imports}} import {{.}} {{/imports}} module Generated { {{#has_doc}} /** {{#ql_internal}} * INTERNAL: Do not use. {{/ql_internal}} {{#doc}} * {{.}} {{/doc}} */ {{/has_doc}} class {{name}} extends Synth::T{{name}}{{#bases}}, {{.}}{{/bases}} { {{#root}} /** * Gets the string representation of this element. */ string toString() { none() } // overridden by subclasses /** * Gets the name of a primary CodeQL class to which this element belongs. * * This is the most precise syntactic category to which they belong; for * example, `CallExpr` is a primary class, but `ApplyExpr` is not. * * There might be some corner cases when this returns multiple classes, or none. */ string getAPrimaryQlClass() { none() } // overridden by subclasses /** * Gets a comma-separated list of the names of the primary CodeQL classes to which this element belongs. */ final string getPrimaryQlClasses() { result = concat(this.getAPrimaryQlClass(), ",") } /** * Gets the most immediate element that should substitute this element in the explicit AST, if any. * Classes can override this to indicate this node should be in the "hidden" AST, mostly reserved * for conversions and syntactic sugar nodes like parentheses. */ {{name}} getResolveStep() { none() } // overridden by subclasses /** * Gets the element that should substitute this element in the explicit AST, applying `getResolveStep` * transitively. */ final {{name}} resolve() { not exists(this.getResolveStep()) and result = this or result = this.getResolveStep().resolve() } {{/root}} {{#final}} override string getAPrimaryQlClass() { result = "{{name}}" } {{/final}} {{#properties}} {{#type_is_hideable}} /** * {{>ql_property_doc}} * * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the * behavior of both the `Immediate` and non-`Immediate` versions. */ {{type}} get{{#is_unordered}}An{{/is_unordered}}Immediate{{singular}}({{#is_indexed}}int index{{/is_indexed}}) { {{^synth}} result = Synth::convert{{type}}FromRaw(Synth::convert{{name}}ToRaw(this){{^root}}.(Raw::{{name}}){{/root}}.{{getter}}({{#is_indexed}}index{{/is_indexed}})) {{/synth}} {{#synth}} none() {{/synth}} } /** * {{>ql_property_doc}} * {{#has_description}} {{#description}} * {{.}} {{/description}} {{/has_description}} */ final {{type}} {{getter}}({{#is_indexed}}int index{{/is_indexed}}) { exists({{type}} immediate | immediate = this.get{{#is_unordered}}An{{/is_unordered}}Immediate{{singular}}({{#is_indexed}}index{{/is_indexed}}) and {{#hideable}}if exists(this.getResolveStep()) then result = immediate else {{/hideable}}result = immediate.resolve()) } {{/type_is_hideable}} {{^type_is_hideable}} /** * {{>ql_property_doc}} * {{#has_description}} {{#description}} * {{.}} {{/description}} {{/has_description}} */ {{type}} {{getter}}({{#is_indexed}}int index{{/is_indexed}}) { {{^synth}} {{^is_predicate}}result = {{/is_predicate}}{{#type_is_class}}Synth::convert{{type}}FromRaw({{/type_is_class}}Synth::convert{{name}}ToRaw(this){{^root}}.(Raw::{{name}}){{/root}}.{{getter}}({{#is_indexed}}index{{/is_indexed}}){{#type_is_class}}){{/type_is_class}} {{/synth}} {{#synth}} none() {{/synth}} } {{/type_is_hideable}} {{#is_optional}} /** * Holds if `{{getter}}({{#is_repeated}}index{{/is_repeated}})` exists. */ final 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}}. */ final {{type}} {{indefinite_getter}}() { result = this.{{getter}}(_) } {{^is_optional}} /** * Gets the number of {{doc_plural}}. */ final int getNumberOf{{plural}}() { result = count(int i | exists(this.{{getter}}(i))) } {{/is_optional}} {{/is_indexed}} {{#is_unordered}} /** * Gets the number of {{doc_plural}}. */ final int getNumberOf{{plural}}() { result = count(this.{{getter}}()) } {{/is_unordered}} {{/properties}} } }