import { STWriter } from "./STWriter.js"; import { ST } from "./ST.js"; import { InstanceScope } from "./InstanceScope.js"; import { IErrorManager, IInstanceScope, IST, ISTGroup } from "./compiler/common.js"; export declare enum InterpreterOption { ANCHOR = 0, FORMAT = 1, NULL = 2, SEPARATOR = 3, WRAP = 4 } /** * This class knows how to execute template byte codes relative to a particular * {@link STGroup}. To execute the byte codes, we need an output stream and a * reference to an {@link ST} instance. That instance's {@link ST#impl} field * points at a {@link CompiledST}, which contains all of the byte codes and * other information relevant to execution. *

* This interpreter is a stack-based bytecode interpreter. All operands go onto * an operand stack.

*

* If {@link #debug} set, we track interpreter events. For now, I am only * tracking instance creation events. These are used by {@link STViz} to pair up * output chunks with the template expressions that generate them.

*

* We create a new interpreter for each invocation of * {@link ST#render}, {@link ST#inspect}, or {@link ST#getEvents}.

*/ export declare class Interpreter { static readonly DEFAULT_OPERAND_STACK_SIZE = 100; static readonly predefinedAnonSubtemplateAttributes: Set; static readonly supportedOptions: Map; /** * Dump bytecode instructions as they are executed. This field is mostly for * StringTemplate development. */ static trace: boolean; /** Operand stack, grows upwards. */ protected operands: unknown[]; /** Stack pointer register. */ protected sp: number; /** The number of characters written on this template line so far. */ protected charsWrittenOnLine: number; /** * Render template with respect to this group. * * @see ST#groupThatCreatedThisInstance * @see CompiledST#nativeGroup */ protected group: ISTGroup; /** For renderers, we have to pass in the locale. */ protected locale: Intl.Locale; protected errMgr: IErrorManager; /** If {@link #trace} is {@code true}, track trace here. */ protected executeTrace: string[]; constructor(group: ISTGroup); constructor(group: ISTGroup, locale: Intl.Locale); constructor(group: ISTGroup, errMgr: IErrorManager); constructor(group: ISTGroup, locale: Intl.Locale, errMgr: IErrorManager); /** * If an instance of x is enclosed in a y which is in a * z, return a {@code String} of these instance names in order from * topmost to lowest; here that would be {@code [z y x]}. * @param scope */ static getEnclosingInstanceStackString(scope?: InstanceScope): string; static getEnclosingInstanceStack(scope: InstanceScope | undefined, topDown: boolean): ST[]; static getScopeStack(scope: InstanceScope, topDown: boolean): InstanceScope[]; static getShort(memory: Int8Array, index: number): number; /** * Execute template {@code self} and return how many characters it wrote to {@code out}. * * @returns the number of characters written to {@code out} */ exec(out: STWriter, scope: InstanceScope): number; /** * Return the first attribute if multi-valued, or the attribute itself if single-valued. *

* This method is used for rendering expressions of the form * {@code }.

*/ first(scope: InstanceScope, v: unknown): unknown; /** * Return the last attribute if multi-valued, or the attribute itself if * single-valued. Unless it's a `List` or array, this is pretty slow * as it iterates until the last element. *

* This method is used for rendering expressions of the form * {@code }.

*/ last(scope: InstanceScope, v: unknown): unknown; /** * Return everything but the first attribute if multi-valued, or * {@code null} if single-valued. */ rest(scope: InstanceScope, v: unknown): unknown; /** * Return all but the last element. trunc(x)==null if x is single-valued. */ trunc(scope: InstanceScope, v: unknown): unknown; /** * Return a new list without {@code null} values. */ strip(scope: InstanceScope, v: unknown): unknown; /** * Return a list with the same elements as {@code v} but in reverse order. *

* Note that {@code null} values are not stripped out; use * {@code reverse(strip(v))} to do that.

*/ reverse(scope: InstanceScope, v: unknown): unknown; /** * Return the length of a multi-valued attribute or 1 if it is a single * attribute. If {@code v} is {@code null} return 0. *

* The implementation treats several common collections and arrays as * special cases for speed.

*/ length(v: unknown): number; convertAnythingIteratableToIterator(scope: InstanceScope | null, o: unknown): unknown; convertAnythingToIterator(scope: InstanceScope, o: unknown): Iterator; /** * Find an attribute via dynamic scoping up enclosing scope chain. Only look * for a dictionary definition if the attribute is not found, so attributes * sent in to a template override dictionary names. *

* Return {@link ST#EMPTY_ATTR} if found definition but no value.

*/ getAttribute(scope: InstanceScope, name: string): unknown; getDictionary(g: ISTGroup, name: string): unknown; /** * Set any default argument values that were not set by the invoking * template or by {@link ST#add} directly. Note that the default values may * be templates. *

* The evaluation context is the {@code invokedST} template itself so * template default arguments can see other arguments.

*/ setDefaultArguments(out: STWriter, scope: InstanceScope): void; getExecutionTrace(): string[]; protected _exec(out: STWriter, scope: InstanceScope): number; protected loadStr(self: ST, ip: number): void; protected superNew(scope: InstanceScope, name: string, argCountOrAttributes: number | Map): void; protected passthru(scope: InstanceScope, templateName: string, attrs: Map): void; protected storeArgs(scope: IInstanceScope, attrs: Map, st?: IST): void; protected storeArgs(scope: IInstanceScope, argCount: number, st?: IST): void; protected indent(out: STWriter, scope: InstanceScope, strIndex: number): void; /** * Write out an expression result that doesn't use expression options. * E.g., {@code } */ protected writeObjectNoOptions(out: STWriter, scope: InstanceScope, o: unknown): number; /** * Write out an expression result that uses expression options. * E.g., {@code } */ protected writeObjectWithOptions(out: STWriter, scope: InstanceScope, o: unknown, options: unknown[]): number; /** * Generic method to emit text for an object. It differentiates * between templates, iterable objects, and plain old Java objects (POJOs) */ protected writeObject(out: STWriter, scope: InstanceScope, o: unknown, options?: Array): number; protected writeIterator(out: STWriter, scope: InstanceScope, it?: Iterator, options?: Array): number; protected writePOJO(out: STWriter, scope: InstanceScope, o: unknown, options?: Array): number; protected getExprStartChar(scope: InstanceScope): number; protected getExprStopChar(scope: InstanceScope): number; protected map(scope: InstanceScope, attr: unknown, st: IST): void; /** * Renders expressions of the form {@code } or * {@code }. */ protected rotMap(scope: InstanceScope, attr: unknown, prototypes: IST[]): void; protected rotateMapIterator(scope: InstanceScope, attr: Iterator, prototypes: IST[]): Array; /** * Renders expressions of the form {@code } or * {@code }. */ protected zipMap(scope: InstanceScope, exprs: unknown[], prototype?: IST): IST[] | undefined; protected setFirstArgument(scope: InstanceScope, st: IST, attr: unknown): void; protected addToList(scope: InstanceScope, list: unknown[], o: unknown): void; protected toString(out: STWriter, scope: InstanceScope, value: unknown): string | null; protected testAttributeTrue(a: unknown): boolean; protected getObjectProperty(out: STWriter, scope: InstanceScope, o: unknown, property: unknown): unknown; protected writeTrace(scope: InstanceScope, ip: number): void; protected printForTrace(tr: string, scope: InstanceScope, o: unknown): string; private renderObject; }