mirror of
https://github.com/abhigyanpatwari/GitNexus.git
synced 2026-09-21 00:21:30 +00:00
feat(csharp-scope): parity Unit 6a — class-like owner extension
Closes 1 parity failure (10 → 9). Extends `populateClassOwnedMembers` to recognize Interface / Struct / Record / Enum / Trait as class-like owners, not just Class. The C# scope query collapses interface_declaration / struct_declaration / record_declaration / enum_declaration to @scope.class (they share body-scope semantics), but the declaration-side tags produce defs of type Interface / Struct / Record / Enum. `populateClassOwnedMembers` previously only looked for Class-typed defs in class scopes, so interface members (including C# 8+ default methods) never got ownerIds — making them invisible to `findOwnedMember` via `memberByOwner`. With this fix, `user.Validate()` on a variable typed as `IValidator` resolves correctly: receiver-bound-calls Case 4 finds IValidator via findClassBindingInScope (which already accepted Interface), walks the chain, and findOwnedMember locates Validate now that the interface default has a proper ownerId. Legacy C# 175/175 green; Python parity 204/204 on both flag paths; 9 C# parity failures remain.
This commit is contained in:
parent
ac2b667922
commit
2de104150e
1 changed files with 16 additions and 4 deletions
|
|
@ -183,13 +183,25 @@ export function populateClassOwnedMembers(parsed: ParsedFile): void {
|
|||
// on `class U: def save(self): def helper(): ...` — helper.ownerId will
|
||||
// remain undefined. The theoretical concern is real only if the
|
||||
// extractor ever stops creating scopes for inner defs.
|
||||
// Class-like def types: Class scope covers C#'s interface/struct/
|
||||
// record/enum too (they all collapse to @scope.class per the query
|
||||
// contract). Interface default methods land as children of the
|
||||
// Interface def here.
|
||||
const isClassLike = (t: string): boolean =>
|
||||
t === 'Class' ||
|
||||
t === 'Interface' ||
|
||||
t === 'Struct' ||
|
||||
t === 'Record' ||
|
||||
t === 'Enum' ||
|
||||
t === 'Trait';
|
||||
|
||||
for (const scope of parsed.scopes) {
|
||||
// Methods: function scope whose parent is a Class scope. Owner is
|
||||
// the parent's Class def.
|
||||
// the parent's class-like def.
|
||||
if (scope.parent !== null) {
|
||||
const parentScope = scopesById.get(scope.parent);
|
||||
if (parentScope !== undefined && parentScope.kind === 'Class') {
|
||||
const classDef = parentScope.ownedDefs.find((d) => d.type === 'Class');
|
||||
const classDef = parentScope.ownedDefs.find((d) => isClassLike(d.type));
|
||||
if (classDef !== undefined) {
|
||||
for (const def of scope.ownedDefs) {
|
||||
(def as { ownerId?: string }).ownerId = classDef.nodeId;
|
||||
|
|
@ -199,9 +211,9 @@ export function populateClassOwnedMembers(parsed: ParsedFile): void {
|
|||
}
|
||||
}
|
||||
// Class-body fields: defs directly owned by a Class scope (the
|
||||
// class def itself excluded).
|
||||
// class-like def itself excluded).
|
||||
if (scope.kind === 'Class') {
|
||||
const classDef = scope.ownedDefs.find((d) => d.type === 'Class');
|
||||
const classDef = scope.ownedDefs.find((d) => isClassLike(d.type));
|
||||
if (classDef !== undefined) {
|
||||
for (const def of scope.ownedDefs) {
|
||||
if (def === classDef) continue;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue