mirror of
https://github.com/abhigyanpatwari/GitNexus.git
synced 2026-09-09 22:33:39 +00:00
fix(zig): address tenth gitnexus-check review pass
- `normalizeZigDepPath`: normalize backslashes BEFORE the absolute-path check. A UNC dep (`\\server\share\dep`) used to slip past the check and normalize to the repo-relative `server/share/dep`; root-relative `\dep` had the same hole. Both now return null. Regression case added to the absolute-spellings test with the files those misreadings would resolve. - `bindPayloads`: a pointer capture `for (pages) |*p|` now records `*Page` (declaredSpelling) instead of `Page` — the `*` is an anonymous payload child before the identifier. Method dispatch is unchanged (`rawName` strips the sigil), but a deref projection `const q = p.*;` now sees the pointer layer. New fixture fn `viaPtrCaptureDeref` + assertion; fails on the previous code (verified by stashing the src fix). - `optional-grammar-gate.test.ts`: renamed the `typescript:tsx` case — the key IS a registry row; what makes it inert is the missing gate entry. Now also asserts a key no registry yields. - `structural-pair-coverage.test.ts`: header updated — ten tables (not eleven) are absent from every rule's target side; `Union` left the set when Zig made it linkable. - `language-classification.ts`: doc comment now names zig in the experimental set (added after Ring 1). Not re-fixed (invalid findings): - "owner-hook contract wired to an undeclared variable": stale-diff read — `findEnclosingClassInfo` declares `resolveFileTypeOwner` / `resolveContainerTypeOwner` as optional parameters (ast-helpers.ts:905, 917) and parse-worker threads them at every call site; tsc compiles clean. - "optional Zig grammar added unconditionally to the parsing fixture suite": the cited block only `fs.readFile`s the committed fixture file to assert it is non-empty — no parser or grammar load is involved.
This commit is contained in:
parent
ef391cc672
commit
c740d716be
8 changed files with 54 additions and 12 deletions
|
|
@ -12,6 +12,9 @@
|
|||
* - experimental: vue (embedded-language / SFC complexity),
|
||||
* cobol (regex-provider path)
|
||||
* - quarantined: (none)
|
||||
*
|
||||
* Added after Ring 1: zig enters as `experimental` (new language
|
||||
* integration; promotion to `production` is a separate governance PR).
|
||||
*/
|
||||
|
||||
import { SupportedLanguages } from '../languages.js';
|
||||
|
|
|
|||
|
|
@ -594,11 +594,14 @@ export async function loadZigBuildConfig(repoRoot: string): Promise<ZigBuildZonC
|
|||
* resolver so both sides agree on which deps are in-repo.
|
||||
*/
|
||||
export function normalizeZigDepPath(depPath: string): string | null {
|
||||
// POSIX (`/x`) and Windows (`C:\x`, `C:/x`) absolute paths both point
|
||||
// outside the repository.
|
||||
if (depPath.startsWith('/') || /^[A-Za-z]:[\\/]/.test(depPath)) return null;
|
||||
// Normalize separators BEFORE the absolute check so every Windows spelling
|
||||
// is visible to it: POSIX (`/x`), drive (`C:\x`, `C:/x`), root-relative
|
||||
// (`\x` → `/x`) and UNC (`\\server\share` → `//server/share`) paths all
|
||||
// point outside the repository.
|
||||
const normalized = depPath.replace(/\\/g, '/');
|
||||
if (normalized.startsWith('/') || /^[A-Za-z]:\//.test(normalized)) return null;
|
||||
const parts: string[] = [];
|
||||
for (const part of depPath.replace(/\\/g, '/').split('/')) {
|
||||
for (const part of normalized.split('/')) {
|
||||
if (part === '' || part === '.') continue;
|
||||
if (part === '..') {
|
||||
if (parts.length === 0) return null;
|
||||
|
|
|
|||
|
|
@ -134,8 +134,13 @@ function bindPayloads(node: SyntaxNode, resolver: ZigSubjectTypeResolver): void
|
|||
if (subject.type === 'range_expression') continue; // `0..` — an index
|
||||
const spelling = resolver.spellingOf(subject);
|
||||
if (spelling === undefined) continue;
|
||||
const element = isFor ? zigElementSpelling(spelling) : zigOptionalPayloadSpelling(spelling);
|
||||
if (element === undefined) continue;
|
||||
const projected = isFor ? zigElementSpelling(spelling) : zigOptionalPayloadSpelling(spelling);
|
||||
if (projected === undefined) continue;
|
||||
// `|*p|` captures a POINTER to the element/payload (the `*` is an
|
||||
// anonymous payload child right before the identifier). Keep the written
|
||||
// `*` so a later deref projection (`const q = p.*;`) still sees the
|
||||
// layer; `rawName` strips it again, so method dispatch is unchanged.
|
||||
const element = captured[i]!.previousSibling?.type === '*' ? `*${projected}` : projected;
|
||||
const rawName = normalizeZigTypeName(element);
|
||||
if (rawName.length === 0 || rawName.startsWith('@')) continue;
|
||||
const existing = host.typeBindings.get(name);
|
||||
|
|
|
|||
|
|
@ -95,6 +95,14 @@ fn viaDeref(ptr: *Page) void {
|
|||
const p = ptr.*;
|
||||
p.bump();
|
||||
}
|
||||
fn viaPtrCaptureDeref(pages: []Page) void {
|
||||
// `|*p|` captures a POINTER: the recorded type must keep the `*`
|
||||
// (`*Page`), or the deref projection below has no layer to remove.
|
||||
for (pages) |*p| {
|
||||
const q = p.*;
|
||||
q.bump();
|
||||
}
|
||||
}
|
||||
|
||||
// Guards: nothing typed here, no edge may appear.
|
||||
fn viaTypeConstructor() void {
|
||||
|
|
|
|||
|
|
@ -611,6 +611,9 @@ describe.skipIf(!zigAvailable)('Zig type aliases (zig-filestruct fixture, aliase
|
|||
expect(calls).toContain('viaIndex → bump');
|
||||
expect(calls).toContain('viaUnwrap → bump');
|
||||
expect(calls).toContain('viaDeref → bump');
|
||||
// A pointer CAPTURE is deref-able too: `for (pages) |*p|` records `*Page`
|
||||
// (not `Page`), so `const q = p.*;` still sees the pointer layer.
|
||||
expect(calls).toContain('viaPtrCaptureDeref → bump');
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -6,10 +6,11 @@
|
|||
* `DEFINITION_ANCHOR_LABELS × ATTACHMENT_TARGET_LABELS` for the framework and
|
||||
* pipeline-phase overlays — so both generated halves are covered there. What
|
||||
* neither rule can reach is `STRUCTURAL_PAIR_DDL`: the containment, inheritance
|
||||
* and import pairs BETWEEN TWO DEFINITION LABELS. Eleven node tables are absent
|
||||
* and import pairs BETWEEN TWO DEFINITION LABELS. Ten node tables are absent
|
||||
* from every rule's target side (`CodeElement`, `Impl`, `Namespace`,
|
||||
* `Template`, `TypeAlias`, `Typedef`, `Union`, `Static`, `Section`, `Folder`,
|
||||
* and the PDG-only `BasicBlock`), so a pair pointing at one is hand-declared or
|
||||
* `Template`, `TypeAlias`, `Typedef`, `Static`, `Section`, `Folder`, and the
|
||||
* PDG-only `BasicBlock` — `Union` left this set when Zig made it a linkable
|
||||
* member container), so a pair pointing at one is hand-declared or
|
||||
* it does not exist. No predicate describes that surface — any container can
|
||||
* hold any definition — so this asks the emitters directly: run the real
|
||||
* pipeline and require every FROM/TO pair it produces to be declared.
|
||||
|
|
|
|||
|
|
@ -60,9 +60,14 @@ describe('optional grammar required-gate', () => {
|
|||
}
|
||||
});
|
||||
|
||||
it('is inert for a grammar-key variant nobody registered', () => {
|
||||
// `typescript:tsx` IS a registry key (`listGrammarSources()` yields it) —
|
||||
// what makes it inert is that OPTIONAL_GRAMMAR_ENV has no entry for it, the
|
||||
// grammar being mandatory. A key no registry ever yields is inert the same
|
||||
// way; both stay ungated no matter what env vars are set.
|
||||
it('is inert for a grammar key with no gate entry, registered or not', () => {
|
||||
process.env[envVar] = '1';
|
||||
expect(isOptionalGrammarRequired('typescript:tsx')).toBe(false);
|
||||
expect(isOptionalGrammarRequired('no-such:grammar')).toBe(false);
|
||||
});
|
||||
|
||||
// Languages with no entry must never be gated — an unregistered language
|
||||
|
|
|
|||
|
|
@ -136,13 +136,27 @@ describe('resolveZigImportInternal', () => {
|
|||
|
||||
it('returns null for absolute `.path` deps, POSIX and Windows spellings alike', () => {
|
||||
// `normalizeZigDepPath` promises null for anything outside the repo; a
|
||||
// `/`-only check let `C:\\local_dep` through as the relative `C:/local_dep`.
|
||||
// `/`-only check let `C:\\local_dep` through as the relative `C:/local_dep`,
|
||||
// and an absolute check that ran BEFORE backslash normalization let the
|
||||
// UNC `\\\\server\\share\\local_dep` (and root-relative `\\local_dep`)
|
||||
// through as relative paths. The `root.zig` entries below are the files
|
||||
// those misreadings WOULD resolve — each spelling must reject, not merely
|
||||
// miss.
|
||||
const files = new Set<string>([
|
||||
'src/main.zig',
|
||||
'C:/local_dep/src/dep.zig',
|
||||
'local_dep/src/dep.zig',
|
||||
'local_dep/src/root.zig',
|
||||
'server/share/local_dep/src/root.zig',
|
||||
]);
|
||||
for (const abs of ['/local_dep', 'C:\\local_dep', 'c:/local_dep', 'D:\\x\\local_dep']) {
|
||||
for (const abs of [
|
||||
'/local_dep',
|
||||
'C:\\local_dep',
|
||||
'c:/local_dep',
|
||||
'D:\\x\\local_dep',
|
||||
'\\\\server\\share\\local_dep',
|
||||
'\\local_dep',
|
||||
]) {
|
||||
const zon = { pathDeps: new Map([['dep', abs]]) };
|
||||
expect(resolveZigImportInternal('src/main.zig', 'dep', files, zon)).toBeNull();
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue