Complete Phase E5 tier-6 Adw/Soup/Gst compile-gate compliance
Relaxes the generated-filename PascalCase validator's uppercase-run cap (>3 -> >4) so legitimate acronym type names (PluginAPIFlags, AuthNTLM) stop crashing generation. Fixes four compounding cross-module correctness bugs the larger tier-6 GIR set exposed at scale: - The duplicate-of-dependency drop only checked simple-name collision, wrongly dropping genuinely distinct C types that merely share a post-namespace-stripping Swift name (Gst.Object/GstObject vs GObject.Object/GObject, plus three tier-4/5 cases: Gdk.AppLaunchContext, Gdk.Gravity, Gdk.Rectangle). Now also requires matching cType. - Qualifying a cross-module reference as "GObject.X" broke wherever a raw C struct also named GObject was in scope (every C target's import), since Swift resolved the module name to the shadowing struct. GObject's Support.swift now exports collision-free GLibObject/GLibValueArray aliases used instead. - Missing `override` keyword: added ancestor-method-selector detection (name + parameter labels, same-module only, since none of these members are open) so a subclass narrowing an ancestor's return type compiles. - The pre-existing cross-module inherited-member dedup pass keyed ancestors by bare Swift name; its cycle guard falsely self-terminated once two classes shared a name, missing real inherited members (e.g. GstObject's own ref()/unref() were never recognized as duplicating GObject.Object's, producing an illegal redeclaration). Rewired to walk by unambiguous GIR name via new ClassPlan.girName/parentGIRName fields. Also fixes bitfield/enum-typed global constants (wraps the raw literal in Type(rawValue:)) and a void-returning ref function (gst_atomic_queue_ref, unlike GstBuffer/GObject's T*-returning convention) via new RecordPlan.copyReturnsVoid. Adds tier-6 smoke tests (Gst/Soup/Adw version calls against the real linked libraries) and refreshes the tier-4/5 skip baselines for the duplicate-detection fix's legitimate coverage growth. Zero skip-baseline drift on tiers 1-6; 220/220 unit tests and all tier smoke suites pass.
This commit is contained in:
parent
c20015be48
commit
525aefa7aa
9 changed files with 545 additions and 121 deletions
|
|
@ -53,6 +53,8 @@ struct NamingTests {
|
|||
#expect(isValidGeneratedFileName("DNDEvent.swift")) // acronym type name
|
||||
#expect(!isValidGeneratedFileName("Align.txt")) // wrong extension
|
||||
#expect(!isValidGeneratedFileName("MarshalBOOLEAN.swift")) // uppercase run, PascalCase start
|
||||
#expect(isValidGeneratedFileName("PluginAPIFlags.swift")) // 4-run acronym, Gst
|
||||
#expect(isValidGeneratedFileName("AuthNTLM.swift")) // 4-run acronym, Soup
|
||||
}
|
||||
|
||||
// MARK: - File merging
|
||||
|
|
|
|||
|
|
@ -203,16 +203,22 @@ struct TypeRegistryTests {
|
|||
@Test("A type dropped as a duplicate of a dependency is detected regardless of the referencing namespace")
|
||||
func detectsCrossModuleDroppedType() {
|
||||
// Dep declares Rect; Mid (which depends on Dep) redeclares the same
|
||||
// simple name — the planner drops Mid.Rect as a duplicate. A
|
||||
// reference into Mid.Rect from any namespace, not just Mid's own,
|
||||
// must be recognized as dangling.
|
||||
// simple name *and the same underlying C struct* — a genuine
|
||||
// redundant forwarding declaration (e.g. a compat header
|
||||
// re-exporting a dependency's type under its own namespace) — the
|
||||
// planner drops Mid.Rect as a duplicate. A reference into Mid.Rect
|
||||
// from any namespace, not just Mid's own, must be recognized as
|
||||
// dangling. A same-name but *different*-cType pair (two genuinely
|
||||
// distinct C structs that merely share a post-namespace-stripping
|
||||
// Swift name, e.g. `GstObject` vs `GObject`) is deliberately NOT
|
||||
// a match here — see `ambiguousCrossModuleNameKeepsBothTypes`.
|
||||
let dep = Repository(namespaces: [
|
||||
Namespace(name: "Dep", version: "1.0",
|
||||
records: [Record(name: "Rect", cType: "DepRect", getTypeFunction: "dep_rect_get_type")])
|
||||
records: [Record(name: "Rect", cType: "Rect", getTypeFunction: "dep_rect_get_type")])
|
||||
])
|
||||
let mid = Repository(namespaces: [
|
||||
Namespace(name: "Mid", version: "1.0",
|
||||
records: [Record(name: "Rect", cType: "MidRect", getTypeFunction: "mid_rect_get_type")])
|
||||
records: [Record(name: "Rect", cType: "Rect", getTypeFunction: "mid_rect_get_type")])
|
||||
])
|
||||
let registry = TypeRegistry(
|
||||
repositories: ["Dep": dep, "Mid": mid],
|
||||
|
|
@ -233,6 +239,32 @@ struct TypeRegistryTests {
|
|||
}
|
||||
}
|
||||
|
||||
@Test("A same-name but different-cType type across a dependency is not a duplicate — both are kept and disambiguated")
|
||||
func ambiguousCrossModuleNameKeepsBothTypes() throws {
|
||||
// Mirrors `Gst.Object` (`GstObject`) vs `GObject.Object` (`GObject`):
|
||||
// Base declares `Object`, and Sub (which depends on Base) also
|
||||
// declares its own distinct `Object` with a different cType.
|
||||
// this must NOT be treated as a duplicate: both are real, distinct
|
||||
// C structs that merely share a post-namespace-stripping Swift
|
||||
// name, so both must be generated and cross-references qualified.
|
||||
let base = Repository(namespaces: [
|
||||
Namespace(name: "Base", version: "1.0",
|
||||
classes: [Class(name: "Object", cType: "BaseObject", parent: nil, getTypeFunction: "base_object_get_type")])
|
||||
])
|
||||
let sub = Repository(namespaces: [
|
||||
Namespace(name: "Sub", version: "1.0",
|
||||
classes: [Class(name: "Object", cType: "SubObject", parent: "Base.Object", getTypeFunction: "sub_object_get_type")])
|
||||
])
|
||||
let registry = TypeRegistry(
|
||||
repositories: ["Base": base, "Sub": sub],
|
||||
directDependencies: ["Sub": ["Base"]]
|
||||
)
|
||||
#expect(registry.droppedShadow("Sub.Object") == nil)
|
||||
#expect(registry.droppedShadow("Base.Object") == nil)
|
||||
let subObject = try #require(registry.resolve(girName: "Sub.Object"))
|
||||
#expect(registry.swiftTypeName(for: subObject, in: "Down") == "Sub.Object")
|
||||
}
|
||||
|
||||
@Test("Manually excluded namespaces are treated as foreign")
|
||||
func manualNamespacesAreForeign() {
|
||||
let repo = Repository(namespaces: [
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue