mirror of
https://github.com/affaan-m/ECC.git
synced 2026-10-26 18:35:05 +00:00
fix(carriers): close the object-literal, spread and extra-argument false negatives
- Record whether each `{` opens a block or an object literal from the
token before it; only a block's `}` lets a regex follow, so `{} / 2`
divides again while `if (ok) {} /re/` stays a regex.
- Match regex-preceding keywords only when no member dot precedes them,
so `a.of / 2` divides.
- Exempt the last dot of a spread from the member-call guard, so
`...require('./x')` is a module load.
- Resolve a call's first argument up to its first top-level comma, so
`require('./x', null)` and `import('./x.json', { with })` name `./x`.
`import(path.join(__dirname, ...))`, previously skipped silently, now
warns as dynamic.
Rescanning all 802 repository JavaScript files against the previous head
changes no result. The real registry is unchanged: 35/35 resolved, zero
failures or warnings. The design doc records the fix and states the gate's
scope: static relative specifiers in planned JavaScript only.
This commit is contained in:
2 files changed
+67
-25
No files matched your search
@@ -102,3 +102,7 @@ Third review follow-up. Review of that head found four more problems, each repro
|
||||
Two first-round findings had stayed open and still reproduced. A member call such as `records.require('./label')` matched the call pattern, because the dot satisfies a word boundary, so a self-contained object method failed every projection. And the dynamic-argument pattern allowed only one level of nested parentheses, so `require(path.join(__dirname, getName()))` produced no warning while `require(getName())` did. A seventh RED added 3 cases, all failing. GREEN skips calls preceded by a dot, including after whitespace or optional chaining, and finds each call's argument by balanced-paren scanning over the string-free skeleton. Rescanning the 802 files changed 6 results, each a newly reported nested dynamic argument in a docker eval check or a test, none of them in a carrier. The real registry is unchanged.
|
||||
|
||||
Focused verification: 22 carrier cases, 12 compiler cases, 57 closure cases, 3 CI cases and 2 publish-surface cases pass with zero failures or skips. ESLint passes on the validator and the new test. The validator is CI-only and stays out of the packed surface, matching `scripts/ci/validate-context-profiles.js`.
|
||||
|
||||
Fourth review follow-up. Three open review findings still let a carrier with a missing dependency pass the gate, each reproduced against the real registry first. Treating every `}` as a statement boundary, the third follow-up's fix, also caught object literals, so in `const ratio = {} / 2; require('../x')` the division was read as a regex that swallowed the `require`; a member named `of` (`a.of / 2`) did the same through the keyword list. The member-call guard treated the last dot of a spread as member access, so `[...require('../x')]` was skipped. And a literal first argument counted only when the call closed right after it, so `require('../x', null)` was demoted to a dynamic warning, which never fails. An eighth RED added 14 cases, 11 failing; the three controls (regex after a function body, a class body and a nested block) already passed. GREEN records whether each `{` opens a block or an object literal from the token before it, and only a block's `}` lets a regex follow. It matches keywords only when no member dot precedes them, ignores the dot of a spread, and resolves a call's first argument up to its first top-level comma, so `import('./data.json', { with: { type: 'json' } })` is an exact-path import, not a dynamic warning. As a side effect, `import(path.join(__dirname, …))`, which used to be skipped silently, now warns as dynamic, because `import()` takes a URL, not a path. Rescanning all 802 repository JavaScript files against the previous head changed no result. The real registry is unchanged: 35/35 resolved, zero failures or warnings. 71 closure cases pass.
|
||||
|
||||
Scope. The gate checks static, relative module specifiers in planned JavaScript files, and nothing else. It does not see `require.resolve`, an aliased or `createRequire`-made `require`, files a script spawns or reads at run time, or `.sh` and `.py` scripts. It does not model `.node` addons or a directory's `package.json` `main`. Each of those can still ship a carrier that fails at load time.
|
||||
Reference in new issue
Block a user