fix(resolution): inherit tsconfig baseUrl through extends - #3591
DevChiniwala wants to merge 2 commits into
Conversation
There was a problem hiding this comment.
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— impacttests/test_build.py— impacttests/test_cjs_module_extension.py— impacttests/test_cpp_nested_and_cli.py— impacttests/test_dotnet.py— impacttests/test_extract.py— impacttests/test_forwarding_review_findings.py— impacttests/test_import_extension_resolution.py— impacttests/test_indirect_dispatch.py— impacttests/test_indirect_dispatch_assign_return.py— impacttests/test_indirect_dispatch_getattr.py— impacttests/test_js_exported_scalar_bindings.py— impacttests/test_jsconfig_baseurl.py— impact, changed-testtests/test_languages.py— impacttests/test_multilang.py— impacttests/test_package_json_subpath_imports.py— impacttests/test_pascal.py— impacttests/test_pascal_resolution.py— impacttests/test_phantom_external_import.py— impacttests/test_python_import_resolution.py— impacttests/test_python_parse_memoization.py— impacttests/test_python_underscore_resolution.py— impacttests/test_rationale.py— impacttests/test_resolve_memoization.py— impacttests/test_ruby_resolution.py— impacttests/test_scala_self_type.py— impacttests/test_source_key_memoization.py— impacttests/test_src_layout_import_resolution.py— impacttests/test_swift_computed_properties.py— impacttests/test_trailing_newline_not_a_syntax_error.py— impacttests/test_ts_new_expression_calls.py— impacttests/test_typescript_module_extensions.py— impacttests/test_unmapped_at_alias_resolution.py— impacttests/test_vue_extraction.py— impacttests/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).
|
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. |
Summary
baseUrlthrough local tsconfig/jsconfigextendschainsbaseUrlrelative to the config that declares itcompilerOptions: nullsafelyFixes #2200
This is complementary to the existing
${configDir}work in #2355: this PR handles inheritedbaseUrldeclarations, 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 passedpython -m ruff check graphify/extractors/resolution.py tests/test_jsconfig_baseurl.py— passedgraphify update .— completed on currentv8; expected optional-parser warnings onlyCompatibility
The existing nearest-config behavior remains unchanged when no inherited
baseUrlis present. Non-local package extends and circular chains are ignored as before, and invalid optional config objects no longer raise during resolution.