feat: establish first-class lexical language parity #2

Merged
trevon merged 14 commits from feat/language-parity-foundation into bench/yams-architecture-reproducibility 2026-08-30 22:09:40 +00:00
5 changed files with 68 additions and 2 deletions
Showing only changes of commit e2a0cbcaa0 - Show all commits

test(scan): characterize secondary language coverage

trvon 2026-08-30 15:53:57 -06:00
Signed by: trevon
GPG key ID: 38686EA797D7A8A7

View file

@ -24,8 +24,8 @@ frontend; Brick does not guess that ownership.
| C++ | Classes/structs/unions/enums, `final`, constructors/destructors/operators, override-qualified methods, multiple inheritance, ordinary calls, and local include resolution | namespaces, overload disambiguation, lambdas, concepts/requires, complex template bases, and multiline declarations | first-class target |
| JavaScript | Default/exported classes, inheritance, owned methods/constructors, named functions, arrows, ES imports/re-exports, CommonJS `require`, dynamic imports, ordinary calls, and multiline template masking | function expressions, computed methods, decorators, JSX structure, package exports, and type-aware member calls | first-class target |
| TypeScript | JavaScript forms plus interfaces/enums/namespaces, generic and abstract classes/functions/methods, `implements`, type imports/re-exports, and typed arrows | type aliases, overload declarations, decorators, declaration merging, TSX structure, and path mappings | first-class target |
| Python | Basic classes, functions/async functions, imports, calls, and indentation scopes | multiple bases, qualified ownership, decorators, multiline strings, relative/dynamic imports, and complete multi-import handling | secondary |
| Swift | File recognition and incidental matching of some class/function syntax | no dedicated patterns; imports, protocols, actors, enums, extensions, async/generic forms, and ownership are incomplete | secondary |
| Python | Characterized fixture coverage for basic classes, functions/async functions, imports, calls, inheritance, and indentation scopes | multiple bases, qualified ownership, decorators, multiline strings, relative/dynamic imports, and complete multi-import handling | secondary |
| Swift | Characterized extension recognition plus incidental simple `class`, `func`, inheritance, ownership, and call matching | no dedicated profile; imports, protocols, actors, enums, extensions, async/generic forms, and Swift-specific signatures are incomplete | secondary |
## Cross-language invariants
@ -64,6 +64,11 @@ Compare graph counts and health metrics only after confirming that analyzed
files, constructs, and evidence coverage remain stable. A lower health score can
be more accurate when a false resolved edge becomes an honest unresolved edge.
Python and Swift fixtures intentionally describe their current secondary tier in
the same corpus. Their assertions are characterization tests, not evidence of
first-class parity. In particular, the Swift fixture preserves the visible gap
between file/type recognition and Swift-specific relationship extraction.
## Delivery order
1. Shared resolver and scope foundation.

View file

@ -0,0 +1,2 @@
class Base:
pass

View file

@ -0,0 +1,10 @@
from base import Base
class Worker(Base):
async def start(self):
helper()
def helper():
pass

View file

@ -0,0 +1,9 @@
import Foundation
protocol Runnable {}
class Worker: Base {
func start() {
helper()
}
}

View file

@ -180,6 +180,46 @@ fn javascript_and_typescript_model_members_without_template_phantoms() {
}
}
#[test]
fn secondary_languages_have_explicit_non_parity_characterization() {
let python = scan(&fixture_root("python")).unwrap();
let python_classes: Vec<_> = python
.nodes
.iter()
.filter(|node| node.kind == NodeKind::Class)
.map(|node| node.name.as_str())
.collect();
let python_functions: Vec<_> = python
.nodes
.iter()
.filter(|node| node.kind == NodeKind::Function)
.map(|node| node.name.as_str())
.collect();
assert_eq!(python_classes.len(), 2);
assert!(python_classes.contains(&"Base"));
assert!(python_classes.contains(&"Worker"));
assert_eq!(python_functions.len(), 2);
assert!(python_functions.contains(&"helper"));
assert!(python_functions.contains(&"start"));
assert_eq!(edge_count(&python, EdgeKind::Imports), 1);
assert_eq!(edge_count(&python, EdgeKind::Inherits), 1);
assert_eq!(edge_count(&python, EdgeKind::Calls), 1);
let swift = scan(&fixture_root("swift")).unwrap();
let swift_symbols: Vec<_> = swift
.nodes
.iter()
.filter(|node| matches!(node.kind, NodeKind::Class | NodeKind::Function))
.map(|node| node.name.as_str())
.collect();
assert_eq!(swift_symbols.len(), 2);
assert!(swift_symbols.contains(&"Worker"));
assert!(swift_symbols.contains(&"start"));
assert_eq!(edge_count(&swift, EdgeKind::Imports), 0);
assert_eq!(edge_count(&swift, EdgeKind::Inherits), 1);
assert_eq!(edge_count(&swift, EdgeKind::Calls), 1);
}
fn assert_fixture(case: FixtureCase) {
let root = fixture_root(case.directory);
let building = scan(&root).unwrap();