Skip to content

fix(resolution): inherit tsconfig baseUrl through extends - #3591

Open
DevChiniwala wants to merge 2 commits into
Graphify-Labs:v8from
DevChiniwala:fix/2200-tsconfig-baseurl-extends
Open

DevChiniwala wants to merge 2 commits into
Graphify-Labs:v8from
DevChiniwala:fix/2200-tsconfig-baseurl-extends

Conversation

@DevChiniwala

Copy link
Copy Markdown
Contributor

Summary

  • resolve baseUrl through local tsconfig/jsconfig extends chains
  • resolve each inherited baseUrl relative to the config that declares it
  • preserve child-over-parent precedence and guard circular/non-local chains
  • handle JSONC and compilerOptions: null safely
  • add regressions for inheritance, child override, JSONC, and null options

Fixes #2200

This is complementary to the existing ${configDir} work in #2355: this PR handles inherited baseUrl declarations, while #2355 handles token expansion in the config that is read.

Validation

  • python -m pytest tests/test_jsconfig_baseurl.py tests/test_js_import_resolution.py -q --tb=short — 87 passed
  • python -m ruff check graphify/extractors/resolution.py tests/test_jsconfig_baseurl.py — passed
  • graphify update . — completed on current v8; expected optional-parser warnings only

Compatibility

The existing nearest-config behavior remains unchanged when no inherited baseUrl is present. Non-local package extends and circular chains are ignored as before, and invalid optional config objects no longer raise during resolution.

Copilot AI lite review requested due to automatic review settings September 16, 2026 05:45

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@graphify-labs graphify-labs Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Graphify reviewed this change.

Worth a look — the grounded gate found no coupling regressions or blocking issues, but 1 advisory finding(s) below merit a look before merge.

Formal verification. No changes could be formally verified in this run.


Graphify review — findings

Resolves compilerOptions.baseUrl through a tsconfig's extends chain via the new _read_tsconfig_base_url, with each config's baseUrl taken relative to its own directory, later parents overriding earlier ones, and the child config winning over all parents. Hardens _read_tsconfig_aliases and the baseUrl reader against malformed configs by coercing non-dict compilerOptions/paths (including compilerOptions: null) to empty, so JSONC parents and broken options no longer abort resolution. Adds tests covering inherited baseUrl, child-over-parent override, and the malformed-config cases.

Worth a look

  • Absolute tsconfig extends can load baseUrl from outside the workspace — graphify/extractors/resolution.py:264 · Escalate · medium
    • agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review
Analysis details — impact, health, verification

Impact & health

Graphify review

Impact — 1991 functions depend on the 186 functions this change touches.

Health — this change adds coupling hotspots:

  • new: extract() — 640 callers, 45 callees
  • new: _rebuild_code() — 123 callers, 53 callees
  • new: _extract_generic() — 18 callers, 29 callees
  • new: extract_js() — 85 callers, 4 callees
  • new: extract_xaml() — 19 callers, 17 callees
  • new: _resolve_js_module_path() — 34 callers, 9 callees
  • new: dispatch_command() — 2 callers, 125 callees
  • new: extract_objc() — 27 callers, 9 callees
  • …and 36 more — each is listed as a finding

Verification — 1991 functions in the blast radius were not formally verified this run (proofs are advisory here).

Gate & verification

graphify gate

PASS — objectively clean (no health regressions, tests not run — proofs not run this pass (advisory)). Grounded, not self-assessed.

Advisory (not blocking):

  • verification_scope: 892 function(s) in the blast radius were not formally verified this run

Test selection

Test selection

35 of 283 test file(s) selected (12%) via static blast radius.

  • tests/test_astro_extraction.py — impact
  • tests/test_build.py — impact
  • tests/test_cjs_module_extension.py — impact
  • tests/test_cpp_nested_and_cli.py — impact
  • tests/test_dotnet.py — impact
  • tests/test_extract.py — impact
  • tests/test_forwarding_review_findings.py — impact
  • tests/test_import_extension_resolution.py — impact
  • tests/test_indirect_dispatch.py — impact
  • tests/test_indirect_dispatch_assign_return.py — impact
  • tests/test_indirect_dispatch_getattr.py — impact
  • tests/test_js_exported_scalar_bindings.py — impact
  • tests/test_jsconfig_baseurl.py — impact, changed-test
  • tests/test_languages.py — impact
  • tests/test_multilang.py — impact
  • tests/test_package_json_subpath_imports.py — impact
  • tests/test_pascal.py — impact
  • tests/test_pascal_resolution.py — impact
  • tests/test_phantom_external_import.py — impact
  • tests/test_python_import_resolution.py — impact
  • tests/test_python_parse_memoization.py — impact
  • tests/test_python_underscore_resolution.py — impact
  • tests/test_rationale.py — impact
  • tests/test_resolve_memoization.py — impact
  • tests/test_ruby_resolution.py — impact
  • tests/test_scala_self_type.py — impact
  • tests/test_source_key_memoization.py — impact
  • tests/test_src_layout_import_resolution.py — impact
  • tests/test_swift_computed_properties.py — impact
  • tests/test_trailing_newline_not_a_syntax_error.py — impact
  • tests/test_ts_new_expression_calls.py — impact
  • tests/test_typescript_module_extensions.py — impact
  • tests/test_unmapped_at_alias_resolution.py — impact
  • tests/test_vue_extraction.py — impact
  • tests/test_walk_python_tree_iterative.py — impact

Selection is safe under the controlled-regression assumption; always-run tests + a periodic full run are the backstops. Advisory — it never changes the check verdict.

Formal verification

Could not verify: Could not verify \_load\_tsconfig\_base\_url.

The verifier did not have enough to check \_load\_tsconfig\_base\_url, so it is saying so rather than guessing. No false assurance is the whole point.

Guarantee: No guarantee either way, this is an honest abstention, not a pass.

Note: Reason: no capturable inputs from the test suite; property tier: parameter `start_dir` is annotated `Path` — outside the synthesizable primitive/collection set

Could not verify: Could not verify \_read\_tsconfig\_aliases.

The verifier did not have enough to check \_read\_tsconfig\_aliases, so it is saying so rather than guessing. No false assurance is the whole point.

Guarantee: No guarantee either way, this is an honest abstention, not a pass.

Note: Reason: no capturable inputs from the test suite; property tier: parameter `tsconfig` is annotated `Path` — outside the synthesizable primitive/collection set

· 44 more finding(s) on lines outside this diff (see the check run).

@DevChiniwala

Copy link
Copy Markdown
Contributor Author

Addressed the absolute tsconfig extends advisory in 1160bb3. Config inheritance now ignores absolute/drive/UNC extends paths for both baseUrl and aliases, while preserving relative local extends; the regression test verifies an external config contributes neither setting. Verification: focused tests (17 passed), and GitHub CI passed on Python 3.10, 3.12, 3.13, 3.14, security-scan, and skillgen-check.

This branch has not been deployed

No deployments
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.

JS/TS resolution: honor baseUrl declared in an extended tsconfig, and add a JSONC config test

2 participants