Commit Graph

1831 Commits

Author SHA1 Message Date
Taus
b027ac3658 Merge pull request #21809 from github/tausbn/yeast-add-support-for-desugaring-phases
Yeast: Two small improvements
2026-05-07 19:00:44 +02:00
Paolo Tranquilli
f9e42ac443 Merge pull request #21794 from github/post-release-prep/codeql-cli-2.25.4
Post-release preparation for codeql-cli-2.25.4
2026-05-07 14:43:24 +02:00
copilot-swe-agent[bot]
e0d663f79b yeast: address review wording in phase docs
Agent-Logs-Url: https://github.com/github/codeql/sessions/6d23db05-a6e9-4de4-8951-b465980fd0ef

Co-authored-by: tausbn <1104778+tausbn@users.noreply.github.com>
2026-05-07 12:35:46 +00:00
Taus
957c89b478 yeast: Support multi-phase desugaring via DesugaringConfig::add_phase
Extend the desugaring config from a single flat list of rules to an
ordered sequence of named Phases. Each phase runs to completion (a
full traversal applying its rules) before the next phase starts.
Rules in different phases never compete for matches.

The config is built via the new chainable API:

    DesugaringConfig::new()
        .add_phase("cleanup", cleanup_rules)
        .add_phase("desugar", desugar_rules)
        .with_output_node_types_yaml(yaml);

Single-phase configs are just .add_phase(...) called once.

A single FreshScope is shared across phases so generated identifier
names (e.g. $tmp-N) are unique throughout the run.

Phase names appear in error messages, e.g. "Phase `desugar`:
exceeded maximum rewrite depth".

Add two regression tests: one verifying basic two-phase chained
desugaring, and one verifying that errors include the failing phase
name.
2026-05-06 21:17:31 +00:00
Taus
9a94836974 yeast: Add per-rule .repeated() flag to opt into iterative matching
Previously, after a rule fired the engine would always re-try that
same rule on the result root. A rule whose output matched its own
query (intentionally or by accident) would loop until the global
MAX_REWRITE_DEPTH safety net kicked in.

Make the default behavior fire-once-per-node: after a rule fires on
node N, the engine no longer tries that same rule on the result root.
Other rules and child traversal are unaffected. Rules that
intentionally rewrite iteratively can opt into the old behavior via
the new Rule::repeated() builder method.

Add two regression tests using a self-swapping assignment rule:
- with .repeated(), the swap loops and trips the depth limit
- without it (default), the swap fires once and terminates
2026-05-06 12:33:18 +00:00
Taus
a0a0e9e9a7 yeast: Add test for chained rules with output-only kinds
Adds a regression test verifying that desugaring rules can chain across
output-only node kinds: a first rule rewrites an input kind to an
output-only kind, and a second rule then rewrites that output-only
kind into another output-only kind. This exercises the schema lookup
for query patterns whose root kind is not present in the input
tree-sitter grammar.
2026-05-06 11:45:53 +00:00
Taus
60dcf88b50 yeast: Add Bazel build rules for yeast crates
Add BUILD.bazel files for the yeast and yeast-macros crates, register
them as dependencies of the shared tree-sitter extractor, and refresh
the vendored crate dependencies via update_tree_sitter_extractors_deps.sh.
2026-05-06 11:34:09 +00:00
Taus
82bbdee832 yeast: Support separate output node types in extractor generator
Language and LanguageSpec gain optional output_node_types field.
When set, the generator produces dbscheme/QL from the output types
and the extractor validates TRAP against them.

All existing extractors pass None (no behavior change).
Ruby extract() calls gain vec![] for the new rules parameter.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-06 11:34:09 +00:00
Taus
9ad431dea1 yeast: Integrate yeast with shared tree-sitter extractor
extract() gains a rules parameter. When empty, uses tree-sitter native
traversal (no behavior change). When non-empty, runs yeast desugaring
and extracts via traverse_yeast.

Adds AstNode trait abstracting over tree_sitter::Node and yeast::Node,
with minimal changes to existing Visitor methods (Node -> &N in 6
signatures).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-06 11:34:09 +00:00
Taus
cc28ff9a48 yeast: Add yeast documentation
Covers architecture, query language, template language
(tree!/trees!/rule!),
capture semantics, fresh identifiers, and extractor integration.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-06 11:34:09 +00:00
Taus
6e580446fd yeast: Add yeast test suite
12 tests covering parsing, queries, tree building, desugaring rules,
cursor navigation, and the shorthand rule! syntax.

Tests use a custom output node-types.yml with named fields for all
children (parameter, stmt, index), loaded via
schema_from_yaml_with_language.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-06 11:34:09 +00:00
Taus
4c5548363c yeast: Add AST dumper for human-readable tree output
Produces indented text showing node kinds, named fields, and leaf
content. Unnamed tokens are hidden unless inside a named field.
Used by tests for readable assertions.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-06 11:34:09 +00:00
Taus
8a9e53cc58 yeast: Add YAML node-types format and converter
Human-friendly YAML alternative to tree-sitter node-types.json with
three sections: supertypes, named, unnamed. Supports bidirectional
conversion and building Schema objects from YAML.

Includes CLI binary (node_types_yaml) and documentation.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-06 11:34:09 +00:00
Taus
04f587190e yeast: AST desugaring framework with proc-macro DSL
YEAST (YEAST Elaborates Abstract Syntax Trees) is a framework for
transforming tree-sitter parse trees before CodeQL extraction.

Core components:
- shared/yeast/ — Ast, Node, Schema, query matching engine, captures,
  FreshScope, BuildCtx
- shared/yeast-macros/ — proc macros: query!, tree!, trees!, rule!

The query language is inspired by tree-sitter queries:
  (assignment left: (_) @lhs right: (_) @rhs)

Templates support embedded Rust ({expr}), splicing ({..expr}),
computed literals (#{expr}), and fresh identifiers ($name).

The rule! macro combines query and transform:
  rule!((for pattern: (_) @pat ...) => (call receiver: {val} ...))

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-06 11:34:09 +00:00
Tom Hvitved
00fb11b028 Merge pull request #21778 from hvitved/rust/type-inference-verbose-type-path-expectations
Rust: Use verbose type paths in inline expectation comments
2026-05-05 20:23:25 +02:00
github-actions[bot]
7610277199 Post-release preparation for codeql-cli-2.25.4 2026-05-05 10:10:06 +00:00
github-actions[bot]
88e1d86c27 Release preparation for version 2.25.4 2026-05-05 09:34:30 +00:00
Tom Hvitved
4c1461ad5b Merge pull request #21786 from hvitved/inline-test-ignore-tags
Inline test expectations: Rename `tagIsOptional` to `tagIsIgnored`
2026-05-05 09:01:58 +02:00
Tom Hvitved
80ccdcc696 Inline test expectations: Rename tagIsOptional to tagIsIgnored 2026-05-04 11:21:33 +02:00
Anders Schack-Mulligen
e0421dbf53 C#: Reinstate toString for SSA data flow nodes. 2026-04-30 13:56:16 +02:00
Tom Hvitved
e1cd708c75 Rust: Use verbose type paths in inline expectation comments 2026-04-30 13:54:09 +02:00
Tom Hvitved
e14b654e8a Update shared/controlflow/codeql/controlflow/ControlFlowGraph.qll
Co-authored-by: Anders Schack-Mulligen <aschackmull@users.noreply.github.com>
2026-04-29 14:57:35 +02:00
Tom Hvitved
cbe207ab65 C#: Include parameters and their defaults in the CFG 2026-04-29 14:01:09 +02:00
Tom Hvitved
cbc12324bb Merge pull request #21703 from hvitved/rust/type-inference-sibling
Rust: Refine `implSiblings`
2026-04-24 12:36:51 +02:00
Tom Hvitved
c64223ae56 Merge pull request #21748 from hvitved/shared/remove-deprecated
Shared: Remove deprecated code
2026-04-23 14:44:17 +02:00
Tom Hvitved
90ae086822 Shared: Remove deprecated code 2026-04-23 11:24:14 +02:00
Tom Hvitved
1a84b2b555 CFG: Use dense ranking 2026-04-23 11:22:38 +02:00
Tom Hvitved
71fa2166ee Apply suggestions from code review
Co-authored-by: Anders Schack-Mulligen <aschackmull@users.noreply.github.com>
2026-04-22 17:06:31 +02:00
Tom Hvitved
39cd86a48e C#: Move handling of callables into shared control flow library 2026-04-22 14:11:57 +02:00
Tom Hvitved
e60275c4de Rust: Refine implSiblings
Consider two implementations of the same trait to be siblings when the
type being implemented by one is an instantiation of the type being
implemented by the other.
2026-04-22 13:32:56 +02:00
Anders Schack-Mulligen
f912731cd4 Merge pull request #21565 from aschackmull/csharp/cfg2
C#: Replace CFG with the shared implementation
2026-04-21 15:50:38 +02:00
Anders Schack-Mulligen
67c0515d3c Cfg: Undo consistency check change. 2026-04-21 13:10:03 +02:00
Anders Schack-Mulligen
9de02b7ae6 Cfg: Use consistent casing in additional node tags. 2026-04-21 10:56:10 +02:00
Anders Schack-Mulligen
e928c224ae C#/Cfg: Some simple review fixes. 2026-04-20 14:43:27 +02:00
github-actions[bot]
a0bab539bb Post-release preparation for codeql-cli-2.25.3 2026-04-20 12:40:34 +00:00
github-actions[bot]
c861d99802 Release preparation for version 2.25.3 2026-04-20 09:27:23 +00:00
Henry Mercer
43c9b95e6f Merge branch 'main' into post-release-prep/codeql-cli-2.25.2 2026-04-14 13:56:52 +01:00
Tom Hvitved
b749ad645a Merge pull request #21706 from hvitved/rust/type-inference-perf-fixes
Rust: Improve performance of two type inference predicates
2026-04-14 13:06:26 +02:00
Owen Mansel-Chan
7458674470 Merge pull request #21584 from owen-mc/shared/update-mad-comments
Shared: update code comments explaining models-as-data format to include barriers and barrier guards
2026-04-14 09:30:28 +01:00
Tom Hvitved
0db62b2e68 Type inference: Fix bad join
Before
```
Pipeline standard for TypeInference::M2::SatisfiesConstraintWithTypeMatching<TypeInference::FunctionCallMatching::AccessConstraint::RelevantAccess,TypeMention::TypeMention,TypeInference::FunctionCallMatching::AccessConstraint::SatisfiesTypeParameterConstraintInput>::TermIsInstantiationOfCondition::typeParametersHaveEqualInstantiationToIndex/4#dde26112@d5eb7x9q was evaluated in 471 iterations totaling 24306ms (delta sizes total: 42097188).
        5676156578   ~1%    {7} r1 = JOIN `TypeInference::M2::SatisfiesConstraintWithTypeMatching<TypeInference::FunctionCallMatching::AccessConstraint::RelevantAccess,TypeMention::TypeMention,TypeInference::FunctionCallMatching::AccessConstraint::SatisfiesTypeParameterConstraintInput>::TermIsInstantiationOfCondition::typeParametersHaveEqualInstantiationToIndex/4#dde26112#prev_delta` WITH `TypeInference::M2::SatisfiesConstraintWithTypeMatching<TypeInference::FunctionCallMatching::AccessConstraint::RelevantAccess,TypeMention::TypeMention,TypeInference::FunctionCallMatching::AccessConstraint::SatisfiesTypeParameterConstraintInput>::TermIsInstantiationOfCondition::typeParametersEqual/4#a276e5d4#prev` ON FIRST 3 OUTPUT Lhs.0, Lhs.1, Lhs.2, Rhs.3, _, Lhs.3, _
                            {5}    | REWRITE WITH Tmp.4 := 1, Out.4 := (Tmp.4 + In.5), Tmp.6 := 0, TEST Out.4 != Tmp.6 KEEPING 5
        5676156578   ~1%    {5}    | SCAN OUTPUT In.1, In.4, In.3, In.0, In.2
          41691564   ~1%    {4}    | JOIN WITH `TypeInference::M2::SatisfiesConstraintWithTypeMatching<TypeInference::AssocFunctionResolution::ArgSatisfiesBlanketLikeConstraint::ArgumentTypeAndBlanketOffset,TypeMention::TypeMention,TypeInference::AssocFunctionResolution::ArgSatisfiesBlanketLikeConstraint::SatisfiesBlanketConstraint::Inp>::TermIsInstantiationOfCondition::getNthTypeParameter/2#40c66343` ON FIRST 3 OUTPUT Lhs.3, Lhs.0, Lhs.4, Lhs.1

          42097188   ~2%    {4} r2 = SCAN `TypeInference::M2::SatisfiesConstraintWithTypeMatching<TypeInference::FunctionCallMatching::AccessConstraint::RelevantAccess,TypeMention::TypeMention,TypeInference::FunctionCallMatching::AccessConstraint::SatisfiesTypeParameterConstraintInput>::TermIsInstantiationOfCondition::typeParametersEqual/4#a276e5d4#prev_delta` OUTPUT In.1, In.3, In.0, In.2

          42097188   ~1%    {5} r3 = JOIN r2 WITH `TypeInference::M2::SatisfiesConstraintWithTypeMatching<TypeInference::AssocFunctionResolution::ArgSatisfiesBlanketLikeConstraint::ArgumentTypeAndBlanketOffset,TypeMention::TypeMention,TypeInference::AssocFunctionResolution::ArgSatisfiesBlanketLikeConstraint::SatisfiesBlanketConstraint::Inp>::TermIsInstantiationOfCondition::getNthTypeParameter/2#40c66343_021#join_rhs` ON FIRST 2 OUTPUT Lhs.2, Lhs.0, Lhs.3, Rhs.2, _
                            {4}    | REWRITE WITH Tmp.4 := 0, TEST InOut.3 != Tmp.4 KEEPING 4
          41691564   ~1%    {5}    | SCAN OUTPUT In.0, In.1, In.2, _, In.3
          41691564   ~1%    {5}    | REWRITE WITH Tmp.3 := 1, Out.3 := (InOut.4 - Tmp.3)
                 0   ~0%    {4}    | JOIN WITH `TypeInference::M2::SatisfiesConstraintWithTypeMatching<TypeInference::FunctionCallMatching::AccessConstraint::RelevantAccess,TypeMention::TypeMention,TypeInference::FunctionCallMatching::AccessConstraint::SatisfiesTypeParameterConstraintInput>::TermIsInstantiationOfCondition::typeParametersHaveEqualInstantiationToIndex/4#dde26112#prev` ON FIRST 4 OUTPUT Lhs.0, Lhs.1, Lhs.2, Lhs.4

          42097188   ~0%    {6} r4 = JOIN r2 WITH `TypeInference::M2::SatisfiesConstraintWithTypeMatching<TypeInference::AssocFunctionResolution::ArgSatisfiesBlanketLikeConstraint::ArgumentTypeAndBlanketOffset,TypeMention::TypeMention,TypeInference::AssocFunctionResolution::ArgSatisfiesBlanketLikeConstraint::SatisfiesBlanketConstraint::Inp>::TermIsInstantiationOfCondition::getNthTypeParameter/2#40c66343_021#join_rhs` ON FIRST 2 OUTPUT Lhs.2, Lhs.0, Lhs.3, Lhs.1, Rhs.2, _
                            {5}    | REWRITE WITH Tmp.5 := 0, TEST InOut.4 = Tmp.5 KEEPING 5
            405624   ~1%    {5}    | SCAN OUTPUT In.1, _, In.3, In.0, In.2
            405624   ~1%    {5}    | REWRITE WITH Out.1 := 0
            405624   ~0%    {4}    | JOIN WITH `TypeInference::M2::SatisfiesConstraintWithTypeMatching<TypeInference::AssocFunctionResolution::ArgSatisfiesBlanketLikeConstraint::ArgumentTypeAndBlanketOffset,TypeMention::TypeMention,TypeInference::AssocFunctionResolution::ArgSatisfiesBlanketLikeConstraint::SatisfiesBlanketConstraint::Inp>::TermIsInstantiationOfCondition::getNthTypeParameter/2#40c66343` ON FIRST 3 OUTPUT Lhs.3, Lhs.0, Lhs.4, _
            405624   ~1%    {4}    | REWRITE WITH Out.3 := 0

          42097188   ~1%    {4} r5 = r1 UNION r3 UNION r4
          42097188   ~1%    {4}    | AND NOT `TypeInference::M2::SatisfiesConstraintWithTypeMatching<TypeInference::FunctionCallMatching::AccessConstraint::RelevantAccess,TypeMention::TypeMention,TypeInference::FunctionCallMatching::AccessConstraint::SatisfiesTypeParameterConstraintInput>::TermIsInstantiationOfCondition::typeParametersHaveEqualInstantiationToIndex/4#dde26112#prev`(FIRST 4)
                            return r5
```

After
```
Pipeline standard for TypeInference::M2::SatisfiesConstraintWithTypeMatching<TypeInference::FunctionCallMatching::AccessConstraint::RelevantAccess,TypeMention::TypeMention,TypeInference::FunctionCallMatching::AccessConstraint::SatisfiesTypeParameterConstraintInput>::TermIsInstantiationOfCondition::typeParametersHaveEqualInstantiationToIndex/4#dde26112@96df1x2u was evaluated in 471 iterations totaling 4058ms (delta sizes total: 42097188).
        42097188   ~0%    {4} r1 = SCAN `TypeInference::M2::SatisfiesConstraintWithTypeMatching<TypeInference::FunctionCallMatching::AccessConstraint::RelevantAccess,TypeMention::TypeMention,TypeInference::FunctionCallMatching::AccessConstraint::SatisfiesTypeParameterConstraintInput>::TermIsInstantiationOfCondition::typeParametersEqual/5#ddfcf430#prev_delta` OUTPUT In.3, In.0, In.1, In.2
          405624   ~0%    {4}    | JOIN WITH const_0 ON FIRST 1 OUTPUT Lhs.1, Lhs.2, Lhs.3, _
          405624   ~1%    {4}    | REWRITE WITH Out.3 := 0

        42097188   ~1%    {6} r2 = SCAN `TypeInference::M2::SatisfiesConstraintWithTypeMatching<TypeInference::FunctionCallMatching::AccessConstraint::RelevantAccess,TypeMention::TypeMention,TypeInference::FunctionCallMatching::AccessConstraint::SatisfiesTypeParameterConstraintInput>::TermIsInstantiationOfCondition::typeParametersHaveEqualInstantiationToIndex/4#dde26112#prev_delta` OUTPUT In.0, In.1, In.2, _, In.3, _
        42097188   ~1%    {4}    | REWRITE WITH Tmp.3 := 1, Out.3 := (Tmp.3 + In.4), Tmp.5 := 0, TEST Out.3 != Tmp.5 KEEPING 4
        41691564   ~1%    {4}    | JOIN WITH `TypeInference::M2::SatisfiesConstraintWithTypeMatching<TypeInference::FunctionCallMatching::AccessConstraint::RelevantAccess,TypeMention::TypeMention,TypeInference::FunctionCallMatching::AccessConstraint::SatisfiesTypeParameterConstraintInput>::TermIsInstantiationOfCondition::typeParametersEqual/5#ddfcf430#prev` ON FIRST 4 OUTPUT Lhs.0, Lhs.1, Lhs.2, Lhs.3

        42097188   ~1%    {6} r3 = SCAN `TypeInference::M2::SatisfiesConstraintWithTypeMatching<TypeInference::FunctionCallMatching::AccessConstraint::RelevantAccess,TypeMention::TypeMention,TypeInference::FunctionCallMatching::AccessConstraint::SatisfiesTypeParameterConstraintInput>::TermIsInstantiationOfCondition::typeParametersEqual/5#ddfcf430#prev_delta` OUTPUT In.0, In.1, In.2, In.3, In.4, _
                          {5}    | REWRITE WITH Tmp.5 := 0, TEST InOut.3 != Tmp.5 KEEPING 5
        41691564   ~1%    {5}    | SCAN OUTPUT In.0, In.1, In.2, _, In.3
        41691564   ~1%    {5}    | REWRITE WITH Tmp.3 := 1, Out.3 := (InOut.4 - Tmp.3)
               0   ~0%    {4}    | JOIN WITH `TypeInference::M2::SatisfiesConstraintWithTypeMatching<TypeInference::FunctionCallMatching::AccessConstraint::RelevantAccess,TypeMention::TypeMention,TypeInference::FunctionCallMatching::AccessConstraint::SatisfiesTypeParameterConstraintInput>::TermIsInstantiationOfCondition::typeParametersHaveEqualInstantiationToIndex/4#dde26112#prev` ON FIRST 4 OUTPUT Lhs.0, Lhs.1, Lhs.2, Lhs.4

        42097188   ~1%    {4} r4 = r1 UNION r2 UNION r3
        42097188   ~1%    {4}    | AND NOT `TypeInference::M2::SatisfiesConstraintWithTypeMatching<TypeInference::FunctionCallMatching::AccessConstraint::RelevantAccess,TypeMention::TypeMention,TypeInference::FunctionCallMatching::AccessConstraint::SatisfiesTypeParameterConstraintInput>::TermIsInstantiationOfCondition::typeParametersHaveEqualInstantiationToIndex/4#dde26112#prev`(FIRST 4)
                          return r4
```
2026-04-14 09:34:13 +02:00
Anders Schack-Mulligen
d5c9fd1085 C#/Cfg: A bit more qldoc. 2026-04-10 15:47:25 +02:00
Anders Schack-Mulligen
ff978d1a8c C#: Replace CFG. 2026-04-10 15:47:13 +02:00
Anders Schack-Mulligen
b85b02abb4 Cfg: Add dominance predicates to shared ControlFlowNode. 2026-04-10 15:47:10 +02:00
Anders Schack-Mulligen
88aaff863b Cfg: Extend consistency checks. 2026-04-10 15:47:09 +02:00
Anders Schack-Mulligen
6ffed8523c Cfg/Java: Move InstanceOfExpr CFG into shared lib. 2026-04-10 15:47:09 +02:00
Anders Schack-Mulligen
0b6c416fd4 Cfg: Support short-circuiting compound assignments. 2026-04-10 15:47:08 +02:00
Anders Schack-Mulligen
a53cffc121 Cfg: Support GotoStmt. 2026-04-10 15:47:07 +02:00
Anders Schack-Mulligen
93a594e9c0 Cfg: Support Throw expressions. 2026-04-10 15:47:07 +02:00
Tom Hvitved
33cc887be0 Merge pull request #21592 from hvitved/dataflow/source-call-context-type-flow
Data flow: Add hook for preventing lambda dispatch in source call contexts
2026-04-09 13:44:42 +02:00
Tom Hvitved
d704b753c8 Fix CP in typeFlowParamType
Forgot to link `p` with `c` using `nodeEnclosingCallable(p, c)`.
2026-04-09 09:19:55 +02:00