Repository navigation
fix(stryker-js-typescript-checker): resolve every exports array fallback target - #254
Merged
Merged
Conversation
…ack target An exports fallback array now yields every resolvable target in fallback order, so exportsCandidatesOf offers each in order and the first entry whose file exists wins. Escaping targets stay refused; a null entry and an inactive condition keep their existing terminal semantics. Verdict-Semantics: unchanged
…in an exports array A null in an exports fallback array ends the list, but the targets listed before it are still candidates. tsc 7.0.2 resolves ["./present.json", null] to present.json; the previous commit returned the subpath as excluded and dropped the base config. Two program-digest scenarios pin both array cases through the real checker runtime.
… any depth tsc 7.0.2 stops the whole fallback list at a null, even one inside a nested array: [["./missing.json", null], "./present.json"] extends nothing. The resolver ended only the inner list and returned present.json as a later candidate. A nested array that hits a null now reports its targets as terminated, and every enclosing array stops there. The property law now nests the null-terminated list up to three levels and fails on the previous head (shrunk to [["./.json", null], "./.json"]). The program-digest scenario for a trailing null passed on the base commit too, so it is removed; the real compiler rejects the nested-null shape with TS6053, so that case cannot be reached through a digest and stays with the law.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
When a tsconfig
extendsa package subpath whoseexportsvalue is an array, the checker took only the first entry that looked like a valid target and never checked that the file exists. With"./strict": ["./missing.json", "./strict-base.json"], tsc extendsstrict-base.json. Our resolver pickedmissing.json, found nothing there and dropped the base config, so editing the real base file didn't change the program digest.Change
resolvePackageExports(resolve-package-exports.workflow.ts) now returns every resolvable target of an array, in order (PackageExportsResolved.targets). The caller ints-compiler.handle.tsturns each one into a candidate path, and the existing "first file that exists" pick chooses among them.nullends the whole list at any depth, as it does in tsc. Targets listed before it stay candidates, and nothing after it is tried, even when the null sits inside a nested array. A leadingnullstill excludes the subpath../../…, invalid segments) are still skipped and never returned.Evidence
1. Same answer as
tsc --showConfig(7.0.2) on throwaway fixtures. Each fixture hasextends: "pkg/base", and onlypresent.jsonexists:exports["./base"]["./missing.json", "./present.json"]target: es2021)["./missing.json","./present.json"]["./present.json", "./missing.json"]["./present.json","./missing.json"]["./present.json", null]["./present.json"]["./missing.json", null, "./present.json"]compilerOptions: {})["./missing.json"][["./missing.json", null], "./present.json"]compilerOptions: {})["./missing.json"]2. Tests that fail without the fix.
∀entries_ArrayOfResolvableTargets_≡EveryTargetInFallbackOrderand the other array laws: with this branch's test file on main's source (9dde0b9), all 16 laws fail, because main has notargets.∀entries_NullTerminatedListAtAnyDepth_≡LeadingTargetsOnlynests the null-terminated list 0–3 levels deep. It fails on this branch's earlier head 782d20d (shrunk to[["./.json", null], "./.json"]) and passes at the current head.tests/program-digest.integration.test.ts) fails on main 9dde0b9, where the digest doesn't move, and passes here.3. Escaping paths are still refused.
∀entries_ArrayWithEscapingTargets_≡OnlyResolvableTargetsInOrderAndNeverEscapingmixes escaping and in-package targets and requires that no escaping target is ever returned.Package suite: 31 files pass. Lint, typecheck and format pass.
Review
ce-code-review, focused and report-only. The correctness peer checked about 70 exports shapes against tsc 7.0.2 and found one P1, a null inside a nested array; this branch fixes it. It also flagged one scenario that passed on the base commit too; that scenario is removed. One pre-existing P2 is not changed here: when the exports value is
[null], the checker still falls back to the old<pkg>/<subpath>.jsonlookup (ts-compiler.handle.ts:519-526), which tsc does not do.Need help on this PR? Tag
@codesmith-botwith what you need. Autofix is disabled.