@codama/visitors-core
Version:
Core visitors for the Codama framework
1,327 lines (1,307 loc) • 74.5 kB
JavaScript
// src/identityVisitor.ts
import {
accountLinkNode,
accountNode,
amountTypeNode,
arrayTypeNode,
arrayValueNode,
assertIsNestedTypeNode,
assertIsNode,
booleanTypeNode,
conditionalValueNode,
constantDiscriminatorNode,
constantPdaSeedNode,
constantValueNode,
COUNT_NODES,
dateTimeTypeNode,
definedTypeLinkNode,
definedTypeNode,
DISCRIMINATOR_NODES,
ENUM_VARIANT_TYPE_NODES,
enumEmptyVariantTypeNode,
enumStructVariantTypeNode,
enumTupleVariantTypeNode,
enumTypeNode,
enumValueNode,
fixedSizeTypeNode,
hiddenPrefixTypeNode,
hiddenSuffixTypeNode,
INSTRUCTION_INPUT_VALUE_NODES,
instructionAccountLinkNode,
instructionAccountNode,
instructionArgumentLinkNode,
instructionArgumentNode,
instructionByteDeltaNode,
instructionLinkNode,
instructionNode,
instructionRemainingAccountsNode,
mapEntryValueNode,
mapTypeNode,
mapValueNode,
optionTypeNode,
PDA_SEED_NODES,
pdaLinkNode,
pdaNode,
pdaSeedValueNode,
pdaValueNode,
postOffsetTypeNode,
prefixedCountNode,
preOffsetTypeNode,
programNode,
REGISTERED_NODE_KINDS as REGISTERED_NODE_KINDS3,
remainderOptionTypeNode,
removeNullAndAssertIsNodeFilter,
resolverValueNode,
rootNode,
sentinelTypeNode,
setTypeNode,
setValueNode,
sizePrefixTypeNode,
solAmountTypeNode,
someValueNode,
structFieldTypeNode,
structFieldValueNode,
structTypeNode,
structValueNode,
tupleTypeNode,
tupleValueNode,
TYPE_NODES,
VALUE_NODES,
variablePdaSeedNode,
zeroableOptionTypeNode
} from "@codama/nodes";
// src/staticVisitor.ts
import { REGISTERED_NODE_KINDS as REGISTERED_NODE_KINDS2 } from "@codama/nodes";
// src/visitor.ts
import { CODAMA_ERROR__UNRECOGNIZED_NODE_KIND, CodamaError } from "@codama/errors";
import { pascalCase, REGISTERED_NODE_KINDS } from "@codama/nodes";
function visit(node, visitor) {
const key = getVisitFunctionName(node.kind);
return visitor[key](node);
}
function visitOrElse(node, visitor, fallback) {
const key = getVisitFunctionName(node.kind);
return (key in visitor ? visitor[key] : fallback)(node);
}
function getVisitFunctionName(nodeKind) {
if (!REGISTERED_NODE_KINDS.includes(nodeKind)) {
throw new CodamaError(CODAMA_ERROR__UNRECOGNIZED_NODE_KIND, { kind: nodeKind });
}
return `visit${pascalCase(nodeKind.slice(0, -4))}`;
}
// src/staticVisitor.ts
function staticVisitor(fn, options = {}) {
const keys = options.keys ?? REGISTERED_NODE_KINDS2;
const visitor = {};
keys.forEach((key) => {
visitor[getVisitFunctionName(key)] = fn.bind(visitor);
});
return visitor;
}
// src/identityVisitor.ts
function identityVisitor(options = {}) {
const keys = options.keys ?? REGISTERED_NODE_KINDS3;
const visitor = staticVisitor((node) => Object.freeze({ ...node }), { keys });
const visit2 = (v) => (node) => keys.includes(node.kind) ? visit(node, v) : Object.freeze({ ...node });
if (keys.includes("rootNode")) {
visitor.visitRoot = function visitRoot(node) {
const program = visit2(this)(node.program);
if (program === null) return null;
assertIsNode(program, "programNode");
return rootNode(
program,
node.additionalPrograms.map(visit2(this)).filter(removeNullAndAssertIsNodeFilter("programNode"))
);
};
}
if (keys.includes("programNode")) {
visitor.visitProgram = function visitProgram(node) {
return programNode({
...node,
accounts: node.accounts.map(visit2(this)).filter(removeNullAndAssertIsNodeFilter("accountNode")),
definedTypes: node.definedTypes.map(visit2(this)).filter(removeNullAndAssertIsNodeFilter("definedTypeNode")),
errors: node.errors.map(visit2(this)).filter(removeNullAndAssertIsNodeFilter("errorNode")),
instructions: node.instructions.map(visit2(this)).filter(removeNullAndAssertIsNodeFilter("instructionNode")),
pdas: node.pdas.map(visit2(this)).filter(removeNullAndAssertIsNodeFilter("pdaNode"))
});
};
}
if (keys.includes("pdaNode")) {
visitor.visitPda = function visitPda(node) {
return pdaNode({
...node,
seeds: node.seeds.map(visit2(this)).filter(removeNullAndAssertIsNodeFilter(PDA_SEED_NODES))
});
};
}
if (keys.includes("accountNode")) {
visitor.visitAccount = function visitAccount(node) {
const data = visit2(this)(node.data);
if (data === null) return null;
assertIsNode(data, "structTypeNode");
const pda = node.pda ? visit2(this)(node.pda) ?? void 0 : void 0;
if (pda) assertIsNode(pda, "pdaLinkNode");
return accountNode({ ...node, data, pda });
};
}
if (keys.includes("instructionNode")) {
visitor.visitInstruction = function visitInstruction(node) {
return instructionNode({
...node,
accounts: node.accounts.map(visit2(this)).filter(removeNullAndAssertIsNodeFilter("instructionAccountNode")),
arguments: node.arguments.map(visit2(this)).filter(removeNullAndAssertIsNodeFilter("instructionArgumentNode")),
byteDeltas: node.byteDeltas ? node.byteDeltas.map(visit2(this)).filter(removeNullAndAssertIsNodeFilter("instructionByteDeltaNode")) : void 0,
discriminators: node.discriminators ? node.discriminators.map(visit2(this)).filter(removeNullAndAssertIsNodeFilter(DISCRIMINATOR_NODES)) : void 0,
extraArguments: node.extraArguments ? node.extraArguments.map(visit2(this)).filter(removeNullAndAssertIsNodeFilter("instructionArgumentNode")) : void 0,
remainingAccounts: node.remainingAccounts ? node.remainingAccounts.map(visit2(this)).filter(removeNullAndAssertIsNodeFilter("instructionRemainingAccountsNode")) : void 0,
subInstructions: node.subInstructions ? node.subInstructions.map(visit2(this)).filter(removeNullAndAssertIsNodeFilter("instructionNode")) : void 0
});
};
}
if (keys.includes("instructionAccountNode")) {
visitor.visitInstructionAccount = function visitInstructionAccount(node) {
const defaultValue = node.defaultValue ? visit2(this)(node.defaultValue) ?? void 0 : void 0;
if (defaultValue) assertIsNode(defaultValue, INSTRUCTION_INPUT_VALUE_NODES);
return instructionAccountNode({ ...node, defaultValue });
};
}
if (keys.includes("instructionArgumentNode")) {
visitor.visitInstructionArgument = function visitInstructionArgument(node) {
const type = visit2(this)(node.type);
if (type === null) return null;
assertIsNode(type, TYPE_NODES);
const defaultValue = node.defaultValue ? visit2(this)(node.defaultValue) ?? void 0 : void 0;
if (defaultValue) assertIsNode(defaultValue, INSTRUCTION_INPUT_VALUE_NODES);
return instructionArgumentNode({ ...node, defaultValue, type });
};
}
if (keys.includes("instructionRemainingAccountsNode")) {
visitor.visitInstructionRemainingAccounts = function visitInstructionRemainingAccounts(node) {
const value = visit2(this)(node.value);
if (value === null) return null;
assertIsNode(value, ["argumentValueNode", "resolverValueNode"]);
return instructionRemainingAccountsNode(value, { ...node });
};
}
if (keys.includes("instructionByteDeltaNode")) {
visitor.visitInstructionByteDelta = function visitInstructionByteDelta(node) {
const value = visit2(this)(node.value);
if (value === null) return null;
assertIsNode(value, ["numberValueNode", "accountLinkNode", "argumentValueNode", "resolverValueNode"]);
return instructionByteDeltaNode(value, { ...node });
};
}
if (keys.includes("definedTypeNode")) {
visitor.visitDefinedType = function visitDefinedType(node) {
const type = visit2(this)(node.type);
if (type === null) return null;
assertIsNode(type, TYPE_NODES);
return definedTypeNode({ ...node, type });
};
}
if (keys.includes("arrayTypeNode")) {
visitor.visitArrayType = function visitArrayType(node) {
const size = visit2(this)(node.count);
if (size === null) return null;
assertIsNode(size, COUNT_NODES);
const item = visit2(this)(node.item);
if (item === null) return null;
assertIsNode(item, TYPE_NODES);
return arrayTypeNode(item, size);
};
}
if (keys.includes("enumTypeNode")) {
visitor.visitEnumType = function visitEnumType(node) {
return enumTypeNode(
node.variants.map(visit2(this)).filter(removeNullAndAssertIsNodeFilter(ENUM_VARIANT_TYPE_NODES)),
{ size: node.size }
);
};
}
if (keys.includes("enumStructVariantTypeNode")) {
visitor.visitEnumStructVariantType = function visitEnumStructVariantType(node) {
const newStruct = visit2(this)(node.struct);
if (!newStruct) {
return enumEmptyVariantTypeNode(node.name);
}
assertIsNode(newStruct, "structTypeNode");
if (newStruct.fields.length === 0) {
return enumEmptyVariantTypeNode(node.name);
}
return enumStructVariantTypeNode(node.name, newStruct);
};
}
if (keys.includes("enumTupleVariantTypeNode")) {
visitor.visitEnumTupleVariantType = function visitEnumTupleVariantType(node) {
const newTuple = visit2(this)(node.tuple);
if (!newTuple) {
return enumEmptyVariantTypeNode(node.name);
}
assertIsNode(newTuple, "tupleTypeNode");
if (newTuple.items.length === 0) {
return enumEmptyVariantTypeNode(node.name);
}
return enumTupleVariantTypeNode(node.name, newTuple);
};
}
if (keys.includes("mapTypeNode")) {
visitor.visitMapType = function visitMapType(node) {
const size = visit2(this)(node.count);
if (size === null) return null;
assertIsNode(size, COUNT_NODES);
const key = visit2(this)(node.key);
if (key === null) return null;
assertIsNode(key, TYPE_NODES);
const value = visit2(this)(node.value);
if (value === null) return null;
assertIsNode(value, TYPE_NODES);
return mapTypeNode(key, value, size);
};
}
if (keys.includes("optionTypeNode")) {
visitor.visitOptionType = function visitOptionType(node) {
const prefix = visit2(this)(node.prefix);
if (prefix === null) return null;
assertIsNestedTypeNode(prefix, "numberTypeNode");
const item = visit2(this)(node.item);
if (item === null) return null;
assertIsNode(item, TYPE_NODES);
return optionTypeNode(item, { ...node, prefix });
};
}
if (keys.includes("zeroableOptionTypeNode")) {
visitor.visitZeroableOptionType = function visitZeroableOptionType(node) {
const item = visit2(this)(node.item);
if (item === null) return null;
assertIsNode(item, TYPE_NODES);
const zeroValue = node.zeroValue ? visit2(this)(node.zeroValue) ?? void 0 : void 0;
if (zeroValue) assertIsNode(zeroValue, "constantValueNode");
return zeroableOptionTypeNode(item, zeroValue);
};
}
if (keys.includes("remainderOptionTypeNode")) {
visitor.visitRemainderOptionType = function visitRemainderOptionType(node) {
const item = visit2(this)(node.item);
if (item === null) return null;
assertIsNode(item, TYPE_NODES);
return remainderOptionTypeNode(item);
};
}
if (keys.includes("booleanTypeNode")) {
visitor.visitBooleanType = function visitBooleanType(node) {
const size = visit2(this)(node.size);
if (size === null) return null;
assertIsNestedTypeNode(size, "numberTypeNode");
return booleanTypeNode(size);
};
}
if (keys.includes("setTypeNode")) {
visitor.visitSetType = function visitSetType(node) {
const size = visit2(this)(node.count);
if (size === null) return null;
assertIsNode(size, COUNT_NODES);
const item = visit2(this)(node.item);
if (item === null) return null;
assertIsNode(item, TYPE_NODES);
return setTypeNode(item, size);
};
}
if (keys.includes("structTypeNode")) {
visitor.visitStructType = function visitStructType(node) {
const fields = node.fields.map(visit2(this)).filter(removeNullAndAssertIsNodeFilter("structFieldTypeNode"));
return structTypeNode(fields);
};
}
if (keys.includes("structFieldTypeNode")) {
visitor.visitStructFieldType = function visitStructFieldType(node) {
const type = visit2(this)(node.type);
if (type === null) return null;
assertIsNode(type, TYPE_NODES);
const defaultValue = node.defaultValue ? visit2(this)(node.defaultValue) ?? void 0 : void 0;
if (defaultValue) assertIsNode(defaultValue, VALUE_NODES);
return structFieldTypeNode({ ...node, defaultValue, type });
};
}
if (keys.includes("tupleTypeNode")) {
visitor.visitTupleType = function visitTupleType(node) {
const items = node.items.map(visit2(this)).filter(removeNullAndAssertIsNodeFilter(TYPE_NODES));
return tupleTypeNode(items);
};
}
if (keys.includes("amountTypeNode")) {
visitor.visitAmountType = function visitAmountType(node) {
const number = visit2(this)(node.number);
if (number === null) return null;
assertIsNestedTypeNode(number, "numberTypeNode");
return amountTypeNode(number, node.decimals, node.unit);
};
}
if (keys.includes("dateTimeTypeNode")) {
visitor.visitDateTimeType = function visitDateTimeType(node) {
const number = visit2(this)(node.number);
if (number === null) return null;
assertIsNestedTypeNode(number, "numberTypeNode");
return dateTimeTypeNode(number);
};
}
if (keys.includes("solAmountTypeNode")) {
visitor.visitSolAmountType = function visitSolAmountType(node) {
const number = visit2(this)(node.number);
if (number === null) return null;
assertIsNestedTypeNode(number, "numberTypeNode");
return solAmountTypeNode(number);
};
}
if (keys.includes("prefixedCountNode")) {
visitor.visitPrefixedCount = function visitPrefixedCount(node) {
const prefix = visit2(this)(node.prefix);
if (prefix === null) return null;
assertIsNestedTypeNode(prefix, "numberTypeNode");
return prefixedCountNode(prefix);
};
}
if (keys.includes("arrayValueNode")) {
visitor.visitArrayValue = function visitArrayValue(node) {
return arrayValueNode(node.items.map(visit2(this)).filter(removeNullAndAssertIsNodeFilter(VALUE_NODES)));
};
}
if (keys.includes("constantValueNode")) {
visitor.visitConstantValue = function visitConstantValue(node) {
const type = visit2(this)(node.type);
if (type === null) return null;
assertIsNode(type, TYPE_NODES);
const value = visit2(this)(node.value);
if (value === null) return null;
assertIsNode(value, VALUE_NODES);
return constantValueNode(type, value);
};
}
if (keys.includes("enumValueNode")) {
visitor.visitEnumValue = function visitEnumValue(node) {
const enumLink = visit2(this)(node.enum);
if (enumLink === null) return null;
assertIsNode(enumLink, ["definedTypeLinkNode"]);
const value = node.value ? visit2(this)(node.value) ?? void 0 : void 0;
if (value) assertIsNode(value, ["structValueNode", "tupleValueNode"]);
return enumValueNode(enumLink, node.variant, value);
};
}
if (keys.includes("mapValueNode")) {
visitor.visitMapValue = function visitMapValue(node) {
return mapValueNode(
node.entries.map(visit2(this)).filter(removeNullAndAssertIsNodeFilter("mapEntryValueNode"))
);
};
}
if (keys.includes("mapEntryValueNode")) {
visitor.visitMapEntryValue = function visitMapEntryValue(node) {
const key = visit2(this)(node.key);
if (key === null) return null;
assertIsNode(key, VALUE_NODES);
const value = visit2(this)(node.value);
if (value === null) return null;
assertIsNode(value, VALUE_NODES);
return mapEntryValueNode(key, value);
};
}
if (keys.includes("setValueNode")) {
visitor.visitSetValue = function visitSetValue(node) {
return setValueNode(node.items.map(visit2(this)).filter(removeNullAndAssertIsNodeFilter(VALUE_NODES)));
};
}
if (keys.includes("someValueNode")) {
visitor.visitSomeValue = function visitSomeValue(node) {
const value = visit2(this)(node.value);
if (value === null) return null;
assertIsNode(value, VALUE_NODES);
return someValueNode(value);
};
}
if (keys.includes("structValueNode")) {
visitor.visitStructValue = function visitStructValue(node) {
return structValueNode(
node.fields.map(visit2(this)).filter(removeNullAndAssertIsNodeFilter("structFieldValueNode"))
);
};
}
if (keys.includes("structFieldValueNode")) {
visitor.visitStructFieldValue = function visitStructFieldValue(node) {
const value = visit2(this)(node.value);
if (value === null) return null;
assertIsNode(value, VALUE_NODES);
return structFieldValueNode(node.name, value);
};
}
if (keys.includes("tupleValueNode")) {
visitor.visitTupleValue = function visitTupleValue(node) {
return tupleValueNode(node.items.map(visit2(this)).filter(removeNullAndAssertIsNodeFilter(VALUE_NODES)));
};
}
if (keys.includes("constantPdaSeedNode")) {
visitor.visitConstantPdaSeed = function visitConstantPdaSeed(node) {
const type = visit2(this)(node.type);
if (type === null) return null;
assertIsNode(type, TYPE_NODES);
const value = visit2(this)(node.value);
if (value === null) return null;
assertIsNode(value, [...VALUE_NODES, "programIdValueNode"]);
return constantPdaSeedNode(type, value);
};
}
if (keys.includes("variablePdaSeedNode")) {
visitor.visitVariablePdaSeed = function visitVariablePdaSeed(node) {
const type = visit2(this)(node.type);
if (type === null) return null;
assertIsNode(type, TYPE_NODES);
return variablePdaSeedNode(node.name, type, node.docs);
};
}
if (keys.includes("resolverValueNode")) {
visitor.visitResolverValue = function visitResolverValue(node) {
const dependsOn = (node.dependsOn ?? []).map(visit2(this)).filter(removeNullAndAssertIsNodeFilter(["accountValueNode", "argumentValueNode"]));
return resolverValueNode(node.name, {
...node,
dependsOn: dependsOn.length === 0 ? void 0 : dependsOn
});
};
}
if (keys.includes("conditionalValueNode")) {
visitor.visitConditionalValue = function visitConditionalValue(node) {
const condition = visit2(this)(node.condition);
if (condition === null) return null;
assertIsNode(condition, ["resolverValueNode", "accountValueNode", "argumentValueNode"]);
const value = node.value ? visit2(this)(node.value) ?? void 0 : void 0;
if (value) assertIsNode(value, VALUE_NODES);
const ifTrue = node.ifTrue ? visit2(this)(node.ifTrue) ?? void 0 : void 0;
if (ifTrue) assertIsNode(ifTrue, INSTRUCTION_INPUT_VALUE_NODES);
const ifFalse = node.ifFalse ? visit2(this)(node.ifFalse) ?? void 0 : void 0;
if (ifFalse) assertIsNode(ifFalse, INSTRUCTION_INPUT_VALUE_NODES);
if (!ifTrue && !ifFalse) return null;
return conditionalValueNode({ condition, ifFalse, ifTrue, value });
};
}
if (keys.includes("pdaValueNode")) {
visitor.visitPdaValue = function visitPdaValue(node) {
const pda = visit2(this)(node.pda);
if (pda === null) return null;
assertIsNode(pda, ["pdaLinkNode", "pdaNode"]);
const seeds = node.seeds.map(visit2(this)).filter(removeNullAndAssertIsNodeFilter("pdaSeedValueNode"));
return pdaValueNode(pda, seeds);
};
}
if (keys.includes("pdaSeedValueNode")) {
visitor.visitPdaSeedValue = function visitPdaSeedValue(node) {
const value = visit2(this)(node.value);
if (value === null) return null;
assertIsNode(value, [...VALUE_NODES, "accountValueNode", "argumentValueNode"]);
return pdaSeedValueNode(node.name, value);
};
}
if (keys.includes("fixedSizeTypeNode")) {
visitor.visitFixedSizeType = function visitFixedSizeType(node) {
const type = visit2(this)(node.type);
if (type === null) return null;
assertIsNode(type, TYPE_NODES);
return fixedSizeTypeNode(type, node.size);
};
}
if (keys.includes("sizePrefixTypeNode")) {
visitor.visitSizePrefixType = function visitSizePrefixType(node) {
const prefix = visit2(this)(node.prefix);
if (prefix === null) return null;
assertIsNestedTypeNode(prefix, "numberTypeNode");
const type = visit2(this)(node.type);
if (type === null) return null;
assertIsNode(type, TYPE_NODES);
return sizePrefixTypeNode(type, prefix);
};
}
if (keys.includes("preOffsetTypeNode")) {
visitor.visitPreOffsetType = function visitPreOffsetType(node) {
const type = visit2(this)(node.type);
if (type === null) return null;
assertIsNode(type, TYPE_NODES);
return preOffsetTypeNode(type, node.offset, node.strategy);
};
}
if (keys.includes("postOffsetTypeNode")) {
visitor.visitPostOffsetType = function visitPostOffsetType(node) {
const type = visit2(this)(node.type);
if (type === null) return null;
assertIsNode(type, TYPE_NODES);
return postOffsetTypeNode(type, node.offset, node.strategy);
};
}
if (keys.includes("sentinelTypeNode")) {
visitor.visitSentinelType = function visitSentinelType(node) {
const sentinel = visit2(this)(node.sentinel);
if (sentinel === null) return null;
assertIsNode(sentinel, "constantValueNode");
const type = visit2(this)(node.type);
if (type === null) return null;
assertIsNode(type, TYPE_NODES);
return sentinelTypeNode(type, sentinel);
};
}
if (keys.includes("hiddenPrefixTypeNode")) {
visitor.visitHiddenPrefixType = function visitHiddenPrefixType(node) {
const type = visit2(this)(node.type);
if (type === null) return null;
assertIsNode(type, TYPE_NODES);
const prefix = node.prefix.map(visit2(this)).filter(removeNullAndAssertIsNodeFilter("constantValueNode"));
if (prefix.length === 0) return type;
return hiddenPrefixTypeNode(type, prefix);
};
}
if (keys.includes("hiddenSuffixTypeNode")) {
visitor.visitHiddenSuffixType = function visitHiddenSuffixType(node) {
const type = visit2(this)(node.type);
if (type === null) return null;
assertIsNode(type, TYPE_NODES);
const suffix = node.suffix.map(visit2(this)).filter(removeNullAndAssertIsNodeFilter("constantValueNode"));
if (suffix.length === 0) return type;
return hiddenSuffixTypeNode(type, suffix);
};
}
if (keys.includes("constantDiscriminatorNode")) {
visitor.visitConstantDiscriminator = function visitConstantDiscriminator(node) {
const constant = visit2(this)(node.constant);
if (constant === null) return null;
assertIsNode(constant, "constantValueNode");
return constantDiscriminatorNode(constant, node.offset);
};
}
if (keys.includes("accountLinkNode")) {
visitor.visitAccountLink = function visitAccountLink(node) {
const program = node.program ? visit2(this)(node.program) ?? void 0 : void 0;
if (program) assertIsNode(program, "programLinkNode");
return accountLinkNode(node.name, program);
};
}
if (keys.includes("definedTypeLinkNode")) {
visitor.visitDefinedTypeLink = function visitDefinedTypeLink(node) {
const program = node.program ? visit2(this)(node.program) ?? void 0 : void 0;
if (program) assertIsNode(program, "programLinkNode");
return definedTypeLinkNode(node.name, program);
};
}
if (keys.includes("instructionLinkNode")) {
visitor.visitInstructionLink = function visitInstructionLink(node) {
const program = node.program ? visit2(this)(node.program) ?? void 0 : void 0;
if (program) assertIsNode(program, "programLinkNode");
return instructionLinkNode(node.name, program);
};
}
if (keys.includes("instructionAccountLinkNode")) {
visitor.visitInstructionAccountLink = function visitInstructionAccountLink(node) {
const instruction = node.instruction ? visit2(this)(node.instruction) ?? void 0 : void 0;
if (instruction) assertIsNode(instruction, "instructionLinkNode");
return instructionAccountLinkNode(node.name, instruction);
};
}
if (keys.includes("instructionArgumentLinkNode")) {
visitor.visitInstructionArgumentLink = function visitInstructionArgumentLink(node) {
const instruction = node.instruction ? visit2(this)(node.instruction) ?? void 0 : void 0;
if (instruction) assertIsNode(instruction, "instructionLinkNode");
return instructionArgumentLinkNode(node.name, instruction);
};
}
if (keys.includes("pdaLinkNode")) {
visitor.visitPdaLink = function visitPdaLink(node) {
const program = node.program ? visit2(this)(node.program) ?? void 0 : void 0;
if (program) assertIsNode(program, "programLinkNode");
return pdaLinkNode(node.name, program);
};
}
return visitor;
}
// src/interceptVisitor.ts
import { REGISTERED_NODE_KINDS as REGISTERED_NODE_KINDS4 } from "@codama/nodes";
function interceptVisitor(visitor, interceptor) {
const registeredVisitFunctions = REGISTERED_NODE_KINDS4.map(getVisitFunctionName);
return Object.fromEntries(
Object.keys(visitor).flatMap((key) => {
const castedKey = key;
if (!registeredVisitFunctions.includes(castedKey)) {
return [];
}
return [
[
castedKey,
function interceptedVisitNode(node) {
const baseFunction = visitor[castedKey];
return interceptor(node, baseFunction.bind(this));
}
]
];
})
);
}
// src/NodeSelector.ts
import { camelCase } from "@codama/nodes";
var getNodeSelectorFunction = (selector) => {
if (typeof selector === "function") return selector;
const checkNode = (node, nodeSelector) => {
if (nodeSelector === "*") return true;
const matches = nodeSelector.match(/^(?:\[([^\]]+)\])?(.*)?$/);
if (!matches) return false;
const [, kinds, name] = matches;
const kindArray = kinds ? kinds.split("|").map(camelCase) : [];
if (kindArray.length > 0 && !kindArray.includes(node.kind)) {
return false;
}
if (name && (!("name" in node) || camelCase(name) !== node.name)) {
return false;
}
return true;
};
const checkPath = (path, nodeSelectors2) => {
if (nodeSelectors2.length === 0) return true;
if (path.length === 0) return false;
const lastNode = path.pop();
const lastNodeSelector = nodeSelectors2.pop();
return checkNode(lastNode, lastNodeSelector) ? checkPath(path, nodeSelectors2) : checkPath(path, [...nodeSelectors2, lastNodeSelector]);
};
const checkInitialPath = (path, nodeSelectors2) => {
if (nodeSelectors2.length === 0 || path.length === 0) return false;
const lastNode = path.pop();
const lastNodeSelector = nodeSelectors2.pop();
return checkNode(lastNode, lastNodeSelector) && checkPath(path, nodeSelectors2);
};
const nodeSelectors = selector.split(".");
return (path) => checkInitialPath([...path], [...nodeSelectors]);
};
var getConjunctiveNodeSelectorFunction = (selector) => {
const selectors = Array.isArray(selector) ? selector : [selector];
const selectorFunctions = selectors.map(getNodeSelectorFunction);
return (path) => selectorFunctions.every((fn) => fn(path));
};
// src/NodeStack.ts
import { CODAMA_ERROR__VISITORS__CANNOT_REMOVE_LAST_PATH_IN_NODE_STACK, CodamaError as CodamaError2 } from "@codama/errors";
// src/NodePath.ts
import { assertIsNode as assertIsNode2, isNode } from "@codama/nodes";
function getLastNodeFromPath(path) {
return path[path.length - 1];
}
function findFirstNodeFromPath(path, kind) {
return path.find((node) => isNode(node, kind));
}
function findLastNodeFromPath(path, kind) {
for (let index = path.length - 1; index >= 0; index--) {
const node = path[index];
if (isNode(node, kind)) return node;
}
return void 0;
}
function findProgramNodeFromPath(path) {
return findLastNodeFromPath(path, "programNode");
}
function findInstructionNodeFromPath(path) {
return findLastNodeFromPath(path, "instructionNode");
}
function getNodePathUntilLastNode(path, kind) {
const lastIndex = (() => {
for (let index = path.length - 1; index >= 0; index--) {
const node = path[index];
if (isNode(node, kind)) return index;
}
return -1;
})();
if (lastIndex === -1) return void 0;
return path.slice(0, lastIndex + 1);
}
function isFilledNodePath(path) {
return !!path && path.length > 0;
}
function isNodePath(path, kind) {
return isNode(isFilledNodePath(path) ? getLastNodeFromPath(path) : null, kind);
}
function assertIsNodePath(path, kind) {
assertIsNode2(isFilledNodePath(path) ? getLastNodeFromPath(path) : null, kind);
}
function nodePathToStringArray(path) {
return path.map((node) => {
return "name" in node ? `[${node.kind}]${node.name}` : `[${node.kind}]`;
});
}
function nodePathToString(path) {
return nodePathToStringArray(path).join(" > ");
}
// src/NodeStack.ts
var NodeStack = class _NodeStack {
/**
* Contains all the node paths saved during the traversal.
*
* - The very last path is the current path which is being
* used during the traversal.
* - The other paths can be used to save and restore the
* current path when jumping to different parts of the tree.
*
* There must at least be one path in the stack at all times.
*/
stack;
constructor(...stack) {
this.stack = stack.length === 0 ? [[]] : [...stack.map((nodes) => [...nodes])];
}
get currentPath() {
return this.stack[this.stack.length - 1];
}
push(node) {
this.currentPath.push(node);
}
pop() {
return this.currentPath.pop();
}
peek() {
return this.isEmpty() ? void 0 : this.currentPath[this.currentPath.length - 1];
}
pushPath(newPath = []) {
this.stack.push([...newPath]);
}
popPath() {
if (this.stack.length <= 1) {
throw new CodamaError2(CODAMA_ERROR__VISITORS__CANNOT_REMOVE_LAST_PATH_IN_NODE_STACK, {
path: [...this.stack[this.stack.length - 1]]
});
}
return [...this.stack.pop()];
}
getPath(kind) {
const path = [...this.currentPath];
if (kind) {
assertIsNodePath(path, kind);
}
return path;
}
isEmpty() {
return this.currentPath.length === 0;
}
clone() {
return new _NodeStack(...this.stack);
}
toString() {
return nodePathToString(this.getPath());
}
};
// src/pipe.ts
function pipe(init, ...fns) {
return fns.reduce((acc, fn) => fn(acc), init);
}
// src/recordNodeStackVisitor.ts
function recordNodeStackVisitor(visitor, stack) {
return interceptVisitor(visitor, (node, next) => {
stack.push(node);
const newNode = next(node);
stack.pop();
return newNode;
});
}
// src/bottomUpTransformerVisitor.ts
function bottomUpTransformerVisitor(transformers, options = {}) {
const transformerFunctions = transformers.map((transformer) => {
if (typeof transformer === "function") return transformer;
return (node, stack2) => getConjunctiveNodeSelectorFunction(transformer.select)(stack2.getPath()) ? transformer.transform(node, stack2) : node;
});
const stack = options.stack ?? new NodeStack();
return pipe(
identityVisitor(options),
(v) => interceptVisitor(v, (node, next) => {
return transformerFunctions.reduce(
(acc, transformer) => acc === null ? null : transformer(acc, stack),
next(node)
);
}),
(v) => recordNodeStackVisitor(v, stack)
);
}
// src/mapVisitor.ts
import { REGISTERED_NODE_KINDS as REGISTERED_NODE_KINDS5 } from "@codama/nodes";
function mapVisitor(visitor, map) {
const registeredVisitFunctions = REGISTERED_NODE_KINDS5.map(getVisitFunctionName);
return Object.fromEntries(
Object.keys(visitor).flatMap((key) => {
const castedKey = key;
if (!registeredVisitFunctions.includes(castedKey)) {
return [];
}
return [
[
castedKey,
(node) => map(visitor[castedKey](node))
]
];
})
);
}
// src/consoleLogVisitor.ts
function consoleLogVisitor(visitor) {
return mapVisitor(visitor, (value) => console.log(value));
}
// src/topDownTransformerVisitor.ts
function topDownTransformerVisitor(transformers, options = {}) {
const transformerFunctions = transformers.map((transformer) => {
if (typeof transformer === "function") return transformer;
return (node, stack2) => getConjunctiveNodeSelectorFunction(transformer.select)(stack2.getPath()) ? transformer.transform(node, stack2) : node;
});
const stack = options.stack ?? new NodeStack();
return pipe(
identityVisitor(options),
(v) => interceptVisitor(v, (node, next) => {
const appliedNode = transformerFunctions.reduce(
(acc, transformer) => acc === null ? null : transformer(acc, stack),
node
);
if (appliedNode === null) return null;
return next(appliedNode);
}),
(v) => recordNodeStackVisitor(v, stack)
);
}
// src/deleteNodesVisitor.ts
function deleteNodesVisitor(selectors, options) {
return topDownTransformerVisitor(
selectors.map(
(selector) => ({
select: selector,
transform: () => null
})
),
options
);
}
// src/extendVisitor.ts
import { CODAMA_ERROR__VISITORS__CANNOT_EXTEND_MISSING_VISIT_FUNCTION, CodamaError as CodamaError3 } from "@codama/errors";
import { REGISTERED_NODE_KINDS as REGISTERED_NODE_KINDS6 } from "@codama/nodes";
function extendVisitor(visitor, overrides) {
const registeredVisitFunctions = REGISTERED_NODE_KINDS6.map(getVisitFunctionName);
const overriddenFunctions = Object.fromEntries(
Object.keys(overrides).flatMap((key) => {
if (!registeredVisitFunctions.includes(key)) {
return [];
}
const castedKey = key;
if (!visitor[castedKey]) {
throw new CodamaError3(CODAMA_ERROR__VISITORS__CANNOT_EXTEND_MISSING_VISIT_FUNCTION, {
visitFunction: castedKey
});
}
return [
[
castedKey,
function extendedVisitNode(node) {
const extendedFunction = overrides[castedKey];
const nextFunction = visitor[castedKey];
return extendedFunction.bind(this)(node, {
next: nextFunction.bind(this),
self: this
});
}
]
];
})
);
return {
...visitor,
...overriddenFunctions
};
}
// src/getByteSizeVisitor.ts
import { isNode as isNode2, isScalarEnum, REGISTERED_TYPE_NODE_KINDS } from "@codama/nodes";
// src/mergeVisitor.ts
import { getAllPrograms, REGISTERED_NODE_KINDS as REGISTERED_NODE_KINDS7 } from "@codama/nodes";
function mergeVisitor(leafValue, merge, options = {}) {
const keys = options.keys ?? REGISTERED_NODE_KINDS7;
const visitor = staticVisitor(leafValue, { keys });
const visit2 = (v) => (node) => keys.includes(node.kind) ? [visit(node, v)] : [];
if (keys.includes("rootNode")) {
visitor.visitRoot = function visitRoot(node) {
return merge(node, getAllPrograms(node).flatMap(visit2(this)));
};
}
if (keys.includes("programNode")) {
visitor.visitProgram = function visitProgram(node) {
return merge(node, [
...node.pdas.flatMap(visit2(this)),
...node.accounts.flatMap(visit2(this)),
...node.instructions.flatMap(visit2(this)),
...node.definedTypes.flatMap(visit2(this)),
...node.errors.flatMap(visit2(this))
]);
};
}
if (keys.includes("pdaNode")) {
visitor.visitPda = function visitPda(node) {
return merge(node, node.seeds.flatMap(visit2(this)));
};
}
if (keys.includes("accountNode")) {
visitor.visitAccount = function visitAccount(node) {
return merge(node, [
...visit2(this)(node.data),
...node.pda ? visit2(this)(node.pda) : [],
...(node.discriminators ?? []).flatMap(visit2(this))
]);
};
}
if (keys.includes("instructionNode")) {
visitor.visitInstruction = function visitInstruction(node) {
return merge(node, [
...node.accounts.flatMap(visit2(this)),
...node.arguments.flatMap(visit2(this)),
...(node.extraArguments ?? []).flatMap(visit2(this)),
...(node.remainingAccounts ?? []).flatMap(visit2(this)),
...(node.byteDeltas ?? []).flatMap(visit2(this)),
...(node.discriminators ?? []).flatMap(visit2(this)),
...(node.subInstructions ?? []).flatMap(visit2(this))
]);
};
}
if (keys.includes("instructionAccountNode")) {
visitor.visitInstructionAccount = function visitInstructionAccount(node) {
return merge(node, [...node.defaultValue ? visit2(this)(node.defaultValue) : []]);
};
}
if (keys.includes("instructionArgumentNode")) {
visitor.visitInstructionArgument = function visitInstructionArgument(node) {
return merge(node, [
...visit2(this)(node.type),
...node.defaultValue ? visit2(this)(node.defaultValue) : []
]);
};
}
if (keys.includes("instructionRemainingAccountsNode")) {
visitor.visitInstructionRemainingAccounts = function visitInstructionRemainingAccounts(node) {
return merge(node, visit2(this)(node.value));
};
}
if (keys.includes("instructionByteDeltaNode")) {
visitor.visitInstructionByteDelta = function visitInstructionByteDelta(node) {
return merge(node, visit2(this)(node.value));
};
}
if (keys.includes("definedTypeNode")) {
visitor.visitDefinedType = function visitDefinedType(node) {
return merge(node, visit2(this)(node.type));
};
}
if (keys.includes("arrayTypeNode")) {
visitor.visitArrayType = function visitArrayType(node) {
return merge(node, [...visit2(this)(node.count), ...visit2(this)(node.item)]);
};
}
if (keys.includes("enumTypeNode")) {
visitor.visitEnumType = function visitEnumType(node) {
return merge(node, [...visit2(this)(node.size), ...node.variants.flatMap(visit2(this))]);
};
}
if (keys.includes("enumStructVariantTypeNode")) {
visitor.visitEnumStructVariantType = function visitEnumStructVariantType(node) {
return merge(node, visit2(this)(node.struct));
};
}
if (keys.includes("enumTupleVariantTypeNode")) {
visitor.visitEnumTupleVariantType = function visitEnumTupleVariantType(node) {
return merge(node, visit2(this)(node.tuple));
};
}
if (keys.includes("mapTypeNode")) {
visitor.visitMapType = function visitMapType(node) {
return merge(node, [...visit2(this)(node.count), ...visit2(this)(node.key), ...visit2(this)(node.value)]);
};
}
if (keys.includes("optionTypeNode")) {
visitor.visitOptionType = function visitOptionType(node) {
return merge(node, [...visit2(this)(node.prefix), ...visit2(this)(node.item)]);
};
}
if (keys.includes("zeroableOptionTypeNode")) {
visitor.visitZeroableOptionType = function visitZeroableOptionType(node) {
return merge(node, [...visit2(this)(node.item), ...node.zeroValue ? visit2(this)(node.zeroValue) : []]);
};
}
if (keys.includes("remainderOptionTypeNode")) {
visitor.visitRemainderOptionType = function visitRemainderOptionType(node) {
return merge(node, visit2(this)(node.item));
};
}
if (keys.includes("booleanTypeNode")) {
visitor.visitBooleanType = function visitBooleanType(node) {
return merge(node, visit2(this)(node.size));
};
}
if (keys.includes("setTypeNode")) {
visitor.visitSetType = function visitSetType(node) {
return merge(node, [...visit2(this)(node.count), ...visit2(this)(node.item)]);
};
}
if (keys.includes("structTypeNode")) {
visitor.visitStructType = function visitStructType(node) {
return merge(node, node.fields.flatMap(visit2(this)));
};
}
if (keys.includes("structFieldTypeNode")) {
visitor.visitStructFieldType = function visitStructFieldType(node) {
return merge(node, [
...visit2(this)(node.type),
...node.defaultValue ? visit2(this)(node.defaultValue) : []
]);
};
}
if (keys.includes("tupleTypeNode")) {
visitor.visitTupleType = function visitTupleType(node) {
return merge(node, node.items.flatMap(visit2(this)));
};
}
if (keys.includes("amountTypeNode")) {
visitor.visitAmountType = function visitAmountType(node) {
return merge(node, visit2(this)(node.number));
};
}
if (keys.includes("dateTimeTypeNode")) {
visitor.visitDateTimeType = function visitDateTimeType(node) {
return merge(node, visit2(this)(node.number));
};
}
if (keys.includes("solAmountTypeNode")) {
visitor.visitSolAmountType = function visitSolAmountType(node) {
return merge(node, visit2(this)(node.number));
};
}
if (keys.includes("prefixedCountNode")) {
visitor.visitPrefixedCount = function visitPrefixedCount(node) {
return merge(node, visit2(this)(node.prefix));
};
}
if (keys.includes("arrayValueNode")) {
visitor.visitArrayValue = function visitArrayValue(node) {
return merge(node, node.items.flatMap(visit2(this)));
};
}
if (keys.includes("constantValueNode")) {
visitor.visitConstantValue = function visitConstantValue(node) {
return merge(node, [...visit2(this)(node.type), ...visit2(this)(node.value)]);
};
}
if (keys.includes("enumValueNode")) {
visitor.visitEnumValue = function visitEnumValue(node) {
return merge(node, [...visit2(this)(node.enum), ...node.value ? visit2(this)(node.value) : []]);
};
}
if (keys.includes("mapValueNode")) {
visitor.visitMapValue = function visitMapValue(node) {
return merge(node, node.entries.flatMap(visit2(this)));
};
}
if (keys.includes("mapEntryValueNode")) {
visitor.visitMapEntryValue = function visitMapEntryValue(node) {
return merge(node, [...visit2(this)(node.key), ...visit2(this)(node.value)]);
};
}
if (keys.includes("setValueNode")) {
visitor.visitSetValue = function visitSetValue(node) {
return merge(node, node.items.flatMap(visit2(this)));
};
}
if (keys.includes("someValueNode")) {
visitor.visitSomeValue = function visitSomeValue(node) {
return merge(node, visit2(this)(node.value));
};
}
if (keys.includes("structValueNode")) {
visitor.visitStructValue = function visitStructValue(node) {
return merge(node, node.fields.flatMap(visit2(this)));
};
}
if (keys.includes("structFieldValueNode")) {
visitor.visitStructFieldValue = function visitStructFieldValue(node) {
return merge(node, visit2(this)(node.value));
};
}
if (keys.includes("tupleValueNode")) {
visitor.visitTupleValue = function visitTupleValue(node) {
return merge(node, node.items.flatMap(visit2(this)));
};
}
if (keys.includes("constantPdaSeedNode")) {
visitor.visitConstantPdaSeed = function visitConstantPdaSeed(node) {
return merge(node, [...visit2(this)(node.type), ...visit2(this)(node.value)]);
};
}
if (keys.includes("variablePdaSeedNode")) {
visitor.visitVariablePdaSeed = function visitVariablePdaSeed(node) {
return merge(node, visit2(this)(node.type));
};
}
if (keys.includes("resolverValueNode")) {
visitor.visitResolverValue = function visitResolverValue(node) {
return merge(node, (node.dependsOn ?? []).flatMap(visit2(this)));
};
}
if (keys.includes("conditionalValueNode")) {
visitor.visitConditionalValue = function visitConditionalValue(node) {
return merge(node, [
...visit2(this)(node.condition),
...node.value ? visit2(this)(node.value) : [],
...node.ifTrue ? visit2(this)(node.ifTrue) : [],
...node.ifFalse ? visit2(this)(node.ifFalse) : []
]);
};
}
if (keys.includes("pdaValueNode")) {
visitor.visitPdaValue = function visitPdaValue(node) {
return merge(node, [...visit2(this)(node.pda), ...node.seeds.flatMap(visit2(this))]);
};
}
if (keys.includes("pdaSeedValueNode")) {
visitor.visitPdaSeedValue = function visitPdaSeedValue(node) {
return merge(node, visit2(this)(node.value));
};
}
if (keys.includes("fixedSizeTypeNode")) {
visitor.visitFixedSizeType = function visitFixedSizeType(node) {
return merge(node, visit2(this)(node.type));
};
}
if (keys.includes("sizePrefixTypeNode")) {
visitor.visitSizePrefixType = function visitSizePrefixType(node) {
return merge(node, [...visit2(this)(node.prefix), ...visit2(this)(node.type)]);
};
}
if (keys.includes("preOffsetTypeNode")) {
visitor.visitPreOffsetType = function visitPreOffsetType(node) {
return merge(node, visit2(this)(node.type));
};
}
if (keys.includes("postOffsetTypeNode")) {
visitor.visitPostOffsetType = function visitPostOffsetType(node) {
return merge(node, visit2(this)(node.type));
};
}
if (keys.includes("sentinelTypeNode")) {
visitor.visitSentinelType = function visitSentinelType(node) {
return merge(node, [...visit2(this)(node.sentinel), ...visit2(this)(node.type)]);
};
}
if (keys.includes("hiddenPrefixTypeNode")) {
visitor.visitHiddenPrefixType = function visitHiddenPrefixType(node) {
return merge(node, [...node.prefix.flatMap(visit2(this)), ...visit2(this)(node.type)]);
};
}
if (keys.includes("hiddenSuffixTypeNode")) {
visitor.visitHiddenSuffixType = function visitHiddenSuffixType(node) {
return merge(node, [...visit2(this)(node.type), ...node.suffix.flatMap(visit2(this))]);
};
}
if (keys.includes("constantDiscriminatorNode")) {
visitor.visitConstantDiscriminator = function visitConstantDiscriminator(node) {
return merge(node, visit2(this)(node.constant));
};
}
if (keys.includes("accountLinkNode")) {
visitor.visitAccountLink = function visitAccountLink(node) {
return merge(node, node.program ? visit2(this)(node.program) : []);
};
}
if (keys.includes("definedTypeLinkNode")) {
visitor.visitDefinedTypeLink = function visitDefinedTypeLink(node) {
return merge(node, node.program ? visit2(this)(node.program) : []);
};
}
if (keys.includes("instructionLinkNode")) {
visitor.visitInstructionLink = function visitInstructionLink(node) {
return merge(node, node.program ? visit2(this)(node.program) : []);
};
}
if (keys.includes("instructionAccountLinkNode")) {
visitor.visitInstructionAccountLink = function visitInstructionAccountLink(node) {
return merge(node, node.instruction ? visit2(this)(node.instruction) : []);
};
}
if (keys.includes("instructionArgumentLinkNode")) {
visitor.visitInstructionArgumentLink = function visitInstructionArgumentLink(node) {
return merge(node, node.instruction ? visit2(this)(node.instruction) : []);
};
}
if (keys.includes("pdaLinkNode")) {
visitor.visitPdaLink = function visitPdaLink(node) {
return merge(node, node.program ? visit2(this)(node.program) : []);
};
}
return visitor;
}
// src/getByteSizeVisitor.ts
function getByteSizeVisitor(linkables, options = {}) {
const stack = options.stack ?? new NodeStack();
const visitedDefinedTypes = /* @__PURE__ */ new Map();
const definedTypeStack = [];
const sumSizes = (values) => values.reduce((all, one) => all === null || one === null ? null : all + one, 0);
const baseVisitor = mergeVisitor(
() => null,
(_, values) => sumSizes(values),
{
keys: [
...REGISTERED_TYPE_NODE_KINDS,
"definedTypeLinkNode",
"definedTypeNode",
"accountNode",
"instructionNode",
"instructionArgumentNode"
]
}
);
return pipe(
baseVisitor,
(v) => extendVisitor(v, {
visitAccount(node, { self }) {
return visit(node.data, self);
},
visitArrayType(node, { self }) {
if (!isNode2(node.count, "fixedCountNode")) return null;
const count = node.count.value;
if (count === 0) return 0;
const itemSize = visit(node.item, self);
return itemSize !== null ? itemSize * count : null;
},
visitDefinedType(node, { self }) {
if (visitedDefinedTypes.has(node.name)) {
return visitedDefinedTypes.get(node.name);
}
definedTypeStack.push(node.name);
const child = visit(node.type, self);
definedTypeStack.pop();
visitedDefinedTypes.set(node.name, child);
return child;
},
visitDefinedTypeLink(node, { self }) {
const linkedDefinedPath = linkables.getPath(stack.getPath(node.kind));
if (!linkedDefinedPath) return null;
const linkedDefinedType = getLastNodeFromPath(linkedDefinedPath);
if (definedTypeStack.includes(linkedDefinedType.name)) {
return null;
}
stack.pushPath(linkedDefinedPath);
const result = visit(linkedDefinedType, self);
stack.popPath();
return result;
},
visitEnumEmptyVariantType() {
return 0;
},
visitEnumType(node, { self }) {
const prefix = visit(node.size, self) ?? 1;
if (isScalarEnum(node)) return prefix;
const variantSizes = node.variants.map((v2) => visit(v2, self));
const allVariantHaveTheSameFixedSize = variantSizes.every((one, _, all) => one === all[0]);
return allVariantHaveTheSameFixedSize && variantSizes.length > 0 && variantSizes[0] !== null ? variantSizes[0] + prefix : null;
},
visitFixedSizeType(node) {
return node.size;
},
visitInstruction(node, { self }) {
return sumSizes(node.arguments.map((arg) => visit(arg, self)));
},
visitInstructionArgument(node, { self }) {
return visit(node.type, self);
},
visitMapType(node, { self }) {
if (!isNode2(node.count, "fixedCountNo