Skip to content

Feat/fortran language support#1085

Open
IppearPeng wants to merge 2 commits into
colbymchenry:mainfrom
IppearPeng:feat/fortran-language-support
Open

Feat/fortran language support#1085
IppearPeng wants to merge 2 commits into
colbymchenry:mainfrom
IppearPeng:feat/fortran-language-support

Conversation

@IppearPeng

Copy link
Copy Markdown

Adds Fortran language support to CodeGraph — ported from a proven in-house implementation (developed on 0.9.x) and re-applied onto the current 1.1.6 resolution architecture, following the repo's own add-lang convention.

CodeGraph now indexes modern free-form (.f90 .f95 .f03 .f08 .f18) and legacy fixed-form (.f .for .f77 .ftn .fpp) Fortran:

  • Extraction — modules/programs, subroutines & functions (incl. CONTAINS-block procedures), derived types with their components, type-bound procedures (PROCEDURE/GENERIC, DEFERRED), generic interfaces, PARAMETER constants, and use
    imports. Emits contains, imports, extends, and calls edges.
  • Resolution semantics
    • CALL obj%method() is normalized (% → .) and resolved onto the receiver's declared CLASS(t)/TYPE(t) binding.
    • Case-insensitive name matching (subroutine foo ↔ CALL FOO()), via a lowercase fallback gated to Fortran — no behavior change for other languages.
    • Polymorphic dispatch through an abstract base is bridged to every extending type's override (fortran-override synthesizer, mirroring cpp-override).
    • Array indexing (a(i)) is no longer mistaken for a call to a variable.

How it was wired

Standard add-lang touch points: LANGUAGES (types.ts), grammar/extension/display-name maps + vendored-wasm branch (grammars.ts), the EXTRACTORS barrel, and a vendored tree-sitter-fortran.wasm (ABI 15). The extractor is visitNode-driven
because Fortran's AST is irregular relative to the declarative LanguageExtractor model. Resolution changes live in tree-sitter.ts, name-matcher.ts, resolution/index.ts, and callback-synthesizer.ts, all Fortran-gated.

Tests / validation

  • tests/extraction.test.ts — a Fortran Extraction block.
  • tests/integration/fortran-pipeline.test.ts — end-to-end resolution.
  • Full suite green (the one intermittent failure is the pre-existing mcp-daemon timing test, unrelated — passes in isolation).

Notes

  • No package.json version bump (releases go through the Actions workflow).
  • Out of scope (follow-up): the language-agnostic resolution-pipeline robustness fixes that shipped alongside this feature upstream — not required by Fortran, kept out to keep this PR focused.

loongio and others added 2 commits July 2, 2026 16:29
Wire the tree-sitter-fortran grammar (vendored ABI-15 wasm) and a
visitNode-driven extractor into the pipeline: modules/programs,
subroutines & functions (incl. CONTAINS-block procedures), derived
types with components and type-bound procedures, generic interfaces,
PARAMETER constants, and `use` imports — across modern free-form
(.f90/.f95/.f03/.f08/.f18) and legacy fixed-form (.f/.for/.f77/.ftn).

Fortran's AST is irregular relative to the declarative LanguageExtractor
model (definition nodes carry no name/body field), so every program-unit
and type construct is handled in the visitNode hook; the declarative type
lists stay empty so the core never re-dispatches a Fortran definition.

Wiring follows the project's add-lang convention: LANGUAGES (types.ts),
WASM_GRAMMAR_FILES / EXTENSION_MAP / display-name / vendored-wasm branch
(grammars.ts), and the EXTRACTORS barrel. Docs (README, site languages
table, CHANGELOG) updated.

Ported from the team's proven implementation, re-applied onto 1.1.6.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Make Fortran's call graph resolve correctly across files:

- extractCall normalizes `CALL obj%method()` to obj.method (chained
  receivers unwrap to the immediate component; this/self kept for typed
  resolution).
- name-matcher: case-insensitive lookup (Fortran declares `subroutine foo`,
  calls `CALL FOO()`) via a lowercase-index fallback gated to fortran;
  receiver-type inference rides the shared localReceiverTypePatterns table
  (colbymchenry#1108) with a CLASS(t)/TYPE(t) declaration pattern, so `eng%Integrate()`
  lands on that type's binding; non-callable kinds are filtered from `calls`
  refs so array indexing never resolves to a variable; TBP binding refs
  can't self-loop.
- resolution pre-filter consults the lowercase name set for case-insensitive
  languages so a case-mismatched ref isn't dropped before any matcher runs.
- callback-synthesizer: fortranOverrideEdges bridges base-type bindings to
  extending types' overrides (CHA), mirroring cpp-override — so polymorphic
  dispatch through an abstract base follows into every override.

Tests: Fortran extraction block in extraction.test.ts plus an end-to-end
fortran-pipeline integration test.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@IppearPeng IppearPeng force-pushed the feat/fortran-language-support branch from 4643a53 to ea9ecca Compare July 2, 2026 08:58
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.

2 participants