Skip to content

fix: handle multi-line function signatures in contract extraction#939

Merged
chubes4 merged 1 commit intomainfrom
fix/test-gen-multiline-sigs
Mar 23, 2026
Merged

fix: handle multi-line function signatures in contract extraction#939
chubes4 merged 1 commit intomainfrom
fix/test-gen-multiline-sigs

Conversation

@chubes4
Copy link
Member

@chubes4 chubes4 commented Mar 23, 2026

Summary

Fixes two extraction gaps that caused wrong test generation for functions with multi-line signatures (#818).

Problem

The contract extractor operated per-line:

  • Params: grammar regex only captured the first line → functions with 3+ params across lines got called with wrong argument count
  • Return type: detect_return_shape only read the fn line → return type on a continuation line was invisible (Unit instead of Result)
// This function's params and return type were lost:
pub fn complex_function(
    root: &Path,           // ← only this line was seen
    files: &[PathBuf],     // ← lost
    config: &Config,       // ← lost
) -> Result<(), Error> {   // ← return type lost too

Fix

  • join_declaration_lines() — concatenates raw lines from fn through { into a single string
  • extract_params_from_declaration() — re-parses the full param list with balanced-paren tracking (handles HashMap<String, Vec<u8>> correctly)
  • detect_return_shape now receives the joined declaration, so return types on continuation lines are found
  • is_async detection also uses the full declaration

Tests

9 unit tests covering:

  • Single-line signatures (unchanged behavior)
  • Multi-line params
  • Return type on next line
  • Nested generics in params
  • No params
  • Self receiver

Two extraction gaps that caused wrong test generation:

1. Multi-line params: when a function signature spans multiple lines,
   the grammar's per-line regex only captures the first line's params.
   Now join_declaration_lines() concatenates from fn through { to get
   the full text, and extract_params_from_declaration() re-parses the
   complete param list with balanced-paren tracking.

2. Multi-line return types: detect_return_shape() only read the fn line.
   When the return type is on a continuation line (common with long
   signatures), it saw Unit instead of Result/Option. Now it reads
   the full joined declaration.

Both fixes use the same join: raw_lines[fn_line..body_start].

9 unit tests added for join_declaration_lines and
extract_params_from_declaration.
@chubes4 chubes4 merged commit 5cfefc7 into main Mar 23, 2026
1 check passed
@chubes4 chubes4 deleted the fix/test-gen-multiline-sigs branch March 23, 2026 02:10
@homeboy-ci
Copy link
Contributor

homeboy-ci bot commented Mar 23, 2026

Homeboy Results — homeboy

Audit

Failure Digest

Audit Failure Digest

  • Alignment score: 0.921
  • Severity counts: info: 1, unknown: 3, warning: 1
  • Outliers in current run: 3
  • Parsed outlier entries: 3
  • Drift increased: yes
  • New findings since baseline: 2
    1. structural — File has 16 top-level items (threshold: 15) (structural::src/core/engine/contract_extract.rs::HighItemCount)
    2. test_coverage — Method 'extract_contracts_from_grammar' has no corresponding test (expected 'test_extract_contracts_from_grammar') (test_coverage::src/core/engine/contract_extract.rs::MissingTestMethod)
  • Top actionable findings:
    1. src/core/engine/contract_extract.rs — high_item_count — File has 16 top-level items (threshold: 15)
    2. src/core/engine/contract_extract.rs — missing_test_method — Method 'extract_contracts_from_grammar' has no corresponding test (expected 'test_extract_contracts_from_grammar')
    3. src/commands/docs.rs — outlier — (outlier)
    4. tests/commands/deploy_test.rs — outlier — (outlier)
    5. src/core/engine/undo/snapshot.rs — outlier — (outlier)
All parsed audit findings (5)
1. **src/core/engine/contract_extract.rs** — high_item_count — File has 16 top-level items (threshold: 15)
2. **src/core/engine/contract_extract.rs** — missing_test_method — Method 'extract_contracts_from_grammar' has no corresponding test (expected 'test_extract_contracts_from_grammar')
3. **src/commands/docs.rs** — outlier — (outlier)
4. **tests/commands/deploy_test.rs** — outlier — (outlier)
5. **src/core/engine/undo/snapshot.rs** — outlier — (outlier)
- Full audit log: https://github.com/Extra-Chill/homeboy/actions/runs/23418444285

Autofixability classification

  • Overall: auto_fixable
  • Autofix enabled: yes
  • Autofix attempted this run: no
  • Auto-fixable failed commands:
    • audit
  • Failed commands with available automated fixes:
    • audit

Machine-readable artifacts

  • homeboy-lint-summary.json
  • homeboy-test-failures.json
  • homeboy-audit-summary.json
  • homeboy-autofixability.json

⚡ Scope: changed files only

audit (changed files only)

Auto-refactor

ℹ️ Autofix enabled, but no fixable file changes were produced

Failure Digest

Autofixability classification

  • Overall: human_needed
  • Autofix enabled: yes
  • Autofix attempted this run: no
  • Human-needed failed commands:
    • refactor --from all

Machine-readable artifacts

  • homeboy-lint-summary.json
  • homeboy-test-failures.json
  • homeboy-audit-summary.json
  • homeboy-autofixability.json

⚡ Scope: changed files only

refactor --from all

Tooling versions
  • Homeboy CLI: homeboy 0.85.3+a28d0e8
  • Extension: rust from https://github.com/Extra-Chill/homeboy-extensions
  • Extension revision: unknown
  • Action: Extra-Chill/homeboy-action@v2

Homeboy Action v1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant