/* eslint-disable @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any */
/**
 * Shared test helpers for attribute collection pass tests.
 */
export { describe, it } from "mocha";
export { expect } from "chai";
export { runAttributeCollectionPass } from "../attribute-collection-pass.js";
/**
 * Assert value is not null/undefined and return it typed as non-null.
 */
export const assertDefined = (value, msg) => {
    if (value === null || value === undefined) {
        throw new Error(msg ?? "Expected value to be defined");
    }
    return value;
};
/**
 * Helper to create a minimal IrModule for testing
 */
export const createModule = (body, attributesApiLocalName = "A", attributeTargetsLocalName) => ({
    kind: "module",
    filePath: "test.ts",
    namespace: "Test",
    className: "Test",
    isStaticContainer: false,
    imports: [
        {
            kind: "import",
            source: "@tsonic/core/lang.js",
            isLocal: false,
            isClr: false,
            specifiers: [
                {
                    kind: "named",
                    name: "attributes",
                    localName: attributesApiLocalName,
                },
                ...(attributeTargetsLocalName
                    ? [
                        {
                            kind: "named",
                            name: "AttributeTargets",
                            localName: attributeTargetsLocalName,
                        },
                    ]
                    : []),
            ],
        },
    ],
    body,
    exports: [],
});
/**
 * Helper to create a minimal identifier IR
 */
export const makeIdentifier = (name, resolvedClrType) => ({
    kind: "identifier",
    name,
    resolvedClrType,
});
export const makeTypedIdentifier = (name, inferredType) => ({
    kind: "identifier",
    name,
    inferredType,
});
export const makeRefType = (name, resolvedClrType) => ({
    kind: "referenceType",
    name,
    resolvedClrType,
});
/**
 * Helper to create a minimal member access IR
 */
export const makeMemberAccess = (object, property) => ({
    kind: "memberAccess",
    object,
    property,
    isComputed: false,
    isOptional: false,
});
/**
 * Helper to create a minimal call IR
 */
export const makeCall = (callee, args, typeArguments) => ({
    kind: "call",
    callee,
    arguments: args,
    isOptional: false,
    ...(typeArguments ? { typeArguments } : {}),
});
/**
 * Helper to create a minimal literal IR
 */
export const makeLiteral = (value) => ({
    kind: "literal",
    value,
    raw: String(value),
});
export const makeObject = (properties) => ({
    kind: "object",
    properties,
});
export const makeObjectProp = (key, value) => ({
    kind: "property",
    key,
    value,
    shorthand: false,
});
export const makeObjectSpread = (expression) => ({
    kind: "spread",
    expression,
});
export const makeUnaryTypeof = (expression) => ({
    kind: "unary",
    operator: "typeof",
    expression,
});
export const makeSpreadArg = (expression) => ({
    kind: "spread",
    expression,
});
export const makeParameter = (name) => ({
    kind: "parameter",
    pattern: { kind: "identifierPattern", name },
    type: undefined,
    initializer: undefined,
    isOptional: false,
    isRest: false,
    passing: "value",
});
export const makeSelector = (memberName) => ({
    kind: "arrowFunction",
    parameters: [makeParameter("x")],
    isAsync: false,
    body: makeMemberAccess(makeIdentifier("x"), memberName),
});
export const makeWrappedSelector = (memberName) => ({
    kind: "arrowFunction",
    parameters: [makeParameter("x")],
    isAsync: false,
    body: makeMemberAccess({
        kind: "typeAssertion",
        expression: makeTypedIdentifier("x", makeRefType("User")),
        targetType: makeRefType("User"),
        inferredType: makeRefType("User"),
    }, memberName),
});
export const makeBadSelectorCallBody = (memberName) => ({
    kind: "arrowFunction",
    parameters: [makeParameter("x")],
    isAsync: false,
    body: makeCall(makeMemberAccess(makeIdentifier("x"), memberName), []),
});
export const makeTypeRootCall = (targetName, apiObjectName = "A") => makeCall(makeIdentifier(apiObjectName), [], [makeRefType(targetName)]);
export const makeFunctionRootCall = (targetName, apiObjectName = "A") => makeCall(makeIdentifier(apiObjectName), [makeIdentifier(targetName)]);
/**
 * Helper to create an attribute marker call IR for A<T>().add(Attr, ...args)
 */
export const makeMarkerCall = (targetName, attrName, args = [], resolvedClrType, apiObjectName = "A") => ({
    kind: "expressionStatement",
    expression: makeCall(makeMemberAccess(makeTypeRootCall(targetName, apiObjectName), "add"), [
        makeIdentifier(attrName, resolvedClrType),
        ...args.map((a) => makeLiteral(a.value)),
    ]),
});
export const makeTypeMarkerCallWithTarget = (targetName, attrName, targetArg, apiObjectName = "A") => ({
    kind: "expressionStatement",
    expression: makeCall(makeMemberAccess(makeCall(makeMemberAccess(makeTypeRootCall(targetName, apiObjectName), "target"), [targetArg]), "add"), [makeIdentifier(attrName, `Test.${attrName}`)]),
});
export const makeCtorMarkerCall = (targetName, attrName) => ({
    kind: "expressionStatement",
    expression: makeCall(makeMemberAccess(makeMemberAccess(makeTypeRootCall(targetName), "ctor"), "add"), [makeIdentifier(attrName, `Test.${attrName}`)]),
});
export const makeCtorMarkerCallWithTarget = (targetName, attrName, targetArg) => ({
    kind: "expressionStatement",
    expression: makeCall(makeMemberAccess(makeCall(makeMemberAccess(makeMemberAccess(makeTypeRootCall(targetName), "ctor"), "target"), [targetArg]), "add"), [makeIdentifier(attrName, `Test.${attrName}`)]),
});
export const makeMethodMarkerCall = (targetName, attrName, selector) => ({
    kind: "expressionStatement",
    expression: makeCall(makeMemberAccess(makeCall(makeMemberAccess(makeTypeRootCall(targetName), "method"), [
        selector,
    ]), "add"), [makeIdentifier(attrName, `Test.${attrName}`)]),
});
export const makeMethodMarkerCallWithTarget = (targetName, attrName, selector, targetArg) => ({
    kind: "expressionStatement",
    expression: makeCall(makeMemberAccess(makeCall(makeMemberAccess(makeCall(makeMemberAccess(makeTypeRootCall(targetName), "method"), [
        selector,
    ]), "target"), [targetArg]), "add"), [makeIdentifier(attrName, `Test.${attrName}`)]),
});
export const makePropMarkerCall = (targetName, propName, attrName, selector = makeSelector(propName)) => ({
    kind: "expressionStatement",
    expression: makeCall(makeMemberAccess(makeCall(makeMemberAccess(makeTypeRootCall(targetName), "prop"), [
        selector,
    ]), "add"), [makeIdentifier(attrName, `Test.${attrName}`)]),
});
export const makePropMarkerCallWithTarget = (targetName, propName, attrName, targetArg) => ({
    kind: "expressionStatement",
    expression: makeCall(makeMemberAccess(makeCall(makeMemberAccess(makeCall(makeMemberAccess(makeTypeRootCall(targetName), "prop"), [
        makeSelector(propName),
    ]), "target"), [targetArg]), "add"), [makeIdentifier(attrName, `Test.${attrName}`)]),
});
export const makeAttrDescriptorDecl = (varName, attrName) => ({
    kind: "variableDeclaration",
    declarationKind: "const",
    isExported: false,
    declarations: [
        {
            kind: "variableDeclarator",
            name: { kind: "identifierPattern", name: varName },
            initializer: makeCall(makeMemberAccess(makeIdentifier("A"), "attr"), [
                makeIdentifier(attrName, `Test.${attrName}`),
                makeLiteral("msg"),
            ]),
        },
    ],
});
export const makeAddDescriptorMarkerCall = (targetName, varName) => ({
    kind: "expressionStatement",
    expression: makeCall(makeMemberAccess(makeTypeRootCall(targetName), "add"), [
        makeIdentifier(varName),
    ]),
});
export const makeInlineDescriptorMarkerCall = (targetName, attrName) => ({
    kind: "expressionStatement",
    expression: makeCall(makeMemberAccess(makeTypeRootCall(targetName), "add"), [
        makeCall(makeMemberAccess(makeIdentifier("A"), "attr"), [
            makeIdentifier(attrName, `Test.${attrName}`),
            makeLiteral("msg"),
        ]),
    ]),
});
export const makeFunctionMarkerCall = (functionName, attrName, args = [], resolvedClrType, apiObjectName = "A") => ({
    kind: "expressionStatement",
    expression: makeCall(makeMemberAccess(makeFunctionRootCall(functionName, apiObjectName), "add"), [
        makeIdentifier(attrName, resolvedClrType),
        ...args.map((a) => makeLiteral(a.value)),
    ]),
});
//# sourceMappingURL=helpers.js.map