Skip to content

test(julia): cover macro signature guard branch#1150

Merged
carlos-alm merged 12 commits into
mainfrom
test/1137-julia-macro-signature-guard
May 19, 2026
Merged

test(julia): cover macro signature guard branch#1150
carlos-alm merged 12 commits into
mainfrom
test/1137-julia-macro-signature-guard

Conversation

@carlos-alm
Copy link
Copy Markdown
Contributor

Summary

  • Adds does not record macro signature as call test to tests/parsers/julia.test.ts, mirroring the existing function-signature guard test for the macro_definition grandparent branch.
  • Verified the test fails when the macro_definition branch is removed from handleCall in src/extractors/julia.ts, so it would catch a future tree-sitter-julia grammar regression on macros.

The test was prepared during PR #1130 review (commit 6ae097b on fix/1126-julia-wasm-extractor-bugs) but landed after the squash-merge, so it never reached this branch's history.

Closes #1137

Test plan

  • npx vitest run tests/parsers/julia.test.ts — all 16 tests pass.
  • Manually removed the macro_definition arm of the handleCall guard and confirmed the new test fails with expected [ 'mymac', 'println' ] to not include 'mymac', then restored.

carlos-alm and others added 6 commits May 14, 2026 22:03
…t fixes to WASM

The native Julia extractor was fixed in #1098 for three issues that were
already latent in the WASM extractor but not surfaced by the existing
fixtures. Per the dual-engine policy, port the fixes so both engines
produce identical results.

1. Parameterized struct names (`struct Vec{T} <: AbstractArray{T,1}`) no
   longer silently emit the raw type-head text as the definition name —
   `findBaseName` recurses through `binary_expression`,
   `parametrized_type_expression`, and related wrappers to locate the
   base identifier.

2. Qualified function defs / short-form methods inside a module no
   longer get double-prefixed: `function Base.show ... end` inside
   `module Foo` now records `Base.show` (not `Foo.Base.show`); same for
   short-form `Foo.bar(x, y) = x + y` inside `module Outer`.

3. `selected_import` with a qualified module (`import LinearAlgebra.BLAS: gemm`)
   now correctly records `LinearAlgebra.BLAS` as the import source and
   `gemm` as the imported name.

Also fixes a related latent bug: `findChild(node, 'call_expression')` on
a `function_definition` was matching the body's first call (e.g.
`println(...)`) instead of the signature, because the signature is
wrapped in a `signature` node. Added a `signatureCall` helper mirroring
the native code.

Closes #1111
…ype test (#1128)

- Remove type_parameter_list / type_argument_list from TYPE_HEAD_WRAPPERS
  in both WASM and native engines. Julia grammar uses curly_expression
  for {T} constructs, so these were dead code. Removing them prevents
  findBaseName from ever recursing into a type-parameter list and
  returning a type variable (e.g. T) instead of the struct name.
- Add WASM test for non-parameterized struct inheritance
  (struct Point <: AbstractPoint). The native engine already covers
  this case; the WASM side now has parity.
…lback (#1128)

- Strengthen the `import Base: show` test to assert the corrected
  source/names shape (was only checking that imports were emitted at
  all, so a regression to the broken pre-fix shape would have slipped
  through).
- Document the grammar assumption behind `signatureCall` /
  `signature_call` in both engines: the call_expression fallback exists
  only for defensive grammar-drift protection, not as a routine path —
  if it ever fires on a real definition, the function name will silently
  match the first body call_expression instead.
…1130)

* fix(julia): port abstract-def / macro-def / signature-call WASM bugs

The WASM Julia extractor diverged from the native Rust extractor in three
ways that no existing WASM fixture exercised:

- handleAbstractDef: `findChild(node, 'identifier')` only looks at direct
  children of `abstract_definition`, but tree-sitter-julia nests the
  identifier inside `type_head`. Result: no abstract type was ever
  recorded. Fall back to `findBaseName(typeHead)` like the native code.
- handleMacroDef: `findChild(node, 'identifier')` resolves to the body's
  first identifier rather than the macro name (e.g. `macro mymac(x) x end`
  recorded `@x` instead of `@mymac`). Unwrap via `signatureCall` to reach
  the call_expression name.
- handleCall: the guard `parent.type === 'function_definition'` never
  matched — the signature's call_expression is parented by `signature`,
  whose own parent is the function/macro definition. Result: every
  long-form `function greet(...) ... end` recorded `greet` as both a
  definition and a call. Match the native walk: skip when parent is
  `signature` and grandparent is `function_definition` or
  `macro_definition`.

Adds WASM tests mirroring the native cases: extracts_abstract_type,
extracts_parameterized_abstract_type_base_name, extracts_macro_def, and
does_not_record_function_signature_as_call.

Closes #1126

* fix(julia): align abstract-def name resolution with struct-def (#1130)
Mirrors the function-signature guard test for the `macro_definition`
grandparent branch in `handleCall`. Without this case, a future
tree-sitter-julia grammar change that breaks the macro branch would
slip through the WASM test suite.

A test was prepared during PR #1130 review but landed on the head
branch after the squash-merge, so it is missing from history.

Closes #1137
@claude
Copy link
Copy Markdown

claude Bot commented May 18, 2026

Claude finished @carlos-alm's task —— View job


PR Review: test(julia): cover macro signature guard branch

Todo List:

  • Read the changed test file to understand the additions
  • Examine the Julia extractor code to understand what's being tested
  • Apply 5-phase review criteria
  • Provide final assessment and rating

Root Cause Analysis

Problem Being Solved: This PR adds test coverage for the macro signature guard branch in the Julia extractor's handleCall function. The existing code at lines 382-385 in src/extractors/julia.ts has a guard that prevents macro definition signatures from being incorrectly recorded as function calls, but this specific branch was untested.

Why This Approach: The test mirrors the existing "does not record function signature as call" test (lines 143-153) but covers the macro_definition grandparent branch specifically. This ensures that macro signatures like macro mymac(x) don't get recorded as calls to mymac.

Risk Assessment: ✅ Low risk - This is a pure test addition that increases coverage of existing defensive logic.

Backlog Compliance

  • Zero-dep: ✅ No new dependencies added
  • Foundation-aligned: ✅ Improves test coverage of core parsing functionality
  • Problem-fit: 4 - Prevents incorrect call extraction that would mislead AI agents about dependencies
  • Breaking: No - Pure test addition
  • Tier: 1

Code Quality Assessment

Test Implementation (lines 155-165): ✅ Excellent

  • Follows the exact pattern of the existing function signature test
  • Clear test name and comprehensive comment explaining the purpose
  • Proper verification: asserts mymac is NOT in calls but println IS in calls
  • Realistic Julia macro syntax

Coverage Validation: ✅ Strong

  • PR description shows manual verification by removing the guard and confirming test failure
  • Test specifically targets the grand?.type === 'macro_definition' branch at line 384

Code Consistency: ✅ Perfect

  • Mirrors existing test pattern exactly
  • Uses same assertion style as other Julia parser tests
  • Maintains test suite organization and naming conventions

Guard Logic Analysis

The tested code (lines 382-385) correctly prevents this scenario:

macro mymac(x)
    println(x)
end

From incorrectly recording mymac as both a definition AND a call. The guard checks:

  1. node.parent?.type === 'signature' - Call is part of a signature
  2. grand?.type === 'macro_definition' - Grandparent is macro definition

This is critical for accurate dependency analysis - without this guard, macros would appear to call themselves, confusing the dependency graph.

Final Assessment

## Root Cause Analysis
**Problem Being Solved**: Test coverage gap for macro signature guard in Julia call extractor
**Why This Approach**: Mirrors existing function guard test pattern, validates defensive parsing logic
**Risk Assessment**: Low risk, pure test coverage improvement

## Backlog Compliance
- Zero-dep: ✅ - No new dependencies
- Foundation-aligned: ✅ - Improves core parsing accuracy
- Problem-fit: 4 - Prevents incorrect dependency extraction for AI agents
- Breaking: No - Test-only addition
- Tier: 1

## Critical Concerns
None - this is a well-implemented test addition with proper verification.

## Final Recommendation
- Rating: ⭐⭐⭐⭐☆ (4/5)
- Action: APPROVE
- Reasoning: Excellent test coverage addition with thorough manual verification, follows existing patterns perfectly, and addresses a real gap in macro handling test coverage.

Minor Note: The only reason this isn't 5/5 is that it's a straightforward test addition rather than solving a complex problem, but it's executed flawlessly.

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented May 18, 2026

Greptile Summary

This PR adds a single regression test to the Julia parser test suite that guards against macro signature names being incorrectly recorded as function calls. The test directly mirrors the existing does not record function signature as call test, targeting the macro_definition branch of the handleCall guard in src/extractors/julia.ts.

  • Adds does not record macro signature as call test, asserting mymac is absent from symbols.calls while println (a body call) is still present.
  • The test is self-contained, well-commented, and was verified to fail when the macro_definition arm of the guard is removed — confirming it provides real regression coverage.

Confidence Score: 5/5

Test-only addition with no production code changes; safe to merge.

The change is a single, focused test that matches the shape of existing tests in the suite, exercises a real guard in the extractor, and was confirmed to catch a real regression. No production code is touched.

No files require special attention.

Important Files Changed

Filename Overview
tests/parsers/julia.test.ts Adds a single test verifying that macro_definition signatures are not recorded as calls; mirrors the existing function-signature guard test and correctly exercises the guard at line 384 of src/extractors/julia.ts.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A["parseJulia(macro mymac(x)\n  println(x)\nend)"]
    B["tree-sitter-julia AST"]
    C["macro_definition node\n  └─ signature\n       └─ call_expression (mymac)"]
    D["handleCall(call_expression)"]
    E{"parent.type === 'signature'\nAND\ngrand.type === 'macro_definition'?"}
    F["return — skip recording\n✅ mymac NOT in calls"]
    G["body call_expression (println)"]
    H["handleCall(println)"]
    I["record call\n✅ println IN calls"]

    A --> B --> C
    C --> D --> E
    E -- yes --> F
    B --> G --> H --> I
Loading

Reviews (7): Last reviewed commit: "Merge branch 'main' into test/1137-julia..." | Re-trigger Greptile

Base automatically changed from fix/1111-julia-wasm-extractor-bugs to main May 18, 2026 01:46
@carlos-alm carlos-alm merged commit a029d43 into main May 19, 2026
21 checks passed
@carlos-alm carlos-alm deleted the test/1137-julia-macro-signature-guard branch May 19, 2026 05:43
@github-actions github-actions Bot locked and limited conversation to collaborators May 19, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

follow-up: add WASM julia regression test for macro signature guard

1 participant