mirror of
https://github.com/abhigyanpatwari/GitNexus.git
synced 2026-10-08 03:08:13 +00:00
feat: Phase 4 — known limitation tests, match arm fix, final verification
- Fix Rust match_arm pattern extraction: unwrap match_pattern to get tuple_struct_pattern inside (tree-sitter-rust wraps in match_pattern node) - Add first-writer-wins regression test for match arm scope leakage - Add 5 documented skip tests for known limitations: - TS destructured for-of (tuple destructuring) - Python tuple unpacking in for-loops - TS instanceof narrowing (block-level scoping) - Rust for with .iter() (method call iterable) - Ruby block parameters (closure param inference) Final: 238 passed, 5 skipped (documented limitations), tsc clean
This commit is contained in:
parent
104f9cd311
commit
caa3310714
2 changed files with 45 additions and 2 deletions
|
|
@ -222,9 +222,13 @@ const extractPatternBinding: PatternBindingExtractor = (
|
|||
patternNode = node.childForFieldName('pattern');
|
||||
valueNode = node.childForFieldName('value');
|
||||
} else if (node.type === 'match_arm') {
|
||||
// match_arm → pattern is in the 'pattern' field
|
||||
// match_arm → pattern field is match_pattern wrapping the actual pattern
|
||||
const matchPatternNode = node.childForFieldName('pattern');
|
||||
// Unwrap match_pattern to get the tuple_struct_pattern inside
|
||||
patternNode = matchPatternNode?.type === 'match_pattern'
|
||||
? matchPatternNode.firstNamedChild
|
||||
: matchPatternNode;
|
||||
// source variable is in the parent match_expression's 'value' field
|
||||
patternNode = node.childForFieldName('pattern');
|
||||
const matchExpr = node.parent?.parent; // match_arm → match_block → match_expression
|
||||
if (matchExpr?.type === 'match_expression') {
|
||||
valueNode = matchExpr.childForFieldName('value');
|
||||
|
|
|
|||
|
|
@ -2927,4 +2927,43 @@ class Foo {
|
|||
expect(flatGet(env, 'user')).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('known limitations (documented skip tests)', () => {
|
||||
it.skip('TS destructured for-of: for (const [k, v] of entries) — requires tuple destructuring', () => {
|
||||
// extractVarName returns undefined for array_pattern
|
||||
});
|
||||
|
||||
it.skip('Python tuple unpacking: for key, value in dict.items() — requires pattern_list', () => {
|
||||
// left is pattern_list, not identifier
|
||||
});
|
||||
|
||||
it.skip('TS instanceof narrowing: if (x instanceof User) { x.save() } — needs block-level scoping', () => {
|
||||
// Narrows existing variable, does not introduce new one
|
||||
});
|
||||
|
||||
it.skip('Rust for with .iter(): for user in users.iter() — needs method call iterable resolution', () => {
|
||||
// Iterable is a call_expression, not an identifier
|
||||
});
|
||||
|
||||
it.skip('Ruby block parameter: users.each { |user| } — closure param inference, different feature', () => {
|
||||
// Not a for-loop; requires block/closure parameter inference
|
||||
});
|
||||
});
|
||||
|
||||
describe('match arm scoping — first-writer-wins regression', () => {
|
||||
it('Rust: first match arm binding wins, later arms do not overwrite', () => {
|
||||
const tree = parse(`
|
||||
fn process(opt: Option<User>) {
|
||||
match opt {
|
||||
Some(user) => user.save(),
|
||||
None => {},
|
||||
}
|
||||
}
|
||||
`, Rust);
|
||||
const { env } = buildTypeEnv(tree, 'rust');
|
||||
// user should be typed from the first arm (Some unwrap)
|
||||
// Known limitation: binding leaks across arms (first-writer-wins)
|
||||
expect(flatGet(env, 'user')).toBe('User');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue