/** * One object, one name — checked before the bytes reach disk. * * An AOT object states its identity three times: the FILE NAME, the root * `` element, and (for the types that carry X++) the class declaration * inside ``. xppc requires all three to agree — "must be named X * instead of Y to be consistent with its file name" — and it says so at BUILD * time, one round trip after the write reported ✅. * * The 2026-08-31 capture run of L2-event-handler-basic produced exactly that: * `create(class, objectName:"EvalL2…Test", xmlContent:)` * wrote `ConDemoEvalL2…Test.xml` containing `class ConDemoEvalL2…Test` and * `EvalL2…Test` — three identities, two of them prefixed, one not. * The create path rewrote the X++ declaration (and `classnum`/`classStr`) when it * applied the model prefix, but never the metadata ``, and the write * verification only asked whether a file existed. So the defect was invisible * until the next build died. * * Two rules, in this order: * 1. REWRITE what can be rewritten — the root ``, alongside the prefix * rewrite the create path already does for the declaration. * 2. REFUSE what is left. A file whose identities disagree does not build, so * writing it and reporting success is strictly worse than not writing it: * the caller pays a build cycle to learn what this check knows for free. * * Extension objects are named `Base.Suffix` in metadata while their X++ says * `class Base_Extension`, so the declaration half is skipped for any dotted * name — comparing those two would refuse every correct extension. */ /** * The root element's own ``, or null. * * A CHILD OF THE ROOT, specifically — not "the first `` in the file". A * field, a control or a method carries a `` too, and a commented-out * example carries one that is not an identity at all. scanXmlLeaves answers the * structural question directly instead of deleting the parts of the document * that would otherwise confuse a regex; see xmlScan.ts for why the deleting * version is a bug and not just a lint finding. */ export declare function readRootObjectName(xml: string): string | null; /** * The class/interface name the X++ `` block declares, or null when * the document carries no declaration (a table extension, a form, an enum). * * Read through the shared lexer, not off the raw text. Every generated class * opens with a `///` block, and "Provides my new class MyNewClass functionality" * contains the word `class` — matching that as a declaration made this gate * refuse perfectly good creates on its first full-suite run. maskXpp blanks * comment and string CONTENT while preserving offsets, so the match runs over * code only and its offset still points into the original source. */ export declare function readDeclarationName(xml: string): string | null; /** * Rewrite the root `` from one identity to another. Only the root element * is touched: a field or control that happens to share the object's name keeps * its own name, which is why this replaces one occurrence and not all of them. */ export declare function rewriteRootObjectName(xml: string, from: string, to: string): string; export interface IdentityProblem { /** Where the disagreeing identity lives. */ where: 'root-name' | 'declaration'; found: string; } /** * Compare the identities inside the document against the name the object is * being written under. An empty array means all of them agree. */ export declare function checkObjectIdentity(xml: string, expectedName: string): IdentityProblem[]; /** The refusal an identity mismatch earns, written so the caller can act on it. */ export declare function renderIdentityRefusal(objectType: string, expectedName: string, fileName: string, problems: readonly IdentityProblem[]): string; //# sourceMappingURL=objectIdentityGate.d.ts.map