🚀 Socket Launch Week Day 5:Introducing Repository Access Permissions and Custom Roles.Learn more
Sign In

@traqula/core

Package Overview
Dependencies
Maintainers
2
Versions
44
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@traqula/core - npm Package Compare versions

Comparing version
1.0.2
to
1.0.3
+87
-1
dist/cjs/lib/AstCoreFactory.js

@@ -5,2 +5,7 @@ "use strict";

class AstCoreFactory {
/**
* Whether this AstFactory will track source location. Default: true.
* In case source location is not tracked,
* each generated node using this factory will be {@link SourceLocationNodeAutoGenerate}
*/
tracksSourceLocation;

@@ -10,5 +15,14 @@ constructor(args = {}) {

}
/**
* Wrap any type into an object that tracks the source location of tha value.
* @param val the value to wrap
* @param loc the source location for that value
*/
wrap(val, loc) {
return { val, loc };
}
/**
* Whether the provided value is an object that tracks source location.
* @param obj
*/
isLocalized(obj) {

@@ -18,2 +32,6 @@ return typeof obj === 'object' && obj !== null && 'loc' in obj &&

}
/**
* Compute the source location of an element based on the elements it contains.
* The provided arguments should be in order of occurrence in the string.
*/
sourceLocation(...elements) {

@@ -44,2 +62,5 @@ if (!this.tracksSourceLocation) {

}
/**
* Generate a source location indicating the no materialization.
*/
sourceLocationNoMaterialize() {

@@ -57,2 +78,9 @@ if (!this.tracksSourceLocation) {

}
/**
* Given a value and some mapper from objects to objects,
* map all containing items in case it is an array,
* otherwise map the provided value in case it is an object, finally, do nothing.
* @param value the value to map
* @param mapper the function mapping an object to another object.
*/
safeObjectTransform(value, mapper) {

@@ -68,2 +96,6 @@ if (value && typeof value === 'object') {

}
/**
* Given a (AST) tree, return a copy of that tree where it and it's
* descendents all have a {@link SourceLocationNodeAutoGenerate} localization.
*/
forcedAutoGenTree(obj) {

@@ -79,2 +111,5 @@ const copy = { ...obj };

}
/**
* In case the provided Node is not yet materialized, force it to be autoGenerated.
*/
forceMaterialized(arg) {

@@ -86,5 +121,12 @@ if (this.isSourceLocationNoMaterialize(arg.loc)) {

}
/**
* Check whether an object is in fact a {@link SourceLocation}.
* @param loc
*/
isSourceLocation(loc) {
return 'sourceLocationType' in loc;
}
/**
* Create a {@link SourceLocation} that indicates what range of characters this node represents in the source string.
*/
sourceLocationSource(start, end) {

@@ -98,3 +140,4 @@ return {

/**
* {@inheritDoc SourceLocationInlinedSource}
* Create a {@link SourceLocation} that indicates a given range of the current range should be replaced by
* a new source.
*/

@@ -120,11 +163,24 @@ sourceLocationInlinedSource(newSource, subLoc, start, end, startOnNew = 0, endOnNew = newSource.length) {

;
/**
* Guard to check if an object is a {@link SourceLocation} of type {@link SourceLocationInlinedSource}.
*/
isSourceLocationInlinedSource(loc) {
return this.isSourceLocation(loc) && loc.sourceLocationType === 'inlinedSource';
}
/**
* Create a {@link SourceLocation} indicating the node should be autoGenerated by a generator.
*/
gen() {
return { sourceLocationType: 'autoGenerate' };
}
/**
* Guard to check if an object is a {@link SourceLocation} of type {@link SourceLocationSource}.
*/
isSourceLocationSource(loc) {
return this.isSourceLocation(loc) && loc.sourceLocationType === 'source';
}
/**
* Create a {@link SourceLocation} that indicates this node,
* representing a range of characters in the original string, should be replaced by some string during generation.
*/
sourceLocationStringReplace(newSource, start, end) {

@@ -136,5 +192,13 @@ if (!this.tracksSourceLocation) {

}
/**
* Guard to check if an object is a {@link SourceLocation} of type {@link SourceLocationStringReplace}.
* @param loc
*/
isSourceLocationStringReplace(loc) {
return this.isSourceLocation(loc) && loc.sourceLocationType === 'stringReplace';
}
/**
* Given a sourceLocation, generate a new {@link SourceLocation}
* that indicates the range of the given location should now be autoGenerated
*/
sourceLocationNodeReplaceUnsafe(loc) {

@@ -166,8 +230,17 @@ if (this.isSourceLocationSource(loc)) {

}
/**
* Guard to check if an object is a {@link SourceLocation} of type {@link SourceLocationNodeReplace}.
*/
isSourceLocationNodeReplace(loc) {
return this.isSourceLocation(loc) && loc.sourceLocationType === 'nodeReplace';
}
/**
* Guard to check if an object is a {@link SourceLocation} of type {@link SourceLocationNodeAutoGenerate}.
*/
isSourceLocationNodeAutoGenerate(loc) {
return this.isSourceLocation(loc) && loc.sourceLocationType === 'autoGenerate';
}
/**
* Check whether the provided {@link SourceLocation} expects the generator to autoGenerate.
*/
isPrintingLoc(loc) {

@@ -178,2 +251,6 @@ return this.isSourceLocationNodeReplace(loc) ||

}
/**
* A simple filter that will only execute the provided callback when the provided {@link SourceLocation}
* expects the generator steps to autoGenerate.
*/
printFilter(node, callback) {

@@ -184,5 +261,11 @@ if (this.isPrintingLoc(node.loc)) {

}
/**
* Guard to check if an object is a {@link SourceLocation} of type {@link SourceLocationNoMaterialize}.
*/
isSourceLocationNoMaterialize(loc) {
return this.isSourceLocation(loc) && loc.sourceLocationType === 'noMaterialize';
}
/**
* Guard to check if an object is the specified Type: {@link Typed}.
*/
isOfType(obj, type) {

@@ -192,2 +275,5 @@ const casted = obj;

}
/**
* Guard to check if an object is the specified Type: {@link SubTyped}.
*/
isOfSubType(obj, type, subType) {

@@ -194,0 +280,0 @@ const temp = obj;

+1
-1

@@ -1,1 +0,1 @@

{"version":3,"file":"AstCoreFactory.js","sourceRoot":"","sources":["../../../lib/AstCoreFactory.ts"],"names":[],"mappings":"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","sourcesContent":["import type { IToken } from '@traqula/chevrotain';\n\nimport type {\n SourceLocation,\n SourceLocationNodeAutoGenerate,\n SourceLocationNodeReplace,\n SourceLocationNoMaterialize,\n SourceLocationSource,\n SourceLocationStringReplace,\n Node,\n Localized,\n Wrap,\n Typed,\n SubTyped,\n SourceLocationInlinedSource,\n} from './types.js';\n\nexport interface AstCoreFactoryArgs {\n /**\n * Whether the AstFactory can track sources, if not, the sourceLocation function returns autoGen. Default true\n */\n tracksSourceLocation: boolean;\n}\n\nexport class AstCoreFactory implements AstCoreFactoryArgs {\n public tracksSourceLocation: boolean;\n public constructor(args: Partial<AstCoreFactoryArgs> = {}) {\n this.tracksSourceLocation = args.tracksSourceLocation ?? true;\n }\n\n public wrap<T>(val: T, loc: SourceLocation): Wrap<T> {\n return { val, loc };\n }\n\n public isLocalized(obj: unknown): obj is Localized {\n return typeof obj === 'object' && obj !== null && 'loc' in obj &&\n typeof obj.loc === 'object' && obj.loc !== null && 'sourceLocationType' in obj.loc;\n }\n\n public sourceLocation(...elements: (undefined | IToken | Localized)[]): SourceLocation {\n if (!this.tracksSourceLocation) {\n return this.gen();\n }\n\n const pureElements = elements.filter(x => x !== undefined);\n if (pureElements.length === 0) {\n return this.sourceLocationNoMaterialize();\n }\n\n const filtered = pureElements.filter(element =>\n !this.isLocalized(element) || this.isSourceLocationSource(element.loc) ||\n this.isSourceLocationStringReplace(element.loc) || this.isSourceLocationNodeReplace(element.loc));\n if (filtered.length === 0) {\n return this.gen();\n }\n const first = filtered.at(0)!;\n const last = filtered.at(-1)!;\n return {\n sourceLocationType: 'source',\n start: this.isLocalized(first) ?\n (<SourceLocationSource | SourceLocationStringReplace> first.loc).start :\n first.startOffset,\n end: this.isLocalized(last) ?\n (<SourceLocationSource | SourceLocationStringReplace> last.loc).end :\n (last.endOffset! + 1),\n };\n }\n\n public sourceLocationNoMaterialize(): SourceLocation {\n if (!this.tracksSourceLocation) {\n return this.gen();\n }\n return { sourceLocationType: 'noMaterialize' };\n }\n\n /**\n * Returns a copy of the argument that is not materialized\n */\n public dematerialized<T extends Node>(arg: T): T {\n return { ...arg, loc: this.sourceLocationNoMaterialize() };\n }\n\n public safeObjectTransform(value: unknown, mapper: (some: object) => any): any {\n if (value && typeof value === 'object') {\n // If you wonder why this is all so hard, this is the reason. We cannot lose the methods of our Array objects\n if (Array.isArray(value)) {\n return value.map(x => this.safeObjectTransform(x, mapper));\n }\n return mapper(value);\n }\n return value;\n }\n\n public forcedAutoGenTree<T extends object>(obj: T): T {\n const copy = { ...obj };\n for (const [ key, value ] of Object.entries(copy)) {\n (<Record<string, object>> copy)[key] = this.safeObjectTransform(value, obj => this.forcedAutoGenTree(obj));\n }\n if (this.isLocalized(copy)) {\n copy.loc = this.gen();\n }\n return copy;\n }\n\n public forceMaterialized<T extends Node>(arg: T): T {\n if (this.isSourceLocationNoMaterialize(arg.loc)) {\n return this.forcedAutoGenTree(arg);\n }\n return { ...arg };\n }\n\n public isSourceLocation(loc: object): loc is SourceLocation {\n return 'sourceLocationType' in loc;\n }\n\n public sourceLocationSource(start: number, end: number): SourceLocationSource {\n return {\n sourceLocationType: 'source',\n start,\n end,\n };\n }\n\n /**\n * {@inheritDoc SourceLocationInlinedSource}\n */\n public sourceLocationInlinedSource(\n newSource: string,\n subLoc: SourceLocation,\n start: number,\n end: number,\n startOnNew = 0,\n endOnNew: number = newSource.length,\n ): SourceLocation {\n if (!this.tracksSourceLocation) {\n return this.gen();\n }\n if (this.isSourceLocationSource(subLoc)) {\n startOnNew = subLoc.start;\n endOnNew = subLoc.end;\n }\n return {\n sourceLocationType: 'inlinedSource',\n newSource,\n start,\n end,\n loc: subLoc,\n startOnNew,\n endOnNew,\n }satisfies SourceLocationInlinedSource;\n };\n\n public isSourceLocationInlinedSource(loc: object): loc is SourceLocationInlinedSource {\n return this.isSourceLocation(loc) && loc.sourceLocationType === 'inlinedSource';\n }\n\n public gen(): SourceLocationNodeAutoGenerate {\n return { sourceLocationType: 'autoGenerate' };\n }\n\n public isSourceLocationSource(loc: object): loc is SourceLocationSource {\n return this.isSourceLocation(loc) && loc.sourceLocationType === 'source';\n }\n\n public sourceLocationStringReplace(newSource: string, start: number, end: number): SourceLocation {\n if (!this.tracksSourceLocation) {\n return this.gen();\n }\n return { sourceLocationType: 'stringReplace', newSource, start, end } satisfies SourceLocationStringReplace;\n }\n\n public isSourceLocationStringReplace(loc: object): loc is SourceLocationStringReplace {\n return this.isSourceLocation(loc) && loc.sourceLocationType === 'stringReplace';\n }\n\n public sourceLocationNodeReplaceUnsafe(loc: SourceLocation): SourceLocationNodeReplace {\n if (this.isSourceLocationSource(loc)) {\n return this.sourceLocationNodeReplace(loc);\n }\n if (this.isSourceLocationInlinedSource(loc)) {\n return this.sourceLocationNodeReplaceUnsafe(loc.loc);\n }\n throw new Error(`Cannot convert SourceLocation of type ${loc.sourceLocationType} to SourceLocationNodeReplace`);\n }\n\n public sourceLocationNodeReplace(location: SourceLocationSource): SourceLocationNodeReplace;\n public sourceLocationNodeReplace(start: number, end: number): SourceLocationNodeReplace;\n public sourceLocationNodeReplace(startOrLoc: number | SourceLocationSource, end?: number): SourceLocationNodeReplace {\n let starting;\n let ending;\n if (typeof startOrLoc === 'number') {\n starting = startOrLoc;\n ending = end!;\n } else {\n starting = startOrLoc.start;\n ending = startOrLoc.end;\n }\n return {\n sourceLocationType: 'nodeReplace',\n start: starting,\n end: ending,\n };\n }\n\n public isSourceLocationNodeReplace(loc: object): loc is SourceLocationNodeReplace {\n return this.isSourceLocation(loc) && loc.sourceLocationType === 'nodeReplace';\n }\n\n public isSourceLocationNodeAutoGenerate(loc: object): loc is SourceLocationNodeAutoGenerate {\n return this.isSourceLocation(loc) && loc.sourceLocationType === 'autoGenerate';\n }\n\n public isPrintingLoc(loc: SourceLocation): boolean {\n return this.isSourceLocationNodeReplace(loc) ||\n this.isSourceLocationNodeAutoGenerate(loc) ||\n (this.isSourceLocationInlinedSource(loc) && this.isPrintingLoc(loc.loc));\n }\n\n public printFilter(node: Localized, callback: () => void): void {\n if (this.isPrintingLoc(node.loc)) {\n callback();\n }\n }\n\n public isSourceLocationNoMaterialize(loc: object): loc is SourceLocationNoMaterialize {\n return this.isSourceLocation(loc) && loc.sourceLocationType === 'noMaterialize';\n }\n\n public isOfType<Type extends string>(obj: object, type: Type): obj is Typed<Type> {\n const casted: { type?: any } = obj;\n return casted.type === type;\n }\n\n public isOfSubType<Type extends string, SubType extends string>(obj: object, type: Type, subType: SubType):\n obj is SubTyped<Type, SubType> {\n const temp: { type?: unknown; subType?: unknown } = obj;\n return temp.type === type && temp.subType === subType;\n }\n}\n"]}
{"version":3,"file":"AstCoreFactory.js","sourceRoot":"","sources":["../../../lib/AstCoreFactory.ts"],"names":[],"mappings":"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","sourcesContent":["import type { IToken } from '@traqula/chevrotain';\n\nimport type {\n SourceLocation,\n SourceLocationNodeAutoGenerate,\n SourceLocationNodeReplace,\n SourceLocationNoMaterialize,\n SourceLocationSource,\n SourceLocationStringReplace,\n Node,\n Localized,\n Wrap,\n Typed,\n SubTyped,\n SourceLocationInlinedSource,\n} from './types.js';\n\nexport interface AstCoreFactoryArgs {\n /**\n * Whether the AstFactory can track sources, if not, the sourceLocation function returns autoGen. Default true\n */\n tracksSourceLocation: boolean;\n}\n\nexport class AstCoreFactory implements AstCoreFactoryArgs {\n /**\n * Whether this AstFactory will track source location. Default: true.\n * In case source location is not tracked,\n * each generated node using this factory will be {@link SourceLocationNodeAutoGenerate}\n */\n public tracksSourceLocation: boolean;\n\n public constructor(args: Partial<AstCoreFactoryArgs> = {}) {\n this.tracksSourceLocation = args.tracksSourceLocation ?? true;\n }\n\n /**\n * Wrap any type into an object that tracks the source location of tha value.\n * @param val the value to wrap\n * @param loc the source location for that value\n */\n public wrap<T>(val: T, loc: SourceLocation): Wrap<T> {\n return { val, loc };\n }\n\n /**\n * Whether the provided value is an object that tracks source location.\n * @param obj\n */\n public isLocalized(obj: unknown): obj is Localized {\n return typeof obj === 'object' && obj !== null && 'loc' in obj &&\n typeof obj.loc === 'object' && obj.loc !== null && 'sourceLocationType' in obj.loc;\n }\n\n /**\n * Compute the source location of an element based on the elements it contains.\n * The provided arguments should be in order of occurrence in the string.\n */\n public sourceLocation(...elements: (undefined | IToken | Localized)[]): SourceLocation {\n if (!this.tracksSourceLocation) {\n return this.gen();\n }\n\n const pureElements = elements.filter(x => x !== undefined);\n if (pureElements.length === 0) {\n return this.sourceLocationNoMaterialize();\n }\n\n const filtered = pureElements.filter(element =>\n !this.isLocalized(element) || this.isSourceLocationSource(element.loc) ||\n this.isSourceLocationStringReplace(element.loc) || this.isSourceLocationNodeReplace(element.loc));\n if (filtered.length === 0) {\n return this.gen();\n }\n const first = filtered.at(0)!;\n const last = filtered.at(-1)!;\n return {\n sourceLocationType: 'source',\n start: this.isLocalized(first) ?\n (<SourceLocationSource | SourceLocationStringReplace> first.loc).start :\n first.startOffset,\n end: this.isLocalized(last) ?\n (<SourceLocationSource | SourceLocationStringReplace> last.loc).end :\n (last.endOffset! + 1),\n };\n }\n\n /**\n * Generate a source location indicating the no materialization.\n */\n public sourceLocationNoMaterialize(): SourceLocation {\n if (!this.tracksSourceLocation) {\n return this.gen();\n }\n return { sourceLocationType: 'noMaterialize' };\n }\n\n /**\n * Returns a copy of the argument that is not materialized\n */\n public dematerialized<T extends Node>(arg: T): T {\n return { ...arg, loc: this.sourceLocationNoMaterialize() };\n }\n\n /**\n * Given a value and some mapper from objects to objects,\n * map all containing items in case it is an array,\n * otherwise map the provided value in case it is an object, finally, do nothing.\n * @param value the value to map\n * @param mapper the function mapping an object to another object.\n */\n public safeObjectTransform(value: unknown, mapper: (some: object) => any): any {\n if (value && typeof value === 'object') {\n // If you wonder why this is all so hard, this is the reason. We cannot lose the methods of our Array objects\n if (Array.isArray(value)) {\n return value.map(x => this.safeObjectTransform(x, mapper));\n }\n return mapper(value);\n }\n return value;\n }\n\n /**\n * Given a (AST) tree, return a copy of that tree where it and it's\n * descendents all have a {@link SourceLocationNodeAutoGenerate} localization.\n */\n public forcedAutoGenTree<T extends object>(obj: T): T {\n const copy = { ...obj };\n for (const [ key, value ] of Object.entries(copy)) {\n (<Record<string, object>> copy)[key] = this.safeObjectTransform(value, obj => this.forcedAutoGenTree(obj));\n }\n if (this.isLocalized(copy)) {\n copy.loc = this.gen();\n }\n return copy;\n }\n\n /**\n * In case the provided Node is not yet materialized, force it to be autoGenerated.\n */\n public forceMaterialized<T extends Node>(arg: T): T {\n if (this.isSourceLocationNoMaterialize(arg.loc)) {\n return this.forcedAutoGenTree(arg);\n }\n return { ...arg };\n }\n\n /**\n * Check whether an object is in fact a {@link SourceLocation}.\n * @param loc\n */\n public isSourceLocation(loc: object): loc is SourceLocation {\n return 'sourceLocationType' in loc;\n }\n\n /**\n * Create a {@link SourceLocation} that indicates what range of characters this node represents in the source string.\n */\n public sourceLocationSource(start: number, end: number): SourceLocationSource {\n return {\n sourceLocationType: 'source',\n start,\n end,\n };\n }\n\n /**\n * Create a {@link SourceLocation} that indicates a given range of the current range should be replaced by\n * a new source.\n */\n public sourceLocationInlinedSource(\n newSource: string,\n subLoc: SourceLocation,\n start: number,\n end: number,\n startOnNew = 0,\n endOnNew: number = newSource.length,\n ): SourceLocation {\n if (!this.tracksSourceLocation) {\n return this.gen();\n }\n if (this.isSourceLocationSource(subLoc)) {\n startOnNew = subLoc.start;\n endOnNew = subLoc.end;\n }\n return {\n sourceLocationType: 'inlinedSource',\n newSource,\n start,\n end,\n loc: subLoc,\n startOnNew,\n endOnNew,\n }satisfies SourceLocationInlinedSource;\n };\n\n /**\n * Guard to check if an object is a {@link SourceLocation} of type {@link SourceLocationInlinedSource}.\n */\n public isSourceLocationInlinedSource(loc: object): loc is SourceLocationInlinedSource {\n return this.isSourceLocation(loc) && loc.sourceLocationType === 'inlinedSource';\n }\n\n /**\n * Create a {@link SourceLocation} indicating the node should be autoGenerated by a generator.\n */\n public gen(): SourceLocationNodeAutoGenerate {\n return { sourceLocationType: 'autoGenerate' };\n }\n\n /**\n * Guard to check if an object is a {@link SourceLocation} of type {@link SourceLocationSource}.\n */\n public isSourceLocationSource(loc: object): loc is SourceLocationSource {\n return this.isSourceLocation(loc) && loc.sourceLocationType === 'source';\n }\n\n /**\n * Create a {@link SourceLocation} that indicates this node,\n * representing a range of characters in the original string, should be replaced by some string during generation.\n */\n public sourceLocationStringReplace(newSource: string, start: number, end: number): SourceLocation {\n if (!this.tracksSourceLocation) {\n return this.gen();\n }\n return { sourceLocationType: 'stringReplace', newSource, start, end } satisfies SourceLocationStringReplace;\n }\n\n /**\n * Guard to check if an object is a {@link SourceLocation} of type {@link SourceLocationStringReplace}.\n * @param loc\n */\n public isSourceLocationStringReplace(loc: object): loc is SourceLocationStringReplace {\n return this.isSourceLocation(loc) && loc.sourceLocationType === 'stringReplace';\n }\n\n /**\n * Given a sourceLocation, generate a new {@link SourceLocation}\n * that indicates the range of the given location should now be autoGenerated\n */\n public sourceLocationNodeReplaceUnsafe(loc: SourceLocation): SourceLocationNodeReplace {\n if (this.isSourceLocationSource(loc)) {\n return this.sourceLocationNodeReplace(loc);\n }\n if (this.isSourceLocationInlinedSource(loc)) {\n return this.sourceLocationNodeReplaceUnsafe(loc.loc);\n }\n throw new Error(`Cannot convert SourceLocation of type ${loc.sourceLocationType} to SourceLocationNodeReplace`);\n }\n\n public sourceLocationNodeReplace(location: SourceLocationSource): SourceLocationNodeReplace;\n public sourceLocationNodeReplace(start: number, end: number): SourceLocationNodeReplace;\n public sourceLocationNodeReplace(startOrLoc: number | SourceLocationSource, end?: number): SourceLocationNodeReplace {\n let starting;\n let ending;\n if (typeof startOrLoc === 'number') {\n starting = startOrLoc;\n ending = end!;\n } else {\n starting = startOrLoc.start;\n ending = startOrLoc.end;\n }\n return {\n sourceLocationType: 'nodeReplace',\n start: starting,\n end: ending,\n };\n }\n\n /**\n * Guard to check if an object is a {@link SourceLocation} of type {@link SourceLocationNodeReplace}.\n */\n public isSourceLocationNodeReplace(loc: object): loc is SourceLocationNodeReplace {\n return this.isSourceLocation(loc) && loc.sourceLocationType === 'nodeReplace';\n }\n\n /**\n * Guard to check if an object is a {@link SourceLocation} of type {@link SourceLocationNodeAutoGenerate}.\n */\n public isSourceLocationNodeAutoGenerate(loc: object): loc is SourceLocationNodeAutoGenerate {\n return this.isSourceLocation(loc) && loc.sourceLocationType === 'autoGenerate';\n }\n\n /**\n * Check whether the provided {@link SourceLocation} expects the generator to autoGenerate.\n */\n public isPrintingLoc(loc: SourceLocation): boolean {\n return this.isSourceLocationNodeReplace(loc) ||\n this.isSourceLocationNodeAutoGenerate(loc) ||\n (this.isSourceLocationInlinedSource(loc) && this.isPrintingLoc(loc.loc));\n }\n\n /**\n * A simple filter that will only execute the provided callback when the provided {@link SourceLocation}\n * expects the generator steps to autoGenerate.\n */\n public printFilter(node: Localized, callback: () => void): void {\n if (this.isPrintingLoc(node.loc)) {\n callback();\n }\n }\n\n /**\n * Guard to check if an object is a {@link SourceLocation} of type {@link SourceLocationNoMaterialize}.\n */\n public isSourceLocationNoMaterialize(loc: object): loc is SourceLocationNoMaterialize {\n return this.isSourceLocation(loc) && loc.sourceLocationType === 'noMaterialize';\n }\n\n /**\n * Guard to check if an object is the specified Type: {@link Typed}.\n */\n public isOfType<Type extends string>(obj: object, type: Type): obj is Typed<Type> {\n const casted: { type?: any } = obj;\n return casted.type === type;\n }\n\n /**\n * Guard to check if an object is the specified Type: {@link SubTyped}.\n */\n public isOfSubType<Type extends string, SubType extends string>(obj: object, type: Type, subType: SubType):\n obj is SubTyped<Type, SubType> {\n const temp: { type?: unknown; subType?: unknown } = obj;\n return temp.type === type && temp.subType === subType;\n }\n}\n"]}

@@ -11,2 +11,6 @@ "use strict";

origSource = '';
/**
* Reference to the latest SourceLocationInlinedSource this generator handled (used for idempotency)
* @protected
*/
handledInlineSource;

@@ -86,5 +90,7 @@ generatedUntil = 0;

if (this.factory.isSourceLocationInlinedSource(localized.loc) && this.handledInlineSource !== localized.loc) {
// Calling handleLoc on the same AST multiple times should be the same as doing it once.
// Idempotence: calling handleLoc on the same AST multiple times should be the same as doing it once.
this.handledInlineSource = localized.loc;
// Like normal, catch up until the start of what this node represents.
this.catchup(localized.loc.start);
// Save pointer location of current source and register new source.
const origSource = this.origSource;

@@ -94,9 +100,12 @@ const origPointer = this.generatedUntil;

this.generatedUntil = 0;
// Catchup the new source to where this node starts representing the source.
this.catchup(localized.loc.startOnNew);
this.handleLoc(localized.loc, handle);
const ret = this.handleLoc(localized.loc, handle);
// Catchup so the entire new source is generated outside what this node represents.
this.generatedUntil = localized.loc.endOnNew;
this.catchup(this.origSource.length);
// Recover the original source and register that you generated the range of this node.
this.origSource = origSource;
this.generatedUntil = Math.max(origPointer, localized.loc.end);
return;
return ret;
}

@@ -103,0 +112,0 @@ // If autoGenerate - do nothing

@@ -1,1 +0,1 @@

{"version":3,"file":"dynamicGenerator.js","sourceRoot":"","sources":["../../../../lib/generator-builder/dynamicGenerator.ts"],"names":[],"mappings":"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","sourcesContent":["import { AstCoreFactory } from '../AstCoreFactory.js';\nimport type { SourceLocationInlinedSource } from '../types.js';\nimport { traqulaIndentation, traqulaNewlineAlternative } from '../utils.js';\nimport type { GenRuleMap } from './builderTypes.js';\nimport type { GeneratorRule, RuleDefArg } from './generatorTypes.js';\n\nexport interface GeneratorContext {\n [traqulaIndentation]?: number;\n [traqulaNewlineAlternative]?: string;\n}\n\nexport class DynamicGenerator<Context, Names extends string, RuleDefs extends GenRuleMap<Names>> {\n protected readonly factory = new AstCoreFactory();\n protected __context: Context | undefined = undefined;\n protected origSource = '';\n protected handledInlineSource: SourceLocationInlinedSource | undefined;\n protected generatedUntil = 0;\n protected toEnsure: ((willPrint: string) => void)[] = [];\n /**\n * Should not contain empty strings\n * @protected\n */\n protected readonly stringBuilder: string[] = [];\n\n public constructor(protected rules: RuleDefs) {\n // eslint-disable-next-line ts/no-unnecessary-type-assertion\n for (const rule of <GeneratorRule[]> Object.values(rules)) {\n // Define function implementation\n this[<keyof (typeof this)> rule.name] =\n <any> ((input: any, context: Context & { origSource: string; offset?: number }, args: any) => {\n this.stringBuilder.length = 0;\n this.origSource = context.origSource;\n this.generatedUntil = context?.offset ?? 0;\n this.setContext(context);\n\n this.subrule(rule, input, args);\n\n this.catchup(this.origSource.length);\n\n return this.stringBuilder.join('');\n });\n }\n }\n\n public setContext(context: Context): void {\n this.__context = context;\n }\n\n protected getSafeContext(): Context & GeneratorContext {\n return <Context & GeneratorContext> this.__context;\n }\n\n protected readonly subrule: RuleDefArg['SUBRULE'] = (cstDef, ast, ...arg) => {\n const def = this.rules[<Names> cstDef.name];\n if (!def) {\n throw new Error(`Rule ${cstDef.name} not found`);\n }\n\n const generate = (): void => def.gImpl({\n SUBRULE: this.subrule,\n PRINT: this.print,\n ENSURE: this.ensure,\n ENSURE_EITHER: this.ensureEither,\n NEW_LINE: this.newLine,\n HANDLE_LOC: this.handleLoc,\n CATCHUP: this.catchup,\n\n PRINT_WORD: this.printWord,\n PRINT_WORDS: this.printWords,\n PRINT_ON_EMPTY: this.printOnEmpty,\n PRINT_ON_OWN_LINE: this.printOnOwnLine,\n })(ast, this.getSafeContext(), ...arg);\n\n if (this.factory.isLocalized(ast)) {\n this.handleLoc(ast, generate);\n } else {\n generate();\n }\n };\n\n protected readonly handleLoc: RuleDefArg['HANDLE_LOC'] = (localized, handle) => {\n if (this.factory.isSourceLocationNoMaterialize(localized.loc)) {\n return;\n }\n if (this.factory.isSourceLocationStringReplace(localized.loc)) {\n this.catchup(localized.loc.start);\n this.print(localized.loc.newSource);\n this.generatedUntil = localized.loc.end;\n return;\n }\n if (this.factory.isSourceLocationNodeReplace(localized.loc)) {\n this.catchup(localized.loc.start);\n this.generatedUntil = localized.loc.end;\n }\n if (this.factory.isSourceLocationSource(localized.loc)) {\n this.catchup(localized.loc.start);\n }\n if (this.factory.isSourceLocationInlinedSource(localized.loc) && this.handledInlineSource !== localized.loc) {\n // Calling handleLoc on the same AST multiple times should be the same as doing it once.\n this.handledInlineSource = localized.loc;\n this.catchup(localized.loc.start);\n const origSource = this.origSource;\n const origPointer = this.generatedUntil;\n this.origSource = localized.loc.newSource;\n this.generatedUntil = 0;\n this.catchup(localized.loc.startOnNew);\n\n this.handleLoc(localized.loc, handle);\n\n this.generatedUntil = localized.loc.endOnNew;\n this.catchup(this.origSource.length);\n this.origSource = origSource;\n this.generatedUntil = Math.max(origPointer, localized.loc.end);\n return;\n }\n // If autoGenerate - do nothing\n\n const ret = handle();\n\n if (this.factory.isSourceLocationSource(localized.loc)) {\n this.catchup(localized.loc.end);\n }\n return ret;\n };\n\n /**\n * Catchup until, excluding\n */\n protected readonly catchup: RuleDefArg['CATCHUP'] = (until) => {\n const start = this.generatedUntil;\n if (start < until) {\n this.print(this.origSource.slice(start, until));\n }\n this.generatedUntil = Math.max(this.generatedUntil, until);\n };\n\n private handeEnsured(toPrint: string): void {\n for (const callBack of this.toEnsure) {\n callBack(toPrint);\n }\n this.toEnsure.length = 0;\n }\n\n protected readonly print: RuleDefArg['PRINT'] = (...args) => {\n const joined = args.join('');\n this.handeEnsured(joined);\n this.stringBuilder.push(joined);\n };\n\n private doesEndWith(subsStr: string): boolean {\n const len = subsStr.length;\n let temp = '';\n while (temp.length < len && this.stringBuilder.length > 0) {\n temp = this.stringBuilder.pop() + temp;\n }\n this.stringBuilder.push(temp);\n return temp.endsWith(subsStr);\n }\n\n protected readonly ensure: RuleDefArg['ENSURE'] = (...args) => {\n // Check whether already present\n const toEnsure = args.join('');\n if (!this.doesEndWith(toEnsure)) {\n this.toEnsure.push((willPrint) => {\n if (!willPrint.startsWith(toEnsure) && !this.doesEndWith(toEnsure)) {\n this.stringBuilder.push(toEnsure);\n }\n });\n }\n };\n\n protected readonly ensureEither: RuleDefArg['ENSURE_EITHER'] = (...args) => {\n if (args.length === 1) {\n this.ensure(...args);\n } else if (args.length > 1 &&\n // Not already matched?\n !args.some(subStr => this.doesEndWith(subStr))) {\n this.toEnsure.push((willPrint) => {\n if (!args.some(subStr => willPrint.startsWith(subStr)) && !args.some(subStr => this.doesEndWith(subStr))) {\n this.stringBuilder.push(args[0]);\n }\n });\n }\n };\n\n private pruneEndingBlanks(): void {\n let temp = '';\n while (/^[ \\t]*$/u.test(temp) && this.stringBuilder.length > 0) {\n temp = this.stringBuilder.pop() + temp;\n }\n this.print(temp.trimEnd());\n }\n\n protected readonly newLine: RuleDefArg['NEW_LINE'] = (arg) => {\n const indentation = this.getSafeContext()[traqulaIndentation] ?? 0;\n const force = arg?.force ?? false;\n if (indentation < 0) {\n const newlineAlternative = this.getSafeContext()[traqulaNewlineAlternative];\n if (newlineAlternative !== undefined &&\n // If we force, it means we would print \\n no matter. - otherwise check whether we have printed the char\n (force || (this.stringBuilder.at(-1) !== newlineAlternative))) {\n this.print(newlineAlternative);\n }\n return;\n }\n this.pruneEndingBlanks();\n if (force) {\n this.print('\\n', ' '.repeat(indentation));\n } else {\n let temp = '';\n while (!temp.includes('\\n') && this.stringBuilder.length > 0) {\n temp = this.stringBuilder.pop() + temp;\n }\n if (/\\n[ \\t]*$/u.test(temp)) {\n // Pointer is on empty newline -> set correct indentation\n temp = temp.replace(/\\n[ \\t]*$/u, `\\n${' '.repeat(indentation)}`);\n this.print(temp);\n } else {\n // Pointer not on empty newline, print newline.\n this.print(temp, '\\n', ' '.repeat(indentation));\n }\n }\n };\n\n private readonly printWord: RuleDefArg['PRINT_WORD'] = (...args) => {\n this.ensureEither(' ', '\\n');\n this.print(...args);\n this.ensureEither(' ', '\\n');\n };\n\n private readonly printWords: RuleDefArg['PRINT_WORD'] = (...args) => {\n for (const arg of args) {\n this.printWord(arg);\n }\n };\n\n private readonly printOnEmpty: RuleDefArg['PRINT_ON_EMPTY'] = (...args) => {\n this.newLine();\n this.print(...args);\n };\n\n private readonly printOnOwnLine: RuleDefArg['PRINT_ON_OWN_LINE'] = (...args) => {\n this.newLine();\n this.print(...args);\n this.newLine();\n };\n}\n"]}
{"version":3,"file":"dynamicGenerator.js","sourceRoot":"","sources":["../../../../lib/generator-builder/dynamicGenerator.ts"],"names":[],"mappings":"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","sourcesContent":["import { AstCoreFactory } from '../AstCoreFactory.js';\nimport type { SourceLocationInlinedSource } from '../types.js';\nimport { traqulaIndentation, traqulaNewlineAlternative } from '../utils.js';\nimport type { GenRuleMap } from './builderTypes.js';\nimport type { GeneratorRule, RuleDefArg } from './generatorTypes.js';\n\nexport interface GeneratorContext {\n [traqulaIndentation]?: number;\n [traqulaNewlineAlternative]?: string;\n}\n\nexport class DynamicGenerator<Context, Names extends string, RuleDefs extends GenRuleMap<Names>> {\n protected readonly factory = new AstCoreFactory();\n protected __context: Context | undefined = undefined;\n protected origSource = '';\n /**\n * Reference to the latest SourceLocationInlinedSource this generator handled (used for idempotency)\n * @protected\n */\n protected handledInlineSource: SourceLocationInlinedSource | undefined;\n protected generatedUntil = 0;\n protected toEnsure: ((willPrint: string) => void)[] = [];\n /**\n * Should not contain empty strings\n * @protected\n */\n protected readonly stringBuilder: string[] = [];\n\n public constructor(protected rules: RuleDefs) {\n // eslint-disable-next-line ts/no-unnecessary-type-assertion\n for (const rule of <GeneratorRule[]> Object.values(rules)) {\n // Define function implementation\n this[<keyof (typeof this)> rule.name] =\n <any> ((input: any, context: Context & { origSource: string; offset?: number }, args: any) => {\n this.stringBuilder.length = 0;\n this.origSource = context.origSource;\n this.generatedUntil = context?.offset ?? 0;\n this.setContext(context);\n\n this.subrule(rule, input, args);\n\n this.catchup(this.origSource.length);\n\n return this.stringBuilder.join('');\n });\n }\n }\n\n public setContext(context: Context): void {\n this.__context = context;\n }\n\n protected getSafeContext(): Context & GeneratorContext {\n return <Context & GeneratorContext> this.__context;\n }\n\n protected readonly subrule: RuleDefArg['SUBRULE'] = (cstDef, ast, ...arg) => {\n const def = this.rules[<Names> cstDef.name];\n if (!def) {\n throw new Error(`Rule ${cstDef.name} not found`);\n }\n\n const generate = (): void => def.gImpl({\n SUBRULE: this.subrule,\n PRINT: this.print,\n ENSURE: this.ensure,\n ENSURE_EITHER: this.ensureEither,\n NEW_LINE: this.newLine,\n HANDLE_LOC: this.handleLoc,\n CATCHUP: this.catchup,\n\n PRINT_WORD: this.printWord,\n PRINT_WORDS: this.printWords,\n PRINT_ON_EMPTY: this.printOnEmpty,\n PRINT_ON_OWN_LINE: this.printOnOwnLine,\n })(ast, this.getSafeContext(), ...arg);\n\n if (this.factory.isLocalized(ast)) {\n this.handleLoc(ast, generate);\n } else {\n generate();\n }\n };\n\n protected readonly handleLoc: RuleDefArg['HANDLE_LOC'] = (localized, handle) => {\n if (this.factory.isSourceLocationNoMaterialize(localized.loc)) {\n return;\n }\n if (this.factory.isSourceLocationStringReplace(localized.loc)) {\n this.catchup(localized.loc.start);\n this.print(localized.loc.newSource);\n this.generatedUntil = localized.loc.end;\n return;\n }\n if (this.factory.isSourceLocationNodeReplace(localized.loc)) {\n this.catchup(localized.loc.start);\n this.generatedUntil = localized.loc.end;\n }\n if (this.factory.isSourceLocationSource(localized.loc)) {\n this.catchup(localized.loc.start);\n }\n if (this.factory.isSourceLocationInlinedSource(localized.loc) && this.handledInlineSource !== localized.loc) {\n // Idempotence: calling handleLoc on the same AST multiple times should be the same as doing it once.\n this.handledInlineSource = localized.loc;\n // Like normal, catch up until the start of what this node represents.\n this.catchup(localized.loc.start);\n // Save pointer location of current source and register new source.\n const origSource = this.origSource;\n const origPointer = this.generatedUntil;\n this.origSource = localized.loc.newSource;\n this.generatedUntil = 0;\n // Catchup the new source to where this node starts representing the source.\n this.catchup(localized.loc.startOnNew);\n\n const ret = this.handleLoc(localized.loc, handle);\n\n // Catchup so the entire new source is generated outside what this node represents.\n this.generatedUntil = localized.loc.endOnNew;\n this.catchup(this.origSource.length);\n // Recover the original source and register that you generated the range of this node.\n this.origSource = origSource;\n this.generatedUntil = Math.max(origPointer, localized.loc.end);\n return ret;\n }\n // If autoGenerate - do nothing\n\n const ret = handle();\n\n if (this.factory.isSourceLocationSource(localized.loc)) {\n this.catchup(localized.loc.end);\n }\n return ret;\n };\n\n /**\n * Catchup until, excluding\n */\n protected readonly catchup: RuleDefArg['CATCHUP'] = (until) => {\n const start = this.generatedUntil;\n if (start < until) {\n this.print(this.origSource.slice(start, until));\n }\n this.generatedUntil = Math.max(this.generatedUntil, until);\n };\n\n private handeEnsured(toPrint: string): void {\n for (const callBack of this.toEnsure) {\n callBack(toPrint);\n }\n this.toEnsure.length = 0;\n }\n\n protected readonly print: RuleDefArg['PRINT'] = (...args) => {\n const joined = args.join('');\n this.handeEnsured(joined);\n this.stringBuilder.push(joined);\n };\n\n private doesEndWith(subsStr: string): boolean {\n const len = subsStr.length;\n let temp = '';\n while (temp.length < len && this.stringBuilder.length > 0) {\n temp = this.stringBuilder.pop() + temp;\n }\n this.stringBuilder.push(temp);\n return temp.endsWith(subsStr);\n }\n\n protected readonly ensure: RuleDefArg['ENSURE'] = (...args) => {\n // Check whether already present\n const toEnsure = args.join('');\n if (!this.doesEndWith(toEnsure)) {\n this.toEnsure.push((willPrint) => {\n if (!willPrint.startsWith(toEnsure) && !this.doesEndWith(toEnsure)) {\n this.stringBuilder.push(toEnsure);\n }\n });\n }\n };\n\n protected readonly ensureEither: RuleDefArg['ENSURE_EITHER'] = (...args) => {\n if (args.length === 1) {\n this.ensure(...args);\n } else if (args.length > 1 &&\n // Not already matched?\n !args.some(subStr => this.doesEndWith(subStr))) {\n this.toEnsure.push((willPrint) => {\n if (!args.some(subStr => willPrint.startsWith(subStr)) && !args.some(subStr => this.doesEndWith(subStr))) {\n this.stringBuilder.push(args[0]);\n }\n });\n }\n };\n\n private pruneEndingBlanks(): void {\n let temp = '';\n while (/^[ \\t]*$/u.test(temp) && this.stringBuilder.length > 0) {\n temp = this.stringBuilder.pop() + temp;\n }\n this.print(temp.trimEnd());\n }\n\n protected readonly newLine: RuleDefArg['NEW_LINE'] = (arg) => {\n const indentation = this.getSafeContext()[traqulaIndentation] ?? 0;\n const force = arg?.force ?? false;\n if (indentation < 0) {\n const newlineAlternative = this.getSafeContext()[traqulaNewlineAlternative];\n if (newlineAlternative !== undefined &&\n // If we force, it means we would print \\n no matter. - otherwise check whether we have printed the char\n (force || (this.stringBuilder.at(-1) !== newlineAlternative))) {\n this.print(newlineAlternative);\n }\n return;\n }\n this.pruneEndingBlanks();\n if (force) {\n this.print('\\n', ' '.repeat(indentation));\n } else {\n let temp = '';\n while (!temp.includes('\\n') && this.stringBuilder.length > 0) {\n temp = this.stringBuilder.pop() + temp;\n }\n if (/\\n[ \\t]*$/u.test(temp)) {\n // Pointer is on empty newline -> set correct indentation\n temp = temp.replace(/\\n[ \\t]*$/u, `\\n${' '.repeat(indentation)}`);\n this.print(temp);\n } else {\n // Pointer not on empty newline, print newline.\n this.print(temp, '\\n', ' '.repeat(indentation));\n }\n }\n };\n\n private readonly printWord: RuleDefArg['PRINT_WORD'] = (...args) => {\n this.ensureEither(' ', '\\n');\n this.print(...args);\n this.ensureEither(' ', '\\n');\n };\n\n private readonly printWords: RuleDefArg['PRINT_WORD'] = (...args) => {\n for (const arg of args) {\n this.printWord(arg);\n }\n };\n\n private readonly printOnEmpty: RuleDefArg['PRINT_ON_EMPTY'] = (...args) => {\n this.newLine();\n this.print(...args);\n };\n\n private readonly printOnOwnLine: RuleDefArg['PRINT_ON_OWN_LINE'] = (...args) => {\n this.newLine();\n this.print(...args);\n this.newLine();\n };\n}\n"]}

@@ -173,3 +173,6 @@ "use strict";

for (let i = curObject.length - 1; i >= 0; i--) {
stack.push(curObject[i]);
const val = curObject[i];
if (val !== null && typeof val === 'object') {
stack.push(val);
}
}

@@ -176,0 +179,0 @@ handleVisitor();

@@ -1,1 +0,1 @@

{"version":3,"file":"TransformerObject.js","sourceRoot":"","sources":["../../../../lib/transformers/TransformerObject.ts"],"names":[],"mappings":";;;AAsCA,MAAa,iBAAiB;IAMU;IAL5B,YAAY,GAAG,SAAS,CAAC;IACnC;;;OAGG;IACH,YAAsC,iBAAmC,EAAE;QAArC,mBAAc,GAAd,cAAc,CAAuB;IAAG,CAAC;IAExE,KAAK,CAAC,oBAAsC,EAAE;QACnD,OAAO,IAAI,iBAAiB,CAAC,EAAE,GAAG,IAAI,CAAC,cAAc,EAAE,GAAG,iBAAiB,EAAE,CAAC,CAAC;IACjF,CAAC;IAED;;;;OAIG;IACI,QAAQ,CAAI,GAAM;QACvB,IAAI,GAAG,KAAK,IAAI,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;YAC5C,OAAO,GAAG,CAAC;QACb,CAAC;QAED,MAAM,KAAK,GAAG,MAAM,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC;QAEzC,0BAA0B;QAC1B,IAAI,KAAK,KAAK,MAAM,CAAC,SAAS,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YACjD,6CAA6C;YAC7C,OAAO,EAAE,GAAG,GAAG,EAAE,CAAC;QACpB,CAAC;QAED,mDAAmD;QACnD,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC;IAClD,CAAC;IAED;;;;;;;;OAQG;IACI,eAAe,CACpB,WAAmB,EACnB,MAA+C,EAC/C,aAAiD,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC;QAE3D,MAAM,QAAQ,GAAG,IAAI,CAAC,cAAc,CAAC;QACrC,MAAM,eAAe,GAAG,QAAQ,CAAC,IAAI,IAAI,IAAI,CAAC;QAC9C,MAAM,gBAAgB,GAAG,QAAQ,CAAC,QAAQ,IAAI,IAAI,CAAC;QACnD,MAAM,iBAAiB,GAAG,QAAQ,CAAC,UAAU,CAAC;QAC9C,MAAM,kBAAkB,GAAG,QAAQ,CAAC,WAAW,CAAC;QAChD,MAAM,kBAAkB,GAAG,QAAQ,CAAC,QAAQ,IAAI,KAAK,CAAC;QAEtD,6FAA6F;QAC7F,IAAI,WAAW,GAAG,KAAK,CAAC;QACxB,MAAM,UAAU,GAAG,EAAE,GAAG,EAAE,WAAW,EAAE,CAAC;QAExC,mBAAmB;QACnB,MAAM,KAAK,GAAG,CAAE,WAAW,CAAE,CAAC;QAC9B,MAAM,WAAW,GAAa,CAAE,UAAU,CAAE,CAAC;QAC7C,MAAM,cAAc,GAAa,CAAE,KAAK,CAAE,CAAC;QAE3C,uGAAuG;QACvG,iHAAiH;QACjH,MAAM,iBAAiB,GAAa,EAAE,CAAC;QACvC,MAAM,eAAe,GAAa,EAAE,CAAC;QACrC,MAAM,eAAe,GAAa,EAAE,CAAC;QACrC,MAAM,YAAY,GAAa,EAAE,CAAC;QAClC,MAAM,eAAe,GAAa,EAAE,CAAC;QAErC,SAAS,YAAY;YACnB,OAAO,KAAK,CAAC,MAAM,KAAK,iBAAiB,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBACjD,iBAAiB,CAAC,GAAG,EAAE,CAAC;gBACxB,MAAM,SAAS,GAAG,eAAe,CAAC,GAAG,EAAG,CAAC;gBACzC,MAAM,SAAS,GAAG,eAAe,CAAC,GAAG,EAAG,CAAC;gBACzC,MAAM,MAAM,GAA6B,YAAY,CAAC,GAAG,EAAG,CAAC;gBAC7D,MAAM,SAAS,GAAG,eAAe,CAAC,GAAG,EAAG,CAAC;gBACzC,MAAM,CAAC,SAAS,CAAC,GAAG,MAAM,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;YACnD,CAAC;QACH,CAAC;QAED,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;YAC5D,MAAM,SAAS,GAAG,KAAK,CAAC,GAAG,EAAG,CAAC;YAC/B,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,EAAG,CAAC;YACrC,MAAM,MAAM,GAAG,cAAc,CAAC,GAAG,EAAG,CAAC;YAErC,kDAAkD;YAClD,IAAI,CAAC,WAAW,EAAE,CAAC;gBACjB,IAAI,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;oBAC7B,MAAM,MAAM,GAAG,CAAE,GAAG,SAAS,CAAE,CAAC;oBAChC,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;oBACrC,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;oBAC7B,eAAe,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;oBAChC,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;oBAC7B,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;oBAE7B,KAAK,IAAI,KAAK,GAAG,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC;wBAC3D,MAAM,GAAG,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;wBAC7B,IAAI,GAAG,KAAK,IAAI,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;4BAC5C,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;4BAChB,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;4BACzB,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;wBACxC,CAAC;oBACH,CAAC;oBACD,YAAY,EAAE,CAAC;oBACf,SAAS;gBACX,CAAC;gBAED,+CAA+C;gBAC/C,MAAM,OAAO,GAAG,UAAU,CAAM,SAAS,CAAC,CAAC;gBAC3C,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,IAAI,eAAe,CAAC;gBACjD,MAAM,SAAS,GAAG,OAAO,CAAC,QAAQ,IAAI,gBAAgB,CAAC;gBACvD,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,iBAAiB,CAAC;gBAC3D,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,IAAI,kBAAkB,CAAC;gBAC9D,WAAW,GAAG,OAAO,CAAC,QAAQ,IAAI,kBAAkB,CAAC;gBAErD,MAAM,IAAI,GAAG,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;gBAE7D,uCAAuC;gBACvC,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;gBACrC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAC3B,eAAe,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;gBAChC,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;gBAC7B,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;gBAE7B,oGAAoG;gBACpG,IAAI,SAAS,IAAI,CAAC,WAAW,EAAE,CAAC;oBAC9B,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;wBACvB,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC;4BAC9B,SAAS;wBACX,CAAC;wBACD,MAAM,GAAG,GAA8B,IAAK,CAAC,GAAG,CAAC,CAAC;wBAElD,+BAA+B;wBAC/B,MAAM,WAAW,GAAG,WAAW,IAAI,WAAW,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;wBACzD,IAAI,WAAW,EAAE,CAAC;4BAChB,gDAAgD;4BACrB,IAAK,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;wBAC7D,CAAC;wBACD,IAAI,UAAU,IAAI,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;4BACtC,yBAAyB;4BACzB,SAAS;wBACX,CAAC;wBACD,IAAI,CAAC,WAAW,IAAI,GAAG,KAAK,IAAI,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;4BAC5D,sBAAsB;4BACtB,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;4BAChB,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;4BACzB,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;wBACzB,CAAC;oBACH,CAAC;gBACH,CAAC;YACH,CAAC;YACD,YAAY,EAAE,CAAC;QACjB,CAAC;QACD,IAAI,KAAK,CAAC,MAAM,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACtC,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;QACvD,CAAC;QACD,YAAY,EAAE,CAAC;QAEf,OAAa,UAAU,CAAC,GAAG,CAAC;IAC9B,CAAC;IAED;;OAEG;IACI,WAAW,CAChB,WAAmB,EACnB,OAA+B,EAC/B,aAA6C,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC;QAEvD,MAAM,QAAQ,GAAG,IAAI,CAAC,cAAc,CAAC;QACrC,MAAM,gBAAgB,GAAG,QAAQ,CAAC,QAAQ,IAAI,IAAI,CAAC;QACnD,MAAM,iBAAiB,GAAG,QAAQ,CAAC,UAAU,CAAC;QAC9C,MAAM,eAAe,GAAG,QAAQ,CAAC,QAAQ,IAAI,KAAK,CAAC;QAEnD,IAAI,WAAW,GAAG,KAAK,CAAC;QAExB,8BAA8B;QAC9B,MAAM,KAAK,GAAG,CAAE,WAAW,CAAE,CAAC;QAC9B,iFAAiF;QACjF,MAAM,kBAAkB,GAAa,EAAE,CAAC;QACxC,MAAM,YAAY,GAAa,EAAE,CAAC;QAElC,SAAS,aAAa;YACpB,OAAO,KAAK,CAAC,MAAM,KAAK,kBAAkB,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBAClD,kBAAkB,CAAC,GAAG,EAAE,CAAC;gBACzB,MAAM,OAAO,GAAG,YAAY,CAAC,GAAG,EAAG,CAAC;gBACpC,OAAO,CAAC,OAAO,CAAC,CAAC;YACnB,CAAC;QACH,CAAC;QAED,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;YAC5D,MAAM,SAAS,GAAG,KAAK,CAAC,GAAG,EAAG,CAAC;YAE/B,IAAI,CAAC,WAAW,EAAE,CAAC;gBACjB,IAAI,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;oBAC7B,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;wBAC/C,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;oBAC3B,CAAC;oBACD,aAAa,EAAE,CAAC;oBAChB,SAAS;gBACX,CAAC;gBAED,+CAA+C;gBAC/C,MAAM,OAAO,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC;gBACtC,WAAW,GAAG,OAAO,CAAC,QAAQ,IAAI,eAAe,CAAC;gBAClD,MAAM,SAAS,GAAG,OAAO,CAAC,QAAQ,IAAI,gBAAgB,CAAC;gBACvD,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,iBAAiB,CAAC;gBAE3D,uCAAuC;gBACvC,kBAAkB,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;gBACtC,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;gBAE7B,oGAAoG;gBACpG,IAAI,SAAS,IAAI,CAAC,WAAW,EAAE,CAAC;oBAC9B,KAAK,MAAM,GAAG,IAAI,SAAS,EAAE,CAAC;wBAC5B,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,GAAG,CAAC,EAAE,CAAC;4BACnC,SAAS;wBACX,CAAC;wBACD,IAAI,UAAU,IAAI,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;4BACtC,SAAS;wBACX,CAAC;wBACD,MAAM,GAAG,GAA8B,SAAU,CAAC,GAAG,CAAC,CAAC;wBACvD,IAAI,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;4BACnC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;wBAClB,CAAC;oBACH,CAAC;gBACH,CAAC;YACH,CAAC;YACD,aAAa,EAAE,CAAC;QAClB,CAAC;QACD,IAAI,KAAK,CAAC,MAAM,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACtC,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;QACvD,CAAC;QACD,aAAa,EAAE,CAAC;IAClB,CAAC;CACF;AA9OD,8CA8OC","sourcesContent":["export interface VisitContext {\n /**\n * Whether you should stop iterating after this object. Default false.\n */\n shortcut?: boolean;\n /**\n * Whether you should continue iterating deeper with this object. Default true.\n */\n continue?: boolean;\n /**\n * Object keys that can be ignored, meaning they do not get visited.\n */\n ignoreKeys?: Set<string>;\n}\n\nexport interface TransformContext extends VisitContext {\n /**\n * Object keys that will be shallowly copied but not traversed.\n * When the same key is included here and in ignoreKeys, the copy will still be made.\n */\n shallowKeys?: Set<string>;\n /**\n * Whether the visited object should be shallowly copied or not. Defaults to true.\n */\n copy?: boolean;\n}\n\nexport interface SelectiveTraversalContext<Nodes> {\n /**\n * Nodes you should visit next. Defaults to empty list\n */\n next?: Nodes[];\n /**\n * Whether you should stop visiting after visiting this object. Default false.\n */\n shortcut?: boolean;\n}\n\nexport class TransformerObject {\n protected maxStackSize = 1_000_000;\n /**\n * Creates stateless transformer.\n * @param defaultContext\n */\n public constructor(protected readonly defaultContext: TransformContext = {}) {}\n\n public clone(newDefaultContext: TransformContext = {}): TransformerObject {\n return new TransformerObject({ ...this.defaultContext, ...newDefaultContext });\n }\n\n /**\n * Function to shallow clone any type.\n * @param obj\n * @protected\n */\n public cloneObj<T>(obj: T): T {\n if (obj === null || typeof obj !== 'object') {\n return obj;\n }\n\n const proto = Object.getPrototypeOf(obj);\n\n // Fast path: plain object\n if (proto === Object.prototype || proto === null) {\n // Spread or assign preserves fast properties\n return { ...obj };\n }\n\n // Otherwise, preserve prototype for custom objects\n return Object.assign(Object.create(proto), obj);\n }\n\n /**\n * Recursively transforms all objects that are not arrays. Mapper is called on deeper objects first.\n * @param startObject object to start iterating from\n * @param mapper mapper to transform the various objects - argument is a copy of the original\n * @param preVisitor callback that is evaluated before iterating deeper.\n * If continues is false, we do not iterate deeper, current object is still mapped. - default: true\n * If shortcut is true, we do not iterate deeper, nor do we branch out, this mapper will be the last one called.\n * - Default false\n */\n public transformObject(\n startObject: object,\n mapper: (copy: object, orig: object) => unknown,\n preVisitor: (orig: object) => TransformContext = () => ({}),\n ): unknown {\n const defaults = this.defaultContext;\n const defaultCopyFlag = defaults.copy ?? true;\n const defaultContinues = defaults.continue ?? true;\n const defaultIgnoreKeys = defaults.ignoreKeys;\n const defaultShallowKeys = defaults.shallowKeys;\n const defaultDidShortCut = defaults.shortcut ?? false;\n\n // Code handles own stack instead of using recursion - this optimizes it for deep operations.\n let didShortCut = false;\n const resultWrap = { res: startObject };\n\n // Grows with stack\n const stack = [ startObject ];\n const stackParent: object[] = [ resultWrap ];\n const stackParentKey: string[] = [ 'res' ];\n\n // Grows with reverse stack - when popping down the stack, you realise you still want to map something.\n // Counter of stack size when we started adding the children of this object, going beyond this means a new parent\n const handleMapperOnLen: number[] = [];\n const mapperCopyStack: object[] = [];\n const mapperOrigStack: object[] = [];\n const mapperParent: object[] = [];\n const mapperParentKey: string[] = [];\n\n function handleMapper(): void {\n while (stack.length === handleMapperOnLen.at(-1)) {\n handleMapperOnLen.pop();\n const copyToMap = mapperCopyStack.pop()!;\n const origToMap = mapperOrigStack.pop()!;\n const parent = <Record<string, unknown>> mapperParent.pop()!;\n const parentKey = mapperParentKey.pop()!;\n parent[parentKey] = mapper(copyToMap, origToMap);\n }\n }\n\n while (stack.length > 0 && stack.length < this.maxStackSize) {\n const curObject = stack.pop()!;\n const curParent = stackParent.pop()!;\n const curKey = stackParentKey.pop()!;\n\n // Only add to the stack when you did not shortcut\n if (!didShortCut) {\n if (Array.isArray(curObject)) {\n const newArr = [ ...curObject ];\n handleMapperOnLen.push(stack.length);\n mapperCopyStack.push(newArr);\n mapperOrigStack.push(curObject);\n mapperParent.push(curParent);\n mapperParentKey.push(curKey);\n\n for (let index = curObject.length - 1; index >= 0; index--) {\n const val = curObject[index];\n if (val !== null && typeof val === 'object') {\n stack.push(val);\n stackParent.push(newArr);\n stackParentKey.push(index.toString());\n }\n }\n handleMapper();\n continue;\n }\n\n // Perform pre visit before expanding the stack\n const context = preVisitor(<any>curObject);\n const copyFlag = context.copy ?? defaultCopyFlag;\n const continues = context.continue ?? defaultContinues;\n const ignoreKeys = context.ignoreKeys ?? defaultIgnoreKeys;\n const shallowKeys = context.shallowKeys ?? defaultShallowKeys;\n didShortCut = context.shortcut ?? defaultDidShortCut;\n\n const copy = copyFlag ? this.cloneObj(curObject) : curObject;\n\n // Register that you want to be visited\n handleMapperOnLen.push(stack.length);\n mapperCopyStack.push(copy);\n mapperOrigStack.push(curObject);\n mapperParent.push(curParent);\n mapperParentKey.push(curKey);\n\n // Extend stack if needed. When shortcutted, should still unwind the stack, but no longer add to it.\n if (continues && !didShortCut) {\n for (const key in copy) {\n if (!Object.hasOwn(copy, key)) {\n continue;\n }\n const val = (<Record<string, unknown>> copy)[key];\n\n // If shallow copy required, do\n const onlyShallow = shallowKeys && shallowKeys?.has(key);\n if (onlyShallow) {\n // Do not add stack entry - assign straight away\n (<Record<string, unknown>> copy)[key] = this.cloneObj(val);\n }\n if (ignoreKeys && ignoreKeys.has(key)) {\n // Do not add stack entry\n continue;\n }\n if (!onlyShallow && val !== null && typeof val === 'object') {\n // Do add stack entry.\n stack.push(val);\n stackParentKey.push(key);\n stackParent.push(copy);\n }\n }\n }\n }\n handleMapper();\n }\n if (stack.length >= this.maxStackSize) {\n throw new Error('Transform object stack overflowed');\n }\n handleMapper();\n\n return <any> resultWrap.res;\n }\n\n /**\n * Visitor that visits all objects. Visits deeper objects first.\n */\n public visitObject(\n startObject: object,\n visitor: (orig: object) => void,\n preVisitor: (orig: object) => VisitContext = () => ({}),\n ): void {\n const defaults = this.defaultContext;\n const defaultContinues = defaults.continue ?? true;\n const defaultIgnoreKeys = defaults.ignoreKeys;\n const defaultShortcut = defaults.shortcut ?? false;\n\n let didShortCut = false;\n\n // Stack of things to preVisit\n const stack = [ startObject ];\n // When the stack is done preVisiting things above this lengths, visit the bellow\n const handleVisitorOnLen: number[] = [];\n const visitorStack: object[] = [];\n\n function handleVisitor(): void {\n while (stack.length === handleVisitorOnLen.at(-1)) {\n handleVisitorOnLen.pop();\n const toVisit = visitorStack.pop()!;\n visitor(toVisit);\n }\n }\n\n while (stack.length > 0 && stack.length < this.maxStackSize) {\n const curObject = stack.pop()!;\n\n if (!didShortCut) {\n if (Array.isArray(curObject)) {\n for (let i = curObject.length - 1; i >= 0; i--) {\n stack.push(curObject[i]);\n }\n handleVisitor();\n continue;\n }\n\n // Perform pre visit before expanding the stack\n const context = preVisitor(curObject);\n didShortCut = context.shortcut ?? defaultShortcut;\n const continues = context.continue ?? defaultContinues;\n const ignoreKeys = context.ignoreKeys ?? defaultIgnoreKeys;\n\n // Register that you want to be visited\n handleVisitorOnLen.push(stack.length);\n visitorStack.push(curObject);\n\n // Extend stack if needed. When shortcutted, should still unwind the stack, but no longer add to it.\n if (continues && !didShortCut) {\n for (const key in curObject) {\n if (!Object.hasOwn(curObject, key)) {\n continue;\n }\n if (ignoreKeys && ignoreKeys.has(key)) {\n continue;\n }\n const val = (<Record<string, unknown>> curObject)[key];\n if (val && typeof val === 'object') {\n stack.push(val);\n }\n }\n }\n }\n handleVisitor();\n }\n if (stack.length >= this.maxStackSize) {\n throw new Error('Transform object stack overflowed');\n }\n handleVisitor();\n }\n}\n"]}
{"version":3,"file":"TransformerObject.js","sourceRoot":"","sources":["../../../../lib/transformers/TransformerObject.ts"],"names":[],"mappings":"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","sourcesContent":["export interface VisitContext {\n /**\n * Whether you should stop iterating after this object. Default false.\n */\n shortcut?: boolean;\n /**\n * Whether you should continue iterating deeper with this object. Default true.\n */\n continue?: boolean;\n /**\n * Object keys that can be ignored, meaning they do not get visited.\n */\n ignoreKeys?: Set<string>;\n}\n\nexport interface TransformContext extends VisitContext {\n /**\n * Object keys that will be shallowly copied but not traversed.\n * When the same key is included here and in ignoreKeys, the copy will still be made.\n */\n shallowKeys?: Set<string>;\n /**\n * Whether the visited object should be shallowly copied or not. Defaults to true.\n */\n copy?: boolean;\n}\n\nexport interface SelectiveTraversalContext<Nodes> {\n /**\n * Nodes you should visit next. Defaults to empty list\n */\n next?: Nodes[];\n /**\n * Whether you should stop visiting after visiting this object. Default false.\n */\n shortcut?: boolean;\n}\n\nexport class TransformerObject {\n protected maxStackSize = 1_000_000;\n /**\n * Creates stateless transformer.\n * @param defaultContext\n */\n public constructor(protected readonly defaultContext: TransformContext = {}) {}\n\n public clone(newDefaultContext: TransformContext = {}): TransformerObject {\n return new TransformerObject({ ...this.defaultContext, ...newDefaultContext });\n }\n\n /**\n * Function to shallow clone any type.\n * @param obj\n * @protected\n */\n public cloneObj<T>(obj: T): T {\n if (obj === null || typeof obj !== 'object') {\n return obj;\n }\n\n const proto = Object.getPrototypeOf(obj);\n\n // Fast path: plain object\n if (proto === Object.prototype || proto === null) {\n // Spread or assign preserves fast properties\n return { ...obj };\n }\n\n // Otherwise, preserve prototype for custom objects\n return Object.assign(Object.create(proto), obj);\n }\n\n /**\n * Recursively transforms all objects that are not arrays. Mapper is called on deeper objects first.\n * @param startObject object to start iterating from\n * @param mapper mapper to transform the various objects - argument is a copy of the original\n * @param preVisitor callback that is evaluated before iterating deeper.\n * If continues is false, we do not iterate deeper, current object is still mapped. - default: true\n * If shortcut is true, we do not iterate deeper, nor do we branch out, this mapper will be the last one called.\n * - Default false\n */\n public transformObject(\n startObject: object,\n mapper: (copy: object, orig: object) => unknown,\n preVisitor: (orig: object) => TransformContext = () => ({}),\n ): unknown {\n const defaults = this.defaultContext;\n const defaultCopyFlag = defaults.copy ?? true;\n const defaultContinues = defaults.continue ?? true;\n const defaultIgnoreKeys = defaults.ignoreKeys;\n const defaultShallowKeys = defaults.shallowKeys;\n const defaultDidShortCut = defaults.shortcut ?? false;\n\n // Code handles own stack instead of using recursion - this optimizes it for deep operations.\n let didShortCut = false;\n const resultWrap = { res: startObject };\n\n // Grows with stack\n const stack = [ startObject ];\n const stackParent: object[] = [ resultWrap ];\n const stackParentKey: string[] = [ 'res' ];\n\n // Grows with reverse stack - when popping down the stack, you realise you still want to map something.\n // Counter of stack size when we started adding the children of this object, going beyond this means a new parent\n const handleMapperOnLen: number[] = [];\n const mapperCopyStack: object[] = [];\n const mapperOrigStack: object[] = [];\n const mapperParent: object[] = [];\n const mapperParentKey: string[] = [];\n\n function handleMapper(): void {\n while (stack.length === handleMapperOnLen.at(-1)) {\n handleMapperOnLen.pop();\n const copyToMap = mapperCopyStack.pop()!;\n const origToMap = mapperOrigStack.pop()!;\n const parent = <Record<string, unknown>> mapperParent.pop()!;\n const parentKey = mapperParentKey.pop()!;\n parent[parentKey] = mapper(copyToMap, origToMap);\n }\n }\n\n while (stack.length > 0 && stack.length < this.maxStackSize) {\n const curObject = stack.pop()!;\n const curParent = stackParent.pop()!;\n const curKey = stackParentKey.pop()!;\n\n // Only add to the stack when you did not shortcut\n if (!didShortCut) {\n if (Array.isArray(curObject)) {\n const newArr = [ ...curObject ];\n handleMapperOnLen.push(stack.length);\n mapperCopyStack.push(newArr);\n mapperOrigStack.push(curObject);\n mapperParent.push(curParent);\n mapperParentKey.push(curKey);\n\n for (let index = curObject.length - 1; index >= 0; index--) {\n const val = <unknown> curObject[index];\n if (val !== null && typeof val === 'object') {\n stack.push(val);\n stackParent.push(newArr);\n stackParentKey.push(index.toString());\n }\n }\n handleMapper();\n continue;\n }\n\n // Perform pre visit before expanding the stack\n const context = preVisitor(<any>curObject);\n const copyFlag = context.copy ?? defaultCopyFlag;\n const continues = context.continue ?? defaultContinues;\n const ignoreKeys = context.ignoreKeys ?? defaultIgnoreKeys;\n const shallowKeys = context.shallowKeys ?? defaultShallowKeys;\n didShortCut = context.shortcut ?? defaultDidShortCut;\n\n const copy = copyFlag ? this.cloneObj(curObject) : curObject;\n\n // Register that you want to be visited\n handleMapperOnLen.push(stack.length);\n mapperCopyStack.push(copy);\n mapperOrigStack.push(curObject);\n mapperParent.push(curParent);\n mapperParentKey.push(curKey);\n\n // Extend stack if needed. When shortcutted, should still unwind the stack, but no longer add to it.\n if (continues && !didShortCut) {\n for (const key in copy) {\n if (!Object.hasOwn(copy, key)) {\n continue;\n }\n const val = (<Record<string, unknown>> copy)[key];\n\n // If shallow copy required, do\n const onlyShallow = shallowKeys && shallowKeys?.has(key);\n if (onlyShallow) {\n // Do not add stack entry - assign straight away\n (<Record<string, unknown>> copy)[key] = this.cloneObj(val);\n }\n if (ignoreKeys && ignoreKeys.has(key)) {\n // Do not add stack entry\n continue;\n }\n if (!onlyShallow && val !== null && typeof val === 'object') {\n // Do add stack entry.\n stack.push(val);\n stackParentKey.push(key);\n stackParent.push(copy);\n }\n }\n }\n }\n handleMapper();\n }\n if (stack.length >= this.maxStackSize) {\n throw new Error('Transform object stack overflowed');\n }\n handleMapper();\n\n return <any> resultWrap.res;\n }\n\n /**\n * Visitor that visits all objects. Visits deeper objects first.\n */\n public visitObject(\n startObject: object,\n visitor: (orig: object) => void,\n preVisitor: (orig: object) => VisitContext = () => ({}),\n ): void {\n const defaults = this.defaultContext;\n const defaultContinues = defaults.continue ?? true;\n const defaultIgnoreKeys = defaults.ignoreKeys;\n const defaultShortcut = defaults.shortcut ?? false;\n\n let didShortCut = false;\n\n // Stack of things to preVisit\n const stack = [ startObject ];\n // When the stack is done preVisiting things above this lengths, visit the bellow\n const handleVisitorOnLen: number[] = [];\n const visitorStack: object[] = [];\n\n function handleVisitor(): void {\n while (stack.length === handleVisitorOnLen.at(-1)) {\n handleVisitorOnLen.pop();\n const toVisit = visitorStack.pop()!;\n visitor(toVisit);\n }\n }\n\n while (stack.length > 0 && stack.length < this.maxStackSize) {\n const curObject = stack.pop()!;\n\n if (!didShortCut) {\n if (Array.isArray(curObject)) {\n for (let i = curObject.length - 1; i >= 0; i--) {\n const val = <unknown> curObject[i];\n if (val !== null && typeof val === 'object') {\n stack.push(val);\n }\n }\n handleVisitor();\n continue;\n }\n\n // Perform pre visit before expanding the stack\n const context = preVisitor(curObject);\n didShortCut = context.shortcut ?? defaultShortcut;\n const continues = context.continue ?? defaultContinues;\n const ignoreKeys = context.ignoreKeys ?? defaultIgnoreKeys;\n\n // Register that you want to be visited\n handleVisitorOnLen.push(stack.length);\n visitorStack.push(curObject);\n\n // Extend stack if needed. When shortcutted, should still unwind the stack, but no longer add to it.\n if (continues && !didShortCut) {\n for (const key in curObject) {\n if (!Object.hasOwn(curObject, key)) {\n continue;\n }\n if (ignoreKeys && ignoreKeys.has(key)) {\n continue;\n }\n const val = (<Record<string, unknown>> curObject)[key];\n if (val && typeof val === 'object') {\n stack.push(val);\n }\n }\n }\n }\n handleVisitor();\n }\n if (stack.length >= this.maxStackSize) {\n throw new Error('Transform object stack overflowed');\n }\n handleVisitor();\n }\n}\n"]}

@@ -1,1 +0,1 @@

{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../lib/types.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * Type that is used by the Traqula core package to type raw objects/ Data Transfer Objects (DTO).\n * Enforces the presence of a type string, and that in case the subType key is present, it also be a string.\n */\nexport interface Typed<Type extends string = string> {\n type: Type;\n subType?: string;\n}\n\n/**\n * A {@link Typed} object that is sure to have a subType\n */\nexport interface SubTyped<Type extends string = string, SubType extends string = string> extends Typed<Type> {\n subType: SubType;\n}\n\n/**\n * Type used by the parser and generator builders of the core Traqula package to annotate\n * the relation between AST objects and the source string.\n */\nexport interface Localized {\n loc: SourceLocation;\n}\n\n/**\n * Wrapper type for localization,\n * can be used to state localization information about any other type (including primitive types)\n */\nexport interface Wrap<T> extends Localized {\n val: T;\n}\n\n/**\n * An AST node. Nodes are indexable by their types.\n * When generating, the SUBRULES called should be located within the current location range.\n */\nexport interface Node extends Localized, Typed {}\n\nexport interface SourceLocationBase {\n sourceLocationType: string;\n}\n\n/**\n * SourceLocation type that annotates that the node represents the AST representation of\n * the given range in the source string.\n */\nexport interface SourceLocationSource extends SourceLocationBase {\n sourceLocationType: 'source';\n start: number;\n end: number;\n}\n\n/**\n * Similar to {@link SourceLocationSource} but also carrying the source it related too.\n * All sourceLocation nodes that are descends of this one, relate themselves to this source.\n */\nexport interface SourceLocationInlinedSource extends SourceLocationBase, Localized {\n sourceLocationType: 'inlinedSource';\n /**\n * The string that will be used as the source for this node and the descends of this node.\n * Note that the generator will print the characters from newSource[0] until start. Likewise for the suffix.\n */\n newSource: string;\n /**\n * Behavior of the current loc, after replacing the source string.\n */\n loc: SourceLocation;\n /**\n * The range that this node replaces in the context of the original source.\n */\n start: number;\n end: number;\n startOnNew: number;\n endOnNew: number;\n}\n\n/**\n * NoStringManifestation means the node does not have a string representation.\n * For example the literal '5' has an integer type (which is an AST node),\n * but the type does not have an associated string representation.\n * When set to true, the node will not be printed, start and end are meaningless in this case.\n */\nexport interface SourceLocationNoMaterialize extends SourceLocationBase {\n sourceLocationType: 'noMaterialize';\n}\n\n/**\n * SourceLocation type that annotates that the node has been replaced\n * in relation to the original string by a new string.\n * It means that this node should be generated, and that the source string from start to end has been changed.\n */\nexport interface SourceLocationStringReplace extends SourceLocationBase {\n sourceLocationType: 'stringReplace';\n /**\n * The string that will replace the given range in the original source.\n */\n newSource: string;\n /**\n * The start of the region in the original source string that this node replaces.\n */\n start: number;\n /**\n * The end of the region in the original source string that this node replaces.\n */\n end: number;\n}\n\n/**\n * SourceLocation type that annotates that the node has been replaced in relation to the original string.\n * It means that this node should be generated, and that the source string from start to end has been changed.\n */\nexport interface SourceLocationNodeReplace extends SourceLocationBase {\n sourceLocationType: 'nodeReplace';\n /**\n * The start of the region in the original source string that this node replaces.\n */\n start: number;\n /**\n * The end of the region in the original source string that this node replaces.\n */\n end: number;\n}\n/**\n * Must have an ancestor of type {@link SourceLocationNodeReplace}\n */\nexport interface SourceLocationNodeAutoGenerate extends SourceLocationBase {\n sourceLocationType: 'autoGenerate';\n}\n\nexport type SourceLocation =\n // Relate yourself to the source\n | SourceLocationSource\n // Add a new source\n | SourceLocationInlinedSource\n // No not generate anything for the current node and descendants\n | SourceLocationNoMaterialize\n // Replace some range by a string\n | SourceLocationStringReplace\n // Replace this node by some autogen\n | SourceLocationNodeReplace\n // Auto gen current node.\n | SourceLocationNodeAutoGenerate;\n"]}
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../lib/types.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * Type that is used by the Traqula core package to type raw objects/ Data Transfer Objects (DTO).\n * Enforces the presence of a type string, and that in case the subType key is present, it also be a string.\n */\nexport interface Typed<Type extends string = string> {\n type: Type;\n subType?: string;\n}\n\n/**\n * A {@link Typed} object that is sure to have a subType\n */\nexport interface SubTyped<Type extends string = string, SubType extends string = string> extends Typed<Type> {\n subType: SubType;\n}\n\n/**\n * Type used by the parser and generator builders of the core Traqula package to annotate\n * the relation between AST objects and the source string.\n */\nexport interface Localized {\n loc: SourceLocation;\n}\n\n/**\n * Wrapper type for localization,\n * can be used to state localization information about any other type (including primitive types)\n */\nexport interface Wrap<T> extends Localized {\n val: T;\n}\n\n/**\n * An AST node. Nodes are indexable by their types.\n * When generating, the SUBRULES called should be located within the current location range.\n */\nexport interface Node extends Localized, Typed {}\n\nexport interface SourceLocationBase {\n sourceLocationType: string;\n}\n\n/**\n * SourceLocation type that annotates that the node represents the AST representation of\n * the given range in the source string.\n */\nexport interface SourceLocationSource extends SourceLocationBase {\n sourceLocationType: 'source';\n start: number;\n end: number;\n}\n\n/**\n * A {@link SourceLocation} that replaces a given range of the generators current source with some other source.\n * The SourceLocation of the node itself is described using the {@link loc} key,\n * and the state of the generator catches up the new source until {@link startOnNew}.\n */\nexport interface SourceLocationInlinedSource extends SourceLocationBase, Localized {\n sourceLocationType: 'inlinedSource';\n /**\n * The string that will be used as the source for this node and the descends of this node.\n * Note that the generator will print the characters from newSource[0] until start. Likewise for the suffix.\n */\n newSource: string;\n /**\n * Behavior of the current loc, after replacing the source string.\n * @deprecated There is in fact no subLocation handling, there never was.\n */\n loc: SourceLocation;\n /**\n * The range that this node replaces in the context of the original source.\n */\n start: number;\n end: number;\n /**\n * The range of characters within the {@link newSource} that can be targeted by descendants of this node.\n * This means anything outside this range in the newSource, will be generated by localization handling.\n */\n startOnNew: number;\n endOnNew: number;\n}\n\n/**\n * NoStringManifestation means the node does not have a string representation.\n * For example the literal '5' has an integer type (which is an AST node),\n * but the type does not have an associated string representation.\n * When set to true, the node will not be printed, start and end are meaningless in this case.\n */\nexport interface SourceLocationNoMaterialize extends SourceLocationBase {\n sourceLocationType: 'noMaterialize';\n}\n\n/**\n * SourceLocation type that annotates that the node has been replaced\n * in relation to the original string by a new string.\n * It means that this node should be generated, and that the source string from start to end has been changed.\n */\nexport interface SourceLocationStringReplace extends SourceLocationBase {\n sourceLocationType: 'stringReplace';\n /**\n * The string that will replace the given range in the original source.\n */\n newSource: string;\n /**\n * The start of the region in the original source string that this node replaces.\n */\n start: number;\n /**\n * The end of the region in the original source string that this node replaces.\n */\n end: number;\n}\n\n/**\n * SourceLocation type that annotates that the node has been replaced in relation to the original string.\n * It means that this node should be generated, and that the source string from start to end has been changed.\n */\nexport interface SourceLocationNodeReplace extends SourceLocationBase {\n sourceLocationType: 'nodeReplace';\n /**\n * The start of the region in the original source string that this node replaces.\n */\n start: number;\n /**\n * The end of the region in the original source string that this node replaces.\n */\n end: number;\n}\n/**\n * Must have an ancestor of type {@link SourceLocationNodeReplace}\n */\nexport interface SourceLocationNodeAutoGenerate extends SourceLocationBase {\n sourceLocationType: 'autoGenerate';\n}\n\nexport type SourceLocation =\n // Relate yourself to the source\n | SourceLocationSource\n // Add a new source\n | SourceLocationInlinedSource\n // No not generate anything for the current node and descendants\n | SourceLocationNoMaterialize\n // Replace some range by a string\n | SourceLocationStringReplace\n // Replace this node by some autogen\n | SourceLocationNodeReplace\n // Auto gen current node.\n | SourceLocationNodeAutoGenerate;\n"]}

@@ -10,7 +10,28 @@ import type { IToken } from '@traqula/chevrotain';

export declare class AstCoreFactory implements AstCoreFactoryArgs {
/**
* Whether this AstFactory will track source location. Default: true.
* In case source location is not tracked,
* each generated node using this factory will be {@link SourceLocationNodeAutoGenerate}
*/
tracksSourceLocation: boolean;
constructor(args?: Partial<AstCoreFactoryArgs>);
/**
* Wrap any type into an object that tracks the source location of tha value.
* @param val the value to wrap
* @param loc the source location for that value
*/
wrap<T>(val: T, loc: SourceLocation): Wrap<T>;
/**
* Whether the provided value is an object that tracks source location.
* @param obj
*/
isLocalized(obj: unknown): obj is Localized;
/**
* Compute the source location of an element based on the elements it contains.
* The provided arguments should be in order of occurrence in the string.
*/
sourceLocation(...elements: (undefined | IToken | Localized)[]): SourceLocation;
/**
* Generate a source location indicating the no materialization.
*/
sourceLocationNoMaterialize(): SourceLocation;

@@ -21,26 +42,91 @@ /**

dematerialized<T extends Node>(arg: T): T;
/**
* Given a value and some mapper from objects to objects,
* map all containing items in case it is an array,
* otherwise map the provided value in case it is an object, finally, do nothing.
* @param value the value to map
* @param mapper the function mapping an object to another object.
*/
safeObjectTransform(value: unknown, mapper: (some: object) => any): any;
/**
* Given a (AST) tree, return a copy of that tree where it and it's
* descendents all have a {@link SourceLocationNodeAutoGenerate} localization.
*/
forcedAutoGenTree<T extends object>(obj: T): T;
/**
* In case the provided Node is not yet materialized, force it to be autoGenerated.
*/
forceMaterialized<T extends Node>(arg: T): T;
/**
* Check whether an object is in fact a {@link SourceLocation}.
* @param loc
*/
isSourceLocation(loc: object): loc is SourceLocation;
/**
* Create a {@link SourceLocation} that indicates what range of characters this node represents in the source string.
*/
sourceLocationSource(start: number, end: number): SourceLocationSource;
/**
* {@inheritDoc SourceLocationInlinedSource}
* Create a {@link SourceLocation} that indicates a given range of the current range should be replaced by
* a new source.
*/
sourceLocationInlinedSource(newSource: string, subLoc: SourceLocation, start: number, end: number, startOnNew?: number, endOnNew?: number): SourceLocation;
/**
* Guard to check if an object is a {@link SourceLocation} of type {@link SourceLocationInlinedSource}.
*/
isSourceLocationInlinedSource(loc: object): loc is SourceLocationInlinedSource;
/**
* Create a {@link SourceLocation} indicating the node should be autoGenerated by a generator.
*/
gen(): SourceLocationNodeAutoGenerate;
/**
* Guard to check if an object is a {@link SourceLocation} of type {@link SourceLocationSource}.
*/
isSourceLocationSource(loc: object): loc is SourceLocationSource;
/**
* Create a {@link SourceLocation} that indicates this node,
* representing a range of characters in the original string, should be replaced by some string during generation.
*/
sourceLocationStringReplace(newSource: string, start: number, end: number): SourceLocation;
/**
* Guard to check if an object is a {@link SourceLocation} of type {@link SourceLocationStringReplace}.
* @param loc
*/
isSourceLocationStringReplace(loc: object): loc is SourceLocationStringReplace;
/**
* Given a sourceLocation, generate a new {@link SourceLocation}
* that indicates the range of the given location should now be autoGenerated
*/
sourceLocationNodeReplaceUnsafe(loc: SourceLocation): SourceLocationNodeReplace;
sourceLocationNodeReplace(location: SourceLocationSource): SourceLocationNodeReplace;
sourceLocationNodeReplace(start: number, end: number): SourceLocationNodeReplace;
/**
* Guard to check if an object is a {@link SourceLocation} of type {@link SourceLocationNodeReplace}.
*/
isSourceLocationNodeReplace(loc: object): loc is SourceLocationNodeReplace;
/**
* Guard to check if an object is a {@link SourceLocation} of type {@link SourceLocationNodeAutoGenerate}.
*/
isSourceLocationNodeAutoGenerate(loc: object): loc is SourceLocationNodeAutoGenerate;
/**
* Check whether the provided {@link SourceLocation} expects the generator to autoGenerate.
*/
isPrintingLoc(loc: SourceLocation): boolean;
/**
* A simple filter that will only execute the provided callback when the provided {@link SourceLocation}
* expects the generator steps to autoGenerate.
*/
printFilter(node: Localized, callback: () => void): void;
/**
* Guard to check if an object is a {@link SourceLocation} of type {@link SourceLocationNoMaterialize}.
*/
isSourceLocationNoMaterialize(loc: object): loc is SourceLocationNoMaterialize;
/**
* Guard to check if an object is the specified Type: {@link Typed}.
*/
isOfType<Type extends string>(obj: object, type: Type): obj is Typed<Type>;
/**
* Guard to check if an object is the specified Type: {@link SubTyped}.
*/
isOfSubType<Type extends string, SubType extends string>(obj: object, type: Type, subType: SubType): obj is SubTyped<Type, SubType>;
}
export class AstCoreFactory {
/**
* Whether this AstFactory will track source location. Default: true.
* In case source location is not tracked,
* each generated node using this factory will be {@link SourceLocationNodeAutoGenerate}
*/
tracksSourceLocation;

@@ -6,5 +11,14 @@ constructor(args = {}) {

}
/**
* Wrap any type into an object that tracks the source location of tha value.
* @param val the value to wrap
* @param loc the source location for that value
*/
wrap(val, loc) {
return { val, loc };
}
/**
* Whether the provided value is an object that tracks source location.
* @param obj
*/
isLocalized(obj) {

@@ -14,2 +28,6 @@ return typeof obj === 'object' && obj !== null && 'loc' in obj &&

}
/**
* Compute the source location of an element based on the elements it contains.
* The provided arguments should be in order of occurrence in the string.
*/
sourceLocation(...elements) {

@@ -40,2 +58,5 @@ if (!this.tracksSourceLocation) {

}
/**
* Generate a source location indicating the no materialization.
*/
sourceLocationNoMaterialize() {

@@ -53,2 +74,9 @@ if (!this.tracksSourceLocation) {

}
/**
* Given a value and some mapper from objects to objects,
* map all containing items in case it is an array,
* otherwise map the provided value in case it is an object, finally, do nothing.
* @param value the value to map
* @param mapper the function mapping an object to another object.
*/
safeObjectTransform(value, mapper) {

@@ -64,2 +92,6 @@ if (value && typeof value === 'object') {

}
/**
* Given a (AST) tree, return a copy of that tree where it and it's
* descendents all have a {@link SourceLocationNodeAutoGenerate} localization.
*/
forcedAutoGenTree(obj) {

@@ -75,2 +107,5 @@ const copy = { ...obj };

}
/**
* In case the provided Node is not yet materialized, force it to be autoGenerated.
*/
forceMaterialized(arg) {

@@ -82,5 +117,12 @@ if (this.isSourceLocationNoMaterialize(arg.loc)) {

}
/**
* Check whether an object is in fact a {@link SourceLocation}.
* @param loc
*/
isSourceLocation(loc) {
return 'sourceLocationType' in loc;
}
/**
* Create a {@link SourceLocation} that indicates what range of characters this node represents in the source string.
*/
sourceLocationSource(start, end) {

@@ -94,3 +136,4 @@ return {

/**
* {@inheritDoc SourceLocationInlinedSource}
* Create a {@link SourceLocation} that indicates a given range of the current range should be replaced by
* a new source.
*/

@@ -116,11 +159,24 @@ sourceLocationInlinedSource(newSource, subLoc, start, end, startOnNew = 0, endOnNew = newSource.length) {

;
/**
* Guard to check if an object is a {@link SourceLocation} of type {@link SourceLocationInlinedSource}.
*/
isSourceLocationInlinedSource(loc) {
return this.isSourceLocation(loc) && loc.sourceLocationType === 'inlinedSource';
}
/**
* Create a {@link SourceLocation} indicating the node should be autoGenerated by a generator.
*/
gen() {
return { sourceLocationType: 'autoGenerate' };
}
/**
* Guard to check if an object is a {@link SourceLocation} of type {@link SourceLocationSource}.
*/
isSourceLocationSource(loc) {
return this.isSourceLocation(loc) && loc.sourceLocationType === 'source';
}
/**
* Create a {@link SourceLocation} that indicates this node,
* representing a range of characters in the original string, should be replaced by some string during generation.
*/
sourceLocationStringReplace(newSource, start, end) {

@@ -132,5 +188,13 @@ if (!this.tracksSourceLocation) {

}
/**
* Guard to check if an object is a {@link SourceLocation} of type {@link SourceLocationStringReplace}.
* @param loc
*/
isSourceLocationStringReplace(loc) {
return this.isSourceLocation(loc) && loc.sourceLocationType === 'stringReplace';
}
/**
* Given a sourceLocation, generate a new {@link SourceLocation}
* that indicates the range of the given location should now be autoGenerated
*/
sourceLocationNodeReplaceUnsafe(loc) {

@@ -162,8 +226,17 @@ if (this.isSourceLocationSource(loc)) {

}
/**
* Guard to check if an object is a {@link SourceLocation} of type {@link SourceLocationNodeReplace}.
*/
isSourceLocationNodeReplace(loc) {
return this.isSourceLocation(loc) && loc.sourceLocationType === 'nodeReplace';
}
/**
* Guard to check if an object is a {@link SourceLocation} of type {@link SourceLocationNodeAutoGenerate}.
*/
isSourceLocationNodeAutoGenerate(loc) {
return this.isSourceLocation(loc) && loc.sourceLocationType === 'autoGenerate';
}
/**
* Check whether the provided {@link SourceLocation} expects the generator to autoGenerate.
*/
isPrintingLoc(loc) {

@@ -174,2 +247,6 @@ return this.isSourceLocationNodeReplace(loc) ||

}
/**
* A simple filter that will only execute the provided callback when the provided {@link SourceLocation}
* expects the generator steps to autoGenerate.
*/
printFilter(node, callback) {

@@ -180,5 +257,11 @@ if (this.isPrintingLoc(node.loc)) {

}
/**
* Guard to check if an object is a {@link SourceLocation} of type {@link SourceLocationNoMaterialize}.
*/
isSourceLocationNoMaterialize(loc) {
return this.isSourceLocation(loc) && loc.sourceLocationType === 'noMaterialize';
}
/**
* Guard to check if an object is the specified Type: {@link Typed}.
*/
isOfType(obj, type) {

@@ -188,2 +271,5 @@ const casted = obj;

}
/**
* Guard to check if an object is the specified Type: {@link SubTyped}.
*/
isOfSubType(obj, type, subType) {

@@ -190,0 +276,0 @@ const temp = obj;

@@ -1,1 +0,1 @@

{"version":3,"file":"AstCoreFactory.js","sourceRoot":"","sources":["../../../lib/AstCoreFactory.ts"],"names":[],"mappings":"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","sourcesContent":["import type { IToken } from '@traqula/chevrotain';\n\nimport type {\n SourceLocation,\n SourceLocationNodeAutoGenerate,\n SourceLocationNodeReplace,\n SourceLocationNoMaterialize,\n SourceLocationSource,\n SourceLocationStringReplace,\n Node,\n Localized,\n Wrap,\n Typed,\n SubTyped,\n SourceLocationInlinedSource,\n} from './types.js';\n\nexport interface AstCoreFactoryArgs {\n /**\n * Whether the AstFactory can track sources, if not, the sourceLocation function returns autoGen. Default true\n */\n tracksSourceLocation: boolean;\n}\n\nexport class AstCoreFactory implements AstCoreFactoryArgs {\n public tracksSourceLocation: boolean;\n public constructor(args: Partial<AstCoreFactoryArgs> = {}) {\n this.tracksSourceLocation = args.tracksSourceLocation ?? true;\n }\n\n public wrap<T>(val: T, loc: SourceLocation): Wrap<T> {\n return { val, loc };\n }\n\n public isLocalized(obj: unknown): obj is Localized {\n return typeof obj === 'object' && obj !== null && 'loc' in obj &&\n typeof obj.loc === 'object' && obj.loc !== null && 'sourceLocationType' in obj.loc;\n }\n\n public sourceLocation(...elements: (undefined | IToken | Localized)[]): SourceLocation {\n if (!this.tracksSourceLocation) {\n return this.gen();\n }\n\n const pureElements = elements.filter(x => x !== undefined);\n if (pureElements.length === 0) {\n return this.sourceLocationNoMaterialize();\n }\n\n const filtered = pureElements.filter(element =>\n !this.isLocalized(element) || this.isSourceLocationSource(element.loc) ||\n this.isSourceLocationStringReplace(element.loc) || this.isSourceLocationNodeReplace(element.loc));\n if (filtered.length === 0) {\n return this.gen();\n }\n const first = filtered.at(0)!;\n const last = filtered.at(-1)!;\n return {\n sourceLocationType: 'source',\n start: this.isLocalized(first) ?\n (<SourceLocationSource | SourceLocationStringReplace> first.loc).start :\n first.startOffset,\n end: this.isLocalized(last) ?\n (<SourceLocationSource | SourceLocationStringReplace> last.loc).end :\n (last.endOffset! + 1),\n };\n }\n\n public sourceLocationNoMaterialize(): SourceLocation {\n if (!this.tracksSourceLocation) {\n return this.gen();\n }\n return { sourceLocationType: 'noMaterialize' };\n }\n\n /**\n * Returns a copy of the argument that is not materialized\n */\n public dematerialized<T extends Node>(arg: T): T {\n return { ...arg, loc: this.sourceLocationNoMaterialize() };\n }\n\n public safeObjectTransform(value: unknown, mapper: (some: object) => any): any {\n if (value && typeof value === 'object') {\n // If you wonder why this is all so hard, this is the reason. We cannot lose the methods of our Array objects\n if (Array.isArray(value)) {\n return value.map(x => this.safeObjectTransform(x, mapper));\n }\n return mapper(value);\n }\n return value;\n }\n\n public forcedAutoGenTree<T extends object>(obj: T): T {\n const copy = { ...obj };\n for (const [ key, value ] of Object.entries(copy)) {\n (<Record<string, object>> copy)[key] = this.safeObjectTransform(value, obj => this.forcedAutoGenTree(obj));\n }\n if (this.isLocalized(copy)) {\n copy.loc = this.gen();\n }\n return copy;\n }\n\n public forceMaterialized<T extends Node>(arg: T): T {\n if (this.isSourceLocationNoMaterialize(arg.loc)) {\n return this.forcedAutoGenTree(arg);\n }\n return { ...arg };\n }\n\n public isSourceLocation(loc: object): loc is SourceLocation {\n return 'sourceLocationType' in loc;\n }\n\n public sourceLocationSource(start: number, end: number): SourceLocationSource {\n return {\n sourceLocationType: 'source',\n start,\n end,\n };\n }\n\n /**\n * {@inheritDoc SourceLocationInlinedSource}\n */\n public sourceLocationInlinedSource(\n newSource: string,\n subLoc: SourceLocation,\n start: number,\n end: number,\n startOnNew = 0,\n endOnNew: number = newSource.length,\n ): SourceLocation {\n if (!this.tracksSourceLocation) {\n return this.gen();\n }\n if (this.isSourceLocationSource(subLoc)) {\n startOnNew = subLoc.start;\n endOnNew = subLoc.end;\n }\n return {\n sourceLocationType: 'inlinedSource',\n newSource,\n start,\n end,\n loc: subLoc,\n startOnNew,\n endOnNew,\n }satisfies SourceLocationInlinedSource;\n };\n\n public isSourceLocationInlinedSource(loc: object): loc is SourceLocationInlinedSource {\n return this.isSourceLocation(loc) && loc.sourceLocationType === 'inlinedSource';\n }\n\n public gen(): SourceLocationNodeAutoGenerate {\n return { sourceLocationType: 'autoGenerate' };\n }\n\n public isSourceLocationSource(loc: object): loc is SourceLocationSource {\n return this.isSourceLocation(loc) && loc.sourceLocationType === 'source';\n }\n\n public sourceLocationStringReplace(newSource: string, start: number, end: number): SourceLocation {\n if (!this.tracksSourceLocation) {\n return this.gen();\n }\n return { sourceLocationType: 'stringReplace', newSource, start, end } satisfies SourceLocationStringReplace;\n }\n\n public isSourceLocationStringReplace(loc: object): loc is SourceLocationStringReplace {\n return this.isSourceLocation(loc) && loc.sourceLocationType === 'stringReplace';\n }\n\n public sourceLocationNodeReplaceUnsafe(loc: SourceLocation): SourceLocationNodeReplace {\n if (this.isSourceLocationSource(loc)) {\n return this.sourceLocationNodeReplace(loc);\n }\n if (this.isSourceLocationInlinedSource(loc)) {\n return this.sourceLocationNodeReplaceUnsafe(loc.loc);\n }\n throw new Error(`Cannot convert SourceLocation of type ${loc.sourceLocationType} to SourceLocationNodeReplace`);\n }\n\n public sourceLocationNodeReplace(location: SourceLocationSource): SourceLocationNodeReplace;\n public sourceLocationNodeReplace(start: number, end: number): SourceLocationNodeReplace;\n public sourceLocationNodeReplace(startOrLoc: number | SourceLocationSource, end?: number): SourceLocationNodeReplace {\n let starting;\n let ending;\n if (typeof startOrLoc === 'number') {\n starting = startOrLoc;\n ending = end!;\n } else {\n starting = startOrLoc.start;\n ending = startOrLoc.end;\n }\n return {\n sourceLocationType: 'nodeReplace',\n start: starting,\n end: ending,\n };\n }\n\n public isSourceLocationNodeReplace(loc: object): loc is SourceLocationNodeReplace {\n return this.isSourceLocation(loc) && loc.sourceLocationType === 'nodeReplace';\n }\n\n public isSourceLocationNodeAutoGenerate(loc: object): loc is SourceLocationNodeAutoGenerate {\n return this.isSourceLocation(loc) && loc.sourceLocationType === 'autoGenerate';\n }\n\n public isPrintingLoc(loc: SourceLocation): boolean {\n return this.isSourceLocationNodeReplace(loc) ||\n this.isSourceLocationNodeAutoGenerate(loc) ||\n (this.isSourceLocationInlinedSource(loc) && this.isPrintingLoc(loc.loc));\n }\n\n public printFilter(node: Localized, callback: () => void): void {\n if (this.isPrintingLoc(node.loc)) {\n callback();\n }\n }\n\n public isSourceLocationNoMaterialize(loc: object): loc is SourceLocationNoMaterialize {\n return this.isSourceLocation(loc) && loc.sourceLocationType === 'noMaterialize';\n }\n\n public isOfType<Type extends string>(obj: object, type: Type): obj is Typed<Type> {\n const casted: { type?: any } = obj;\n return casted.type === type;\n }\n\n public isOfSubType<Type extends string, SubType extends string>(obj: object, type: Type, subType: SubType):\n obj is SubTyped<Type, SubType> {\n const temp: { type?: unknown; subType?: unknown } = obj;\n return temp.type === type && temp.subType === subType;\n }\n}\n"]}
{"version":3,"file":"AstCoreFactory.js","sourceRoot":"","sources":["../../../lib/AstCoreFactory.ts"],"names":[],"mappings":"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","sourcesContent":["import type { IToken } from '@traqula/chevrotain';\n\nimport type {\n SourceLocation,\n SourceLocationNodeAutoGenerate,\n SourceLocationNodeReplace,\n SourceLocationNoMaterialize,\n SourceLocationSource,\n SourceLocationStringReplace,\n Node,\n Localized,\n Wrap,\n Typed,\n SubTyped,\n SourceLocationInlinedSource,\n} from './types.js';\n\nexport interface AstCoreFactoryArgs {\n /**\n * Whether the AstFactory can track sources, if not, the sourceLocation function returns autoGen. Default true\n */\n tracksSourceLocation: boolean;\n}\n\nexport class AstCoreFactory implements AstCoreFactoryArgs {\n /**\n * Whether this AstFactory will track source location. Default: true.\n * In case source location is not tracked,\n * each generated node using this factory will be {@link SourceLocationNodeAutoGenerate}\n */\n public tracksSourceLocation: boolean;\n\n public constructor(args: Partial<AstCoreFactoryArgs> = {}) {\n this.tracksSourceLocation = args.tracksSourceLocation ?? true;\n }\n\n /**\n * Wrap any type into an object that tracks the source location of tha value.\n * @param val the value to wrap\n * @param loc the source location for that value\n */\n public wrap<T>(val: T, loc: SourceLocation): Wrap<T> {\n return { val, loc };\n }\n\n /**\n * Whether the provided value is an object that tracks source location.\n * @param obj\n */\n public isLocalized(obj: unknown): obj is Localized {\n return typeof obj === 'object' && obj !== null && 'loc' in obj &&\n typeof obj.loc === 'object' && obj.loc !== null && 'sourceLocationType' in obj.loc;\n }\n\n /**\n * Compute the source location of an element based on the elements it contains.\n * The provided arguments should be in order of occurrence in the string.\n */\n public sourceLocation(...elements: (undefined | IToken | Localized)[]): SourceLocation {\n if (!this.tracksSourceLocation) {\n return this.gen();\n }\n\n const pureElements = elements.filter(x => x !== undefined);\n if (pureElements.length === 0) {\n return this.sourceLocationNoMaterialize();\n }\n\n const filtered = pureElements.filter(element =>\n !this.isLocalized(element) || this.isSourceLocationSource(element.loc) ||\n this.isSourceLocationStringReplace(element.loc) || this.isSourceLocationNodeReplace(element.loc));\n if (filtered.length === 0) {\n return this.gen();\n }\n const first = filtered.at(0)!;\n const last = filtered.at(-1)!;\n return {\n sourceLocationType: 'source',\n start: this.isLocalized(first) ?\n (<SourceLocationSource | SourceLocationStringReplace> first.loc).start :\n first.startOffset,\n end: this.isLocalized(last) ?\n (<SourceLocationSource | SourceLocationStringReplace> last.loc).end :\n (last.endOffset! + 1),\n };\n }\n\n /**\n * Generate a source location indicating the no materialization.\n */\n public sourceLocationNoMaterialize(): SourceLocation {\n if (!this.tracksSourceLocation) {\n return this.gen();\n }\n return { sourceLocationType: 'noMaterialize' };\n }\n\n /**\n * Returns a copy of the argument that is not materialized\n */\n public dematerialized<T extends Node>(arg: T): T {\n return { ...arg, loc: this.sourceLocationNoMaterialize() };\n }\n\n /**\n * Given a value and some mapper from objects to objects,\n * map all containing items in case it is an array,\n * otherwise map the provided value in case it is an object, finally, do nothing.\n * @param value the value to map\n * @param mapper the function mapping an object to another object.\n */\n public safeObjectTransform(value: unknown, mapper: (some: object) => any): any {\n if (value && typeof value === 'object') {\n // If you wonder why this is all so hard, this is the reason. We cannot lose the methods of our Array objects\n if (Array.isArray(value)) {\n return value.map(x => this.safeObjectTransform(x, mapper));\n }\n return mapper(value);\n }\n return value;\n }\n\n /**\n * Given a (AST) tree, return a copy of that tree where it and it's\n * descendents all have a {@link SourceLocationNodeAutoGenerate} localization.\n */\n public forcedAutoGenTree<T extends object>(obj: T): T {\n const copy = { ...obj };\n for (const [ key, value ] of Object.entries(copy)) {\n (<Record<string, object>> copy)[key] = this.safeObjectTransform(value, obj => this.forcedAutoGenTree(obj));\n }\n if (this.isLocalized(copy)) {\n copy.loc = this.gen();\n }\n return copy;\n }\n\n /**\n * In case the provided Node is not yet materialized, force it to be autoGenerated.\n */\n public forceMaterialized<T extends Node>(arg: T): T {\n if (this.isSourceLocationNoMaterialize(arg.loc)) {\n return this.forcedAutoGenTree(arg);\n }\n return { ...arg };\n }\n\n /**\n * Check whether an object is in fact a {@link SourceLocation}.\n * @param loc\n */\n public isSourceLocation(loc: object): loc is SourceLocation {\n return 'sourceLocationType' in loc;\n }\n\n /**\n * Create a {@link SourceLocation} that indicates what range of characters this node represents in the source string.\n */\n public sourceLocationSource(start: number, end: number): SourceLocationSource {\n return {\n sourceLocationType: 'source',\n start,\n end,\n };\n }\n\n /**\n * Create a {@link SourceLocation} that indicates a given range of the current range should be replaced by\n * a new source.\n */\n public sourceLocationInlinedSource(\n newSource: string,\n subLoc: SourceLocation,\n start: number,\n end: number,\n startOnNew = 0,\n endOnNew: number = newSource.length,\n ): SourceLocation {\n if (!this.tracksSourceLocation) {\n return this.gen();\n }\n if (this.isSourceLocationSource(subLoc)) {\n startOnNew = subLoc.start;\n endOnNew = subLoc.end;\n }\n return {\n sourceLocationType: 'inlinedSource',\n newSource,\n start,\n end,\n loc: subLoc,\n startOnNew,\n endOnNew,\n }satisfies SourceLocationInlinedSource;\n };\n\n /**\n * Guard to check if an object is a {@link SourceLocation} of type {@link SourceLocationInlinedSource}.\n */\n public isSourceLocationInlinedSource(loc: object): loc is SourceLocationInlinedSource {\n return this.isSourceLocation(loc) && loc.sourceLocationType === 'inlinedSource';\n }\n\n /**\n * Create a {@link SourceLocation} indicating the node should be autoGenerated by a generator.\n */\n public gen(): SourceLocationNodeAutoGenerate {\n return { sourceLocationType: 'autoGenerate' };\n }\n\n /**\n * Guard to check if an object is a {@link SourceLocation} of type {@link SourceLocationSource}.\n */\n public isSourceLocationSource(loc: object): loc is SourceLocationSource {\n return this.isSourceLocation(loc) && loc.sourceLocationType === 'source';\n }\n\n /**\n * Create a {@link SourceLocation} that indicates this node,\n * representing a range of characters in the original string, should be replaced by some string during generation.\n */\n public sourceLocationStringReplace(newSource: string, start: number, end: number): SourceLocation {\n if (!this.tracksSourceLocation) {\n return this.gen();\n }\n return { sourceLocationType: 'stringReplace', newSource, start, end } satisfies SourceLocationStringReplace;\n }\n\n /**\n * Guard to check if an object is a {@link SourceLocation} of type {@link SourceLocationStringReplace}.\n * @param loc\n */\n public isSourceLocationStringReplace(loc: object): loc is SourceLocationStringReplace {\n return this.isSourceLocation(loc) && loc.sourceLocationType === 'stringReplace';\n }\n\n /**\n * Given a sourceLocation, generate a new {@link SourceLocation}\n * that indicates the range of the given location should now be autoGenerated\n */\n public sourceLocationNodeReplaceUnsafe(loc: SourceLocation): SourceLocationNodeReplace {\n if (this.isSourceLocationSource(loc)) {\n return this.sourceLocationNodeReplace(loc);\n }\n if (this.isSourceLocationInlinedSource(loc)) {\n return this.sourceLocationNodeReplaceUnsafe(loc.loc);\n }\n throw new Error(`Cannot convert SourceLocation of type ${loc.sourceLocationType} to SourceLocationNodeReplace`);\n }\n\n public sourceLocationNodeReplace(location: SourceLocationSource): SourceLocationNodeReplace;\n public sourceLocationNodeReplace(start: number, end: number): SourceLocationNodeReplace;\n public sourceLocationNodeReplace(startOrLoc: number | SourceLocationSource, end?: number): SourceLocationNodeReplace {\n let starting;\n let ending;\n if (typeof startOrLoc === 'number') {\n starting = startOrLoc;\n ending = end!;\n } else {\n starting = startOrLoc.start;\n ending = startOrLoc.end;\n }\n return {\n sourceLocationType: 'nodeReplace',\n start: starting,\n end: ending,\n };\n }\n\n /**\n * Guard to check if an object is a {@link SourceLocation} of type {@link SourceLocationNodeReplace}.\n */\n public isSourceLocationNodeReplace(loc: object): loc is SourceLocationNodeReplace {\n return this.isSourceLocation(loc) && loc.sourceLocationType === 'nodeReplace';\n }\n\n /**\n * Guard to check if an object is a {@link SourceLocation} of type {@link SourceLocationNodeAutoGenerate}.\n */\n public isSourceLocationNodeAutoGenerate(loc: object): loc is SourceLocationNodeAutoGenerate {\n return this.isSourceLocation(loc) && loc.sourceLocationType === 'autoGenerate';\n }\n\n /**\n * Check whether the provided {@link SourceLocation} expects the generator to autoGenerate.\n */\n public isPrintingLoc(loc: SourceLocation): boolean {\n return this.isSourceLocationNodeReplace(loc) ||\n this.isSourceLocationNodeAutoGenerate(loc) ||\n (this.isSourceLocationInlinedSource(loc) && this.isPrintingLoc(loc.loc));\n }\n\n /**\n * A simple filter that will only execute the provided callback when the provided {@link SourceLocation}\n * expects the generator steps to autoGenerate.\n */\n public printFilter(node: Localized, callback: () => void): void {\n if (this.isPrintingLoc(node.loc)) {\n callback();\n }\n }\n\n /**\n * Guard to check if an object is a {@link SourceLocation} of type {@link SourceLocationNoMaterialize}.\n */\n public isSourceLocationNoMaterialize(loc: object): loc is SourceLocationNoMaterialize {\n return this.isSourceLocation(loc) && loc.sourceLocationType === 'noMaterialize';\n }\n\n /**\n * Guard to check if an object is the specified Type: {@link Typed}.\n */\n public isOfType<Type extends string>(obj: object, type: Type): obj is Typed<Type> {\n const casted: { type?: any } = obj;\n return casted.type === type;\n }\n\n /**\n * Guard to check if an object is the specified Type: {@link SubTyped}.\n */\n public isOfSubType<Type extends string, SubType extends string>(obj: object, type: Type, subType: SubType):\n obj is SubTyped<Type, SubType> {\n const temp: { type?: unknown; subType?: unknown } = obj;\n return temp.type === type && temp.subType === subType;\n }\n}\n"]}

@@ -15,2 +15,6 @@ import { AstCoreFactory } from '../AstCoreFactory.js';

protected origSource: string;
/**
* Reference to the latest SourceLocationInlinedSource this generator handled (used for idempotency)
* @protected
*/
protected handledInlineSource: SourceLocationInlinedSource | undefined;

@@ -17,0 +21,0 @@ protected generatedUntil: number;

@@ -8,2 +8,6 @@ import { AstCoreFactory } from '../AstCoreFactory.js';

origSource = '';
/**
* Reference to the latest SourceLocationInlinedSource this generator handled (used for idempotency)
* @protected
*/
handledInlineSource;

@@ -83,5 +87,7 @@ generatedUntil = 0;

if (this.factory.isSourceLocationInlinedSource(localized.loc) && this.handledInlineSource !== localized.loc) {
// Calling handleLoc on the same AST multiple times should be the same as doing it once.
// Idempotence: calling handleLoc on the same AST multiple times should be the same as doing it once.
this.handledInlineSource = localized.loc;
// Like normal, catch up until the start of what this node represents.
this.catchup(localized.loc.start);
// Save pointer location of current source and register new source.
const origSource = this.origSource;

@@ -91,9 +97,12 @@ const origPointer = this.generatedUntil;

this.generatedUntil = 0;
// Catchup the new source to where this node starts representing the source.
this.catchup(localized.loc.startOnNew);
this.handleLoc(localized.loc, handle);
const ret = this.handleLoc(localized.loc, handle);
// Catchup so the entire new source is generated outside what this node represents.
this.generatedUntil = localized.loc.endOnNew;
this.catchup(this.origSource.length);
// Recover the original source and register that you generated the range of this node.
this.origSource = origSource;
this.generatedUntil = Math.max(origPointer, localized.loc.end);
return;
return ret;
}

@@ -100,0 +109,0 @@ // If autoGenerate - do nothing

@@ -1,1 +0,1 @@

{"version":3,"file":"dynamicGenerator.js","sourceRoot":"","sources":["../../../../lib/generator-builder/dynamicGenerator.ts"],"names":[],"mappings":"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","sourcesContent":["import { AstCoreFactory } from '../AstCoreFactory.js';\nimport type { SourceLocationInlinedSource } from '../types.js';\nimport { traqulaIndentation, traqulaNewlineAlternative } from '../utils.js';\nimport type { GenRuleMap } from './builderTypes.js';\nimport type { GeneratorRule, RuleDefArg } from './generatorTypes.js';\n\nexport interface GeneratorContext {\n [traqulaIndentation]?: number;\n [traqulaNewlineAlternative]?: string;\n}\n\nexport class DynamicGenerator<Context, Names extends string, RuleDefs extends GenRuleMap<Names>> {\n protected readonly factory = new AstCoreFactory();\n protected __context: Context | undefined = undefined;\n protected origSource = '';\n protected handledInlineSource: SourceLocationInlinedSource | undefined;\n protected generatedUntil = 0;\n protected toEnsure: ((willPrint: string) => void)[] = [];\n /**\n * Should not contain empty strings\n * @protected\n */\n protected readonly stringBuilder: string[] = [];\n\n public constructor(protected rules: RuleDefs) {\n // eslint-disable-next-line ts/no-unnecessary-type-assertion\n for (const rule of <GeneratorRule[]> Object.values(rules)) {\n // Define function implementation\n this[<keyof (typeof this)> rule.name] =\n <any> ((input: any, context: Context & { origSource: string; offset?: number }, args: any) => {\n this.stringBuilder.length = 0;\n this.origSource = context.origSource;\n this.generatedUntil = context?.offset ?? 0;\n this.setContext(context);\n\n this.subrule(rule, input, args);\n\n this.catchup(this.origSource.length);\n\n return this.stringBuilder.join('');\n });\n }\n }\n\n public setContext(context: Context): void {\n this.__context = context;\n }\n\n protected getSafeContext(): Context & GeneratorContext {\n return <Context & GeneratorContext> this.__context;\n }\n\n protected readonly subrule: RuleDefArg['SUBRULE'] = (cstDef, ast, ...arg) => {\n const def = this.rules[<Names> cstDef.name];\n if (!def) {\n throw new Error(`Rule ${cstDef.name} not found`);\n }\n\n const generate = (): void => def.gImpl({\n SUBRULE: this.subrule,\n PRINT: this.print,\n ENSURE: this.ensure,\n ENSURE_EITHER: this.ensureEither,\n NEW_LINE: this.newLine,\n HANDLE_LOC: this.handleLoc,\n CATCHUP: this.catchup,\n\n PRINT_WORD: this.printWord,\n PRINT_WORDS: this.printWords,\n PRINT_ON_EMPTY: this.printOnEmpty,\n PRINT_ON_OWN_LINE: this.printOnOwnLine,\n })(ast, this.getSafeContext(), ...arg);\n\n if (this.factory.isLocalized(ast)) {\n this.handleLoc(ast, generate);\n } else {\n generate();\n }\n };\n\n protected readonly handleLoc: RuleDefArg['HANDLE_LOC'] = (localized, handle) => {\n if (this.factory.isSourceLocationNoMaterialize(localized.loc)) {\n return;\n }\n if (this.factory.isSourceLocationStringReplace(localized.loc)) {\n this.catchup(localized.loc.start);\n this.print(localized.loc.newSource);\n this.generatedUntil = localized.loc.end;\n return;\n }\n if (this.factory.isSourceLocationNodeReplace(localized.loc)) {\n this.catchup(localized.loc.start);\n this.generatedUntil = localized.loc.end;\n }\n if (this.factory.isSourceLocationSource(localized.loc)) {\n this.catchup(localized.loc.start);\n }\n if (this.factory.isSourceLocationInlinedSource(localized.loc) && this.handledInlineSource !== localized.loc) {\n // Calling handleLoc on the same AST multiple times should be the same as doing it once.\n this.handledInlineSource = localized.loc;\n this.catchup(localized.loc.start);\n const origSource = this.origSource;\n const origPointer = this.generatedUntil;\n this.origSource = localized.loc.newSource;\n this.generatedUntil = 0;\n this.catchup(localized.loc.startOnNew);\n\n this.handleLoc(localized.loc, handle);\n\n this.generatedUntil = localized.loc.endOnNew;\n this.catchup(this.origSource.length);\n this.origSource = origSource;\n this.generatedUntil = Math.max(origPointer, localized.loc.end);\n return;\n }\n // If autoGenerate - do nothing\n\n const ret = handle();\n\n if (this.factory.isSourceLocationSource(localized.loc)) {\n this.catchup(localized.loc.end);\n }\n return ret;\n };\n\n /**\n * Catchup until, excluding\n */\n protected readonly catchup: RuleDefArg['CATCHUP'] = (until) => {\n const start = this.generatedUntil;\n if (start < until) {\n this.print(this.origSource.slice(start, until));\n }\n this.generatedUntil = Math.max(this.generatedUntil, until);\n };\n\n private handeEnsured(toPrint: string): void {\n for (const callBack of this.toEnsure) {\n callBack(toPrint);\n }\n this.toEnsure.length = 0;\n }\n\n protected readonly print: RuleDefArg['PRINT'] = (...args) => {\n const joined = args.join('');\n this.handeEnsured(joined);\n this.stringBuilder.push(joined);\n };\n\n private doesEndWith(subsStr: string): boolean {\n const len = subsStr.length;\n let temp = '';\n while (temp.length < len && this.stringBuilder.length > 0) {\n temp = this.stringBuilder.pop() + temp;\n }\n this.stringBuilder.push(temp);\n return temp.endsWith(subsStr);\n }\n\n protected readonly ensure: RuleDefArg['ENSURE'] = (...args) => {\n // Check whether already present\n const toEnsure = args.join('');\n if (!this.doesEndWith(toEnsure)) {\n this.toEnsure.push((willPrint) => {\n if (!willPrint.startsWith(toEnsure) && !this.doesEndWith(toEnsure)) {\n this.stringBuilder.push(toEnsure);\n }\n });\n }\n };\n\n protected readonly ensureEither: RuleDefArg['ENSURE_EITHER'] = (...args) => {\n if (args.length === 1) {\n this.ensure(...args);\n } else if (args.length > 1 &&\n // Not already matched?\n !args.some(subStr => this.doesEndWith(subStr))) {\n this.toEnsure.push((willPrint) => {\n if (!args.some(subStr => willPrint.startsWith(subStr)) && !args.some(subStr => this.doesEndWith(subStr))) {\n this.stringBuilder.push(args[0]);\n }\n });\n }\n };\n\n private pruneEndingBlanks(): void {\n let temp = '';\n while (/^[ \\t]*$/u.test(temp) && this.stringBuilder.length > 0) {\n temp = this.stringBuilder.pop() + temp;\n }\n this.print(temp.trimEnd());\n }\n\n protected readonly newLine: RuleDefArg['NEW_LINE'] = (arg) => {\n const indentation = this.getSafeContext()[traqulaIndentation] ?? 0;\n const force = arg?.force ?? false;\n if (indentation < 0) {\n const newlineAlternative = this.getSafeContext()[traqulaNewlineAlternative];\n if (newlineAlternative !== undefined &&\n // If we force, it means we would print \\n no matter. - otherwise check whether we have printed the char\n (force || (this.stringBuilder.at(-1) !== newlineAlternative))) {\n this.print(newlineAlternative);\n }\n return;\n }\n this.pruneEndingBlanks();\n if (force) {\n this.print('\\n', ' '.repeat(indentation));\n } else {\n let temp = '';\n while (!temp.includes('\\n') && this.stringBuilder.length > 0) {\n temp = this.stringBuilder.pop() + temp;\n }\n if (/\\n[ \\t]*$/u.test(temp)) {\n // Pointer is on empty newline -> set correct indentation\n temp = temp.replace(/\\n[ \\t]*$/u, `\\n${' '.repeat(indentation)}`);\n this.print(temp);\n } else {\n // Pointer not on empty newline, print newline.\n this.print(temp, '\\n', ' '.repeat(indentation));\n }\n }\n };\n\n private readonly printWord: RuleDefArg['PRINT_WORD'] = (...args) => {\n this.ensureEither(' ', '\\n');\n this.print(...args);\n this.ensureEither(' ', '\\n');\n };\n\n private readonly printWords: RuleDefArg['PRINT_WORD'] = (...args) => {\n for (const arg of args) {\n this.printWord(arg);\n }\n };\n\n private readonly printOnEmpty: RuleDefArg['PRINT_ON_EMPTY'] = (...args) => {\n this.newLine();\n this.print(...args);\n };\n\n private readonly printOnOwnLine: RuleDefArg['PRINT_ON_OWN_LINE'] = (...args) => {\n this.newLine();\n this.print(...args);\n this.newLine();\n };\n}\n"]}
{"version":3,"file":"dynamicGenerator.js","sourceRoot":"","sources":["../../../../lib/generator-builder/dynamicGenerator.ts"],"names":[],"mappings":"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","sourcesContent":["import { AstCoreFactory } from '../AstCoreFactory.js';\nimport type { SourceLocationInlinedSource } from '../types.js';\nimport { traqulaIndentation, traqulaNewlineAlternative } from '../utils.js';\nimport type { GenRuleMap } from './builderTypes.js';\nimport type { GeneratorRule, RuleDefArg } from './generatorTypes.js';\n\nexport interface GeneratorContext {\n [traqulaIndentation]?: number;\n [traqulaNewlineAlternative]?: string;\n}\n\nexport class DynamicGenerator<Context, Names extends string, RuleDefs extends GenRuleMap<Names>> {\n protected readonly factory = new AstCoreFactory();\n protected __context: Context | undefined = undefined;\n protected origSource = '';\n /**\n * Reference to the latest SourceLocationInlinedSource this generator handled (used for idempotency)\n * @protected\n */\n protected handledInlineSource: SourceLocationInlinedSource | undefined;\n protected generatedUntil = 0;\n protected toEnsure: ((willPrint: string) => void)[] = [];\n /**\n * Should not contain empty strings\n * @protected\n */\n protected readonly stringBuilder: string[] = [];\n\n public constructor(protected rules: RuleDefs) {\n // eslint-disable-next-line ts/no-unnecessary-type-assertion\n for (const rule of <GeneratorRule[]> Object.values(rules)) {\n // Define function implementation\n this[<keyof (typeof this)> rule.name] =\n <any> ((input: any, context: Context & { origSource: string; offset?: number }, args: any) => {\n this.stringBuilder.length = 0;\n this.origSource = context.origSource;\n this.generatedUntil = context?.offset ?? 0;\n this.setContext(context);\n\n this.subrule(rule, input, args);\n\n this.catchup(this.origSource.length);\n\n return this.stringBuilder.join('');\n });\n }\n }\n\n public setContext(context: Context): void {\n this.__context = context;\n }\n\n protected getSafeContext(): Context & GeneratorContext {\n return <Context & GeneratorContext> this.__context;\n }\n\n protected readonly subrule: RuleDefArg['SUBRULE'] = (cstDef, ast, ...arg) => {\n const def = this.rules[<Names> cstDef.name];\n if (!def) {\n throw new Error(`Rule ${cstDef.name} not found`);\n }\n\n const generate = (): void => def.gImpl({\n SUBRULE: this.subrule,\n PRINT: this.print,\n ENSURE: this.ensure,\n ENSURE_EITHER: this.ensureEither,\n NEW_LINE: this.newLine,\n HANDLE_LOC: this.handleLoc,\n CATCHUP: this.catchup,\n\n PRINT_WORD: this.printWord,\n PRINT_WORDS: this.printWords,\n PRINT_ON_EMPTY: this.printOnEmpty,\n PRINT_ON_OWN_LINE: this.printOnOwnLine,\n })(ast, this.getSafeContext(), ...arg);\n\n if (this.factory.isLocalized(ast)) {\n this.handleLoc(ast, generate);\n } else {\n generate();\n }\n };\n\n protected readonly handleLoc: RuleDefArg['HANDLE_LOC'] = (localized, handle) => {\n if (this.factory.isSourceLocationNoMaterialize(localized.loc)) {\n return;\n }\n if (this.factory.isSourceLocationStringReplace(localized.loc)) {\n this.catchup(localized.loc.start);\n this.print(localized.loc.newSource);\n this.generatedUntil = localized.loc.end;\n return;\n }\n if (this.factory.isSourceLocationNodeReplace(localized.loc)) {\n this.catchup(localized.loc.start);\n this.generatedUntil = localized.loc.end;\n }\n if (this.factory.isSourceLocationSource(localized.loc)) {\n this.catchup(localized.loc.start);\n }\n if (this.factory.isSourceLocationInlinedSource(localized.loc) && this.handledInlineSource !== localized.loc) {\n // Idempotence: calling handleLoc on the same AST multiple times should be the same as doing it once.\n this.handledInlineSource = localized.loc;\n // Like normal, catch up until the start of what this node represents.\n this.catchup(localized.loc.start);\n // Save pointer location of current source and register new source.\n const origSource = this.origSource;\n const origPointer = this.generatedUntil;\n this.origSource = localized.loc.newSource;\n this.generatedUntil = 0;\n // Catchup the new source to where this node starts representing the source.\n this.catchup(localized.loc.startOnNew);\n\n const ret = this.handleLoc(localized.loc, handle);\n\n // Catchup so the entire new source is generated outside what this node represents.\n this.generatedUntil = localized.loc.endOnNew;\n this.catchup(this.origSource.length);\n // Recover the original source and register that you generated the range of this node.\n this.origSource = origSource;\n this.generatedUntil = Math.max(origPointer, localized.loc.end);\n return ret;\n }\n // If autoGenerate - do nothing\n\n const ret = handle();\n\n if (this.factory.isSourceLocationSource(localized.loc)) {\n this.catchup(localized.loc.end);\n }\n return ret;\n };\n\n /**\n * Catchup until, excluding\n */\n protected readonly catchup: RuleDefArg['CATCHUP'] = (until) => {\n const start = this.generatedUntil;\n if (start < until) {\n this.print(this.origSource.slice(start, until));\n }\n this.generatedUntil = Math.max(this.generatedUntil, until);\n };\n\n private handeEnsured(toPrint: string): void {\n for (const callBack of this.toEnsure) {\n callBack(toPrint);\n }\n this.toEnsure.length = 0;\n }\n\n protected readonly print: RuleDefArg['PRINT'] = (...args) => {\n const joined = args.join('');\n this.handeEnsured(joined);\n this.stringBuilder.push(joined);\n };\n\n private doesEndWith(subsStr: string): boolean {\n const len = subsStr.length;\n let temp = '';\n while (temp.length < len && this.stringBuilder.length > 0) {\n temp = this.stringBuilder.pop() + temp;\n }\n this.stringBuilder.push(temp);\n return temp.endsWith(subsStr);\n }\n\n protected readonly ensure: RuleDefArg['ENSURE'] = (...args) => {\n // Check whether already present\n const toEnsure = args.join('');\n if (!this.doesEndWith(toEnsure)) {\n this.toEnsure.push((willPrint) => {\n if (!willPrint.startsWith(toEnsure) && !this.doesEndWith(toEnsure)) {\n this.stringBuilder.push(toEnsure);\n }\n });\n }\n };\n\n protected readonly ensureEither: RuleDefArg['ENSURE_EITHER'] = (...args) => {\n if (args.length === 1) {\n this.ensure(...args);\n } else if (args.length > 1 &&\n // Not already matched?\n !args.some(subStr => this.doesEndWith(subStr))) {\n this.toEnsure.push((willPrint) => {\n if (!args.some(subStr => willPrint.startsWith(subStr)) && !args.some(subStr => this.doesEndWith(subStr))) {\n this.stringBuilder.push(args[0]);\n }\n });\n }\n };\n\n private pruneEndingBlanks(): void {\n let temp = '';\n while (/^[ \\t]*$/u.test(temp) && this.stringBuilder.length > 0) {\n temp = this.stringBuilder.pop() + temp;\n }\n this.print(temp.trimEnd());\n }\n\n protected readonly newLine: RuleDefArg['NEW_LINE'] = (arg) => {\n const indentation = this.getSafeContext()[traqulaIndentation] ?? 0;\n const force = arg?.force ?? false;\n if (indentation < 0) {\n const newlineAlternative = this.getSafeContext()[traqulaNewlineAlternative];\n if (newlineAlternative !== undefined &&\n // If we force, it means we would print \\n no matter. - otherwise check whether we have printed the char\n (force || (this.stringBuilder.at(-1) !== newlineAlternative))) {\n this.print(newlineAlternative);\n }\n return;\n }\n this.pruneEndingBlanks();\n if (force) {\n this.print('\\n', ' '.repeat(indentation));\n } else {\n let temp = '';\n while (!temp.includes('\\n') && this.stringBuilder.length > 0) {\n temp = this.stringBuilder.pop() + temp;\n }\n if (/\\n[ \\t]*$/u.test(temp)) {\n // Pointer is on empty newline -> set correct indentation\n temp = temp.replace(/\\n[ \\t]*$/u, `\\n${' '.repeat(indentation)}`);\n this.print(temp);\n } else {\n // Pointer not on empty newline, print newline.\n this.print(temp, '\\n', ' '.repeat(indentation));\n }\n }\n };\n\n private readonly printWord: RuleDefArg['PRINT_WORD'] = (...args) => {\n this.ensureEither(' ', '\\n');\n this.print(...args);\n this.ensureEither(' ', '\\n');\n };\n\n private readonly printWords: RuleDefArg['PRINT_WORD'] = (...args) => {\n for (const arg of args) {\n this.printWord(arg);\n }\n };\n\n private readonly printOnEmpty: RuleDefArg['PRINT_ON_EMPTY'] = (...args) => {\n this.newLine();\n this.print(...args);\n };\n\n private readonly printOnOwnLine: RuleDefArg['PRINT_ON_OWN_LINE'] = (...args) => {\n this.newLine();\n this.print(...args);\n this.newLine();\n };\n}\n"]}

@@ -170,3 +170,6 @@ export class TransformerObject {

for (let i = curObject.length - 1; i >= 0; i--) {
stack.push(curObject[i]);
const val = curObject[i];
if (val !== null && typeof val === 'object') {
stack.push(val);
}
}

@@ -173,0 +176,0 @@ handleVisitor();

@@ -1,1 +0,1 @@

{"version":3,"file":"TransformerObject.js","sourceRoot":"","sources":["../../../../lib/transformers/TransformerObject.ts"],"names":[],"mappings":"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","sourcesContent":["export interface VisitContext {\n /**\n * Whether you should stop iterating after this object. Default false.\n */\n shortcut?: boolean;\n /**\n * Whether you should continue iterating deeper with this object. Default true.\n */\n continue?: boolean;\n /**\n * Object keys that can be ignored, meaning they do not get visited.\n */\n ignoreKeys?: Set<string>;\n}\n\nexport interface TransformContext extends VisitContext {\n /**\n * Object keys that will be shallowly copied but not traversed.\n * When the same key is included here and in ignoreKeys, the copy will still be made.\n */\n shallowKeys?: Set<string>;\n /**\n * Whether the visited object should be shallowly copied or not. Defaults to true.\n */\n copy?: boolean;\n}\n\nexport interface SelectiveTraversalContext<Nodes> {\n /**\n * Nodes you should visit next. Defaults to empty list\n */\n next?: Nodes[];\n /**\n * Whether you should stop visiting after visiting this object. Default false.\n */\n shortcut?: boolean;\n}\n\nexport class TransformerObject {\n protected maxStackSize = 1_000_000;\n /**\n * Creates stateless transformer.\n * @param defaultContext\n */\n public constructor(protected readonly defaultContext: TransformContext = {}) {}\n\n public clone(newDefaultContext: TransformContext = {}): TransformerObject {\n return new TransformerObject({ ...this.defaultContext, ...newDefaultContext });\n }\n\n /**\n * Function to shallow clone any type.\n * @param obj\n * @protected\n */\n public cloneObj<T>(obj: T): T {\n if (obj === null || typeof obj !== 'object') {\n return obj;\n }\n\n const proto = Object.getPrototypeOf(obj);\n\n // Fast path: plain object\n if (proto === Object.prototype || proto === null) {\n // Spread or assign preserves fast properties\n return { ...obj };\n }\n\n // Otherwise, preserve prototype for custom objects\n return Object.assign(Object.create(proto), obj);\n }\n\n /**\n * Recursively transforms all objects that are not arrays. Mapper is called on deeper objects first.\n * @param startObject object to start iterating from\n * @param mapper mapper to transform the various objects - argument is a copy of the original\n * @param preVisitor callback that is evaluated before iterating deeper.\n * If continues is false, we do not iterate deeper, current object is still mapped. - default: true\n * If shortcut is true, we do not iterate deeper, nor do we branch out, this mapper will be the last one called.\n * - Default false\n */\n public transformObject(\n startObject: object,\n mapper: (copy: object, orig: object) => unknown,\n preVisitor: (orig: object) => TransformContext = () => ({}),\n ): unknown {\n const defaults = this.defaultContext;\n const defaultCopyFlag = defaults.copy ?? true;\n const defaultContinues = defaults.continue ?? true;\n const defaultIgnoreKeys = defaults.ignoreKeys;\n const defaultShallowKeys = defaults.shallowKeys;\n const defaultDidShortCut = defaults.shortcut ?? false;\n\n // Code handles own stack instead of using recursion - this optimizes it for deep operations.\n let didShortCut = false;\n const resultWrap = { res: startObject };\n\n // Grows with stack\n const stack = [ startObject ];\n const stackParent: object[] = [ resultWrap ];\n const stackParentKey: string[] = [ 'res' ];\n\n // Grows with reverse stack - when popping down the stack, you realise you still want to map something.\n // Counter of stack size when we started adding the children of this object, going beyond this means a new parent\n const handleMapperOnLen: number[] = [];\n const mapperCopyStack: object[] = [];\n const mapperOrigStack: object[] = [];\n const mapperParent: object[] = [];\n const mapperParentKey: string[] = [];\n\n function handleMapper(): void {\n while (stack.length === handleMapperOnLen.at(-1)) {\n handleMapperOnLen.pop();\n const copyToMap = mapperCopyStack.pop()!;\n const origToMap = mapperOrigStack.pop()!;\n const parent = <Record<string, unknown>> mapperParent.pop()!;\n const parentKey = mapperParentKey.pop()!;\n parent[parentKey] = mapper(copyToMap, origToMap);\n }\n }\n\n while (stack.length > 0 && stack.length < this.maxStackSize) {\n const curObject = stack.pop()!;\n const curParent = stackParent.pop()!;\n const curKey = stackParentKey.pop()!;\n\n // Only add to the stack when you did not shortcut\n if (!didShortCut) {\n if (Array.isArray(curObject)) {\n const newArr = [ ...curObject ];\n handleMapperOnLen.push(stack.length);\n mapperCopyStack.push(newArr);\n mapperOrigStack.push(curObject);\n mapperParent.push(curParent);\n mapperParentKey.push(curKey);\n\n for (let index = curObject.length - 1; index >= 0; index--) {\n const val = curObject[index];\n if (val !== null && typeof val === 'object') {\n stack.push(val);\n stackParent.push(newArr);\n stackParentKey.push(index.toString());\n }\n }\n handleMapper();\n continue;\n }\n\n // Perform pre visit before expanding the stack\n const context = preVisitor(<any>curObject);\n const copyFlag = context.copy ?? defaultCopyFlag;\n const continues = context.continue ?? defaultContinues;\n const ignoreKeys = context.ignoreKeys ?? defaultIgnoreKeys;\n const shallowKeys = context.shallowKeys ?? defaultShallowKeys;\n didShortCut = context.shortcut ?? defaultDidShortCut;\n\n const copy = copyFlag ? this.cloneObj(curObject) : curObject;\n\n // Register that you want to be visited\n handleMapperOnLen.push(stack.length);\n mapperCopyStack.push(copy);\n mapperOrigStack.push(curObject);\n mapperParent.push(curParent);\n mapperParentKey.push(curKey);\n\n // Extend stack if needed. When shortcutted, should still unwind the stack, but no longer add to it.\n if (continues && !didShortCut) {\n for (const key in copy) {\n if (!Object.hasOwn(copy, key)) {\n continue;\n }\n const val = (<Record<string, unknown>> copy)[key];\n\n // If shallow copy required, do\n const onlyShallow = shallowKeys && shallowKeys?.has(key);\n if (onlyShallow) {\n // Do not add stack entry - assign straight away\n (<Record<string, unknown>> copy)[key] = this.cloneObj(val);\n }\n if (ignoreKeys && ignoreKeys.has(key)) {\n // Do not add stack entry\n continue;\n }\n if (!onlyShallow && val !== null && typeof val === 'object') {\n // Do add stack entry.\n stack.push(val);\n stackParentKey.push(key);\n stackParent.push(copy);\n }\n }\n }\n }\n handleMapper();\n }\n if (stack.length >= this.maxStackSize) {\n throw new Error('Transform object stack overflowed');\n }\n handleMapper();\n\n return <any> resultWrap.res;\n }\n\n /**\n * Visitor that visits all objects. Visits deeper objects first.\n */\n public visitObject(\n startObject: object,\n visitor: (orig: object) => void,\n preVisitor: (orig: object) => VisitContext = () => ({}),\n ): void {\n const defaults = this.defaultContext;\n const defaultContinues = defaults.continue ?? true;\n const defaultIgnoreKeys = defaults.ignoreKeys;\n const defaultShortcut = defaults.shortcut ?? false;\n\n let didShortCut = false;\n\n // Stack of things to preVisit\n const stack = [ startObject ];\n // When the stack is done preVisiting things above this lengths, visit the bellow\n const handleVisitorOnLen: number[] = [];\n const visitorStack: object[] = [];\n\n function handleVisitor(): void {\n while (stack.length === handleVisitorOnLen.at(-1)) {\n handleVisitorOnLen.pop();\n const toVisit = visitorStack.pop()!;\n visitor(toVisit);\n }\n }\n\n while (stack.length > 0 && stack.length < this.maxStackSize) {\n const curObject = stack.pop()!;\n\n if (!didShortCut) {\n if (Array.isArray(curObject)) {\n for (let i = curObject.length - 1; i >= 0; i--) {\n stack.push(curObject[i]);\n }\n handleVisitor();\n continue;\n }\n\n // Perform pre visit before expanding the stack\n const context = preVisitor(curObject);\n didShortCut = context.shortcut ?? defaultShortcut;\n const continues = context.continue ?? defaultContinues;\n const ignoreKeys = context.ignoreKeys ?? defaultIgnoreKeys;\n\n // Register that you want to be visited\n handleVisitorOnLen.push(stack.length);\n visitorStack.push(curObject);\n\n // Extend stack if needed. When shortcutted, should still unwind the stack, but no longer add to it.\n if (continues && !didShortCut) {\n for (const key in curObject) {\n if (!Object.hasOwn(curObject, key)) {\n continue;\n }\n if (ignoreKeys && ignoreKeys.has(key)) {\n continue;\n }\n const val = (<Record<string, unknown>> curObject)[key];\n if (val && typeof val === 'object') {\n stack.push(val);\n }\n }\n }\n }\n handleVisitor();\n }\n if (stack.length >= this.maxStackSize) {\n throw new Error('Transform object stack overflowed');\n }\n handleVisitor();\n }\n}\n"]}
{"version":3,"file":"TransformerObject.js","sourceRoot":"","sources":["../../../../lib/transformers/TransformerObject.ts"],"names":[],"mappings":"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","sourcesContent":["export interface VisitContext {\n /**\n * Whether you should stop iterating after this object. Default false.\n */\n shortcut?: boolean;\n /**\n * Whether you should continue iterating deeper with this object. Default true.\n */\n continue?: boolean;\n /**\n * Object keys that can be ignored, meaning they do not get visited.\n */\n ignoreKeys?: Set<string>;\n}\n\nexport interface TransformContext extends VisitContext {\n /**\n * Object keys that will be shallowly copied but not traversed.\n * When the same key is included here and in ignoreKeys, the copy will still be made.\n */\n shallowKeys?: Set<string>;\n /**\n * Whether the visited object should be shallowly copied or not. Defaults to true.\n */\n copy?: boolean;\n}\n\nexport interface SelectiveTraversalContext<Nodes> {\n /**\n * Nodes you should visit next. Defaults to empty list\n */\n next?: Nodes[];\n /**\n * Whether you should stop visiting after visiting this object. Default false.\n */\n shortcut?: boolean;\n}\n\nexport class TransformerObject {\n protected maxStackSize = 1_000_000;\n /**\n * Creates stateless transformer.\n * @param defaultContext\n */\n public constructor(protected readonly defaultContext: TransformContext = {}) {}\n\n public clone(newDefaultContext: TransformContext = {}): TransformerObject {\n return new TransformerObject({ ...this.defaultContext, ...newDefaultContext });\n }\n\n /**\n * Function to shallow clone any type.\n * @param obj\n * @protected\n */\n public cloneObj<T>(obj: T): T {\n if (obj === null || typeof obj !== 'object') {\n return obj;\n }\n\n const proto = Object.getPrototypeOf(obj);\n\n // Fast path: plain object\n if (proto === Object.prototype || proto === null) {\n // Spread or assign preserves fast properties\n return { ...obj };\n }\n\n // Otherwise, preserve prototype for custom objects\n return Object.assign(Object.create(proto), obj);\n }\n\n /**\n * Recursively transforms all objects that are not arrays. Mapper is called on deeper objects first.\n * @param startObject object to start iterating from\n * @param mapper mapper to transform the various objects - argument is a copy of the original\n * @param preVisitor callback that is evaluated before iterating deeper.\n * If continues is false, we do not iterate deeper, current object is still mapped. - default: true\n * If shortcut is true, we do not iterate deeper, nor do we branch out, this mapper will be the last one called.\n * - Default false\n */\n public transformObject(\n startObject: object,\n mapper: (copy: object, orig: object) => unknown,\n preVisitor: (orig: object) => TransformContext = () => ({}),\n ): unknown {\n const defaults = this.defaultContext;\n const defaultCopyFlag = defaults.copy ?? true;\n const defaultContinues = defaults.continue ?? true;\n const defaultIgnoreKeys = defaults.ignoreKeys;\n const defaultShallowKeys = defaults.shallowKeys;\n const defaultDidShortCut = defaults.shortcut ?? false;\n\n // Code handles own stack instead of using recursion - this optimizes it for deep operations.\n let didShortCut = false;\n const resultWrap = { res: startObject };\n\n // Grows with stack\n const stack = [ startObject ];\n const stackParent: object[] = [ resultWrap ];\n const stackParentKey: string[] = [ 'res' ];\n\n // Grows with reverse stack - when popping down the stack, you realise you still want to map something.\n // Counter of stack size when we started adding the children of this object, going beyond this means a new parent\n const handleMapperOnLen: number[] = [];\n const mapperCopyStack: object[] = [];\n const mapperOrigStack: object[] = [];\n const mapperParent: object[] = [];\n const mapperParentKey: string[] = [];\n\n function handleMapper(): void {\n while (stack.length === handleMapperOnLen.at(-1)) {\n handleMapperOnLen.pop();\n const copyToMap = mapperCopyStack.pop()!;\n const origToMap = mapperOrigStack.pop()!;\n const parent = <Record<string, unknown>> mapperParent.pop()!;\n const parentKey = mapperParentKey.pop()!;\n parent[parentKey] = mapper(copyToMap, origToMap);\n }\n }\n\n while (stack.length > 0 && stack.length < this.maxStackSize) {\n const curObject = stack.pop()!;\n const curParent = stackParent.pop()!;\n const curKey = stackParentKey.pop()!;\n\n // Only add to the stack when you did not shortcut\n if (!didShortCut) {\n if (Array.isArray(curObject)) {\n const newArr = [ ...curObject ];\n handleMapperOnLen.push(stack.length);\n mapperCopyStack.push(newArr);\n mapperOrigStack.push(curObject);\n mapperParent.push(curParent);\n mapperParentKey.push(curKey);\n\n for (let index = curObject.length - 1; index >= 0; index--) {\n const val = <unknown> curObject[index];\n if (val !== null && typeof val === 'object') {\n stack.push(val);\n stackParent.push(newArr);\n stackParentKey.push(index.toString());\n }\n }\n handleMapper();\n continue;\n }\n\n // Perform pre visit before expanding the stack\n const context = preVisitor(<any>curObject);\n const copyFlag = context.copy ?? defaultCopyFlag;\n const continues = context.continue ?? defaultContinues;\n const ignoreKeys = context.ignoreKeys ?? defaultIgnoreKeys;\n const shallowKeys = context.shallowKeys ?? defaultShallowKeys;\n didShortCut = context.shortcut ?? defaultDidShortCut;\n\n const copy = copyFlag ? this.cloneObj(curObject) : curObject;\n\n // Register that you want to be visited\n handleMapperOnLen.push(stack.length);\n mapperCopyStack.push(copy);\n mapperOrigStack.push(curObject);\n mapperParent.push(curParent);\n mapperParentKey.push(curKey);\n\n // Extend stack if needed. When shortcutted, should still unwind the stack, but no longer add to it.\n if (continues && !didShortCut) {\n for (const key in copy) {\n if (!Object.hasOwn(copy, key)) {\n continue;\n }\n const val = (<Record<string, unknown>> copy)[key];\n\n // If shallow copy required, do\n const onlyShallow = shallowKeys && shallowKeys?.has(key);\n if (onlyShallow) {\n // Do not add stack entry - assign straight away\n (<Record<string, unknown>> copy)[key] = this.cloneObj(val);\n }\n if (ignoreKeys && ignoreKeys.has(key)) {\n // Do not add stack entry\n continue;\n }\n if (!onlyShallow && val !== null && typeof val === 'object') {\n // Do add stack entry.\n stack.push(val);\n stackParentKey.push(key);\n stackParent.push(copy);\n }\n }\n }\n }\n handleMapper();\n }\n if (stack.length >= this.maxStackSize) {\n throw new Error('Transform object stack overflowed');\n }\n handleMapper();\n\n return <any> resultWrap.res;\n }\n\n /**\n * Visitor that visits all objects. Visits deeper objects first.\n */\n public visitObject(\n startObject: object,\n visitor: (orig: object) => void,\n preVisitor: (orig: object) => VisitContext = () => ({}),\n ): void {\n const defaults = this.defaultContext;\n const defaultContinues = defaults.continue ?? true;\n const defaultIgnoreKeys = defaults.ignoreKeys;\n const defaultShortcut = defaults.shortcut ?? false;\n\n let didShortCut = false;\n\n // Stack of things to preVisit\n const stack = [ startObject ];\n // When the stack is done preVisiting things above this lengths, visit the bellow\n const handleVisitorOnLen: number[] = [];\n const visitorStack: object[] = [];\n\n function handleVisitor(): void {\n while (stack.length === handleVisitorOnLen.at(-1)) {\n handleVisitorOnLen.pop();\n const toVisit = visitorStack.pop()!;\n visitor(toVisit);\n }\n }\n\n while (stack.length > 0 && stack.length < this.maxStackSize) {\n const curObject = stack.pop()!;\n\n if (!didShortCut) {\n if (Array.isArray(curObject)) {\n for (let i = curObject.length - 1; i >= 0; i--) {\n const val = <unknown> curObject[i];\n if (val !== null && typeof val === 'object') {\n stack.push(val);\n }\n }\n handleVisitor();\n continue;\n }\n\n // Perform pre visit before expanding the stack\n const context = preVisitor(curObject);\n didShortCut = context.shortcut ?? defaultShortcut;\n const continues = context.continue ?? defaultContinues;\n const ignoreKeys = context.ignoreKeys ?? defaultIgnoreKeys;\n\n // Register that you want to be visited\n handleVisitorOnLen.push(stack.length);\n visitorStack.push(curObject);\n\n // Extend stack if needed. When shortcutted, should still unwind the stack, but no longer add to it.\n if (continues && !didShortCut) {\n for (const key in curObject) {\n if (!Object.hasOwn(curObject, key)) {\n continue;\n }\n if (ignoreKeys && ignoreKeys.has(key)) {\n continue;\n }\n const val = (<Record<string, unknown>> curObject)[key];\n if (val && typeof val === 'object') {\n stack.push(val);\n }\n }\n }\n }\n handleVisitor();\n }\n if (stack.length >= this.maxStackSize) {\n throw new Error('Transform object stack overflowed');\n }\n handleVisitor();\n }\n}\n"]}

@@ -48,4 +48,5 @@ /**

/**
* Similar to {@link SourceLocationSource} but also carrying the source it related too.
* All sourceLocation nodes that are descends of this one, relate themselves to this source.
* A {@link SourceLocation} that replaces a given range of the generators current source with some other source.
* The SourceLocation of the node itself is described using the {@link loc} key,
* and the state of the generator catches up the new source until {@link startOnNew}.
*/

@@ -61,2 +62,3 @@ export interface SourceLocationInlinedSource extends SourceLocationBase, Localized {

* Behavior of the current loc, after replacing the source string.
* @deprecated There is in fact no subLocation handling, there never was.
*/

@@ -69,2 +71,6 @@ loc: SourceLocation;

end: number;
/**
* The range of characters within the {@link newSource} that can be targeted by descendants of this node.
* This means anything outside this range in the newSource, will be generated by localization handling.
*/
startOnNew: number;

@@ -71,0 +77,0 @@ endOnNew: number;

@@ -1,1 +0,1 @@

{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../lib/types.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * Type that is used by the Traqula core package to type raw objects/ Data Transfer Objects (DTO).\n * Enforces the presence of a type string, and that in case the subType key is present, it also be a string.\n */\nexport interface Typed<Type extends string = string> {\n type: Type;\n subType?: string;\n}\n\n/**\n * A {@link Typed} object that is sure to have a subType\n */\nexport interface SubTyped<Type extends string = string, SubType extends string = string> extends Typed<Type> {\n subType: SubType;\n}\n\n/**\n * Type used by the parser and generator builders of the core Traqula package to annotate\n * the relation between AST objects and the source string.\n */\nexport interface Localized {\n loc: SourceLocation;\n}\n\n/**\n * Wrapper type for localization,\n * can be used to state localization information about any other type (including primitive types)\n */\nexport interface Wrap<T> extends Localized {\n val: T;\n}\n\n/**\n * An AST node. Nodes are indexable by their types.\n * When generating, the SUBRULES called should be located within the current location range.\n */\nexport interface Node extends Localized, Typed {}\n\nexport interface SourceLocationBase {\n sourceLocationType: string;\n}\n\n/**\n * SourceLocation type that annotates that the node represents the AST representation of\n * the given range in the source string.\n */\nexport interface SourceLocationSource extends SourceLocationBase {\n sourceLocationType: 'source';\n start: number;\n end: number;\n}\n\n/**\n * Similar to {@link SourceLocationSource} but also carrying the source it related too.\n * All sourceLocation nodes that are descends of this one, relate themselves to this source.\n */\nexport interface SourceLocationInlinedSource extends SourceLocationBase, Localized {\n sourceLocationType: 'inlinedSource';\n /**\n * The string that will be used as the source for this node and the descends of this node.\n * Note that the generator will print the characters from newSource[0] until start. Likewise for the suffix.\n */\n newSource: string;\n /**\n * Behavior of the current loc, after replacing the source string.\n */\n loc: SourceLocation;\n /**\n * The range that this node replaces in the context of the original source.\n */\n start: number;\n end: number;\n startOnNew: number;\n endOnNew: number;\n}\n\n/**\n * NoStringManifestation means the node does not have a string representation.\n * For example the literal '5' has an integer type (which is an AST node),\n * but the type does not have an associated string representation.\n * When set to true, the node will not be printed, start and end are meaningless in this case.\n */\nexport interface SourceLocationNoMaterialize extends SourceLocationBase {\n sourceLocationType: 'noMaterialize';\n}\n\n/**\n * SourceLocation type that annotates that the node has been replaced\n * in relation to the original string by a new string.\n * It means that this node should be generated, and that the source string from start to end has been changed.\n */\nexport interface SourceLocationStringReplace extends SourceLocationBase {\n sourceLocationType: 'stringReplace';\n /**\n * The string that will replace the given range in the original source.\n */\n newSource: string;\n /**\n * The start of the region in the original source string that this node replaces.\n */\n start: number;\n /**\n * The end of the region in the original source string that this node replaces.\n */\n end: number;\n}\n\n/**\n * SourceLocation type that annotates that the node has been replaced in relation to the original string.\n * It means that this node should be generated, and that the source string from start to end has been changed.\n */\nexport interface SourceLocationNodeReplace extends SourceLocationBase {\n sourceLocationType: 'nodeReplace';\n /**\n * The start of the region in the original source string that this node replaces.\n */\n start: number;\n /**\n * The end of the region in the original source string that this node replaces.\n */\n end: number;\n}\n/**\n * Must have an ancestor of type {@link SourceLocationNodeReplace}\n */\nexport interface SourceLocationNodeAutoGenerate extends SourceLocationBase {\n sourceLocationType: 'autoGenerate';\n}\n\nexport type SourceLocation =\n // Relate yourself to the source\n | SourceLocationSource\n // Add a new source\n | SourceLocationInlinedSource\n // No not generate anything for the current node and descendants\n | SourceLocationNoMaterialize\n // Replace some range by a string\n | SourceLocationStringReplace\n // Replace this node by some autogen\n | SourceLocationNodeReplace\n // Auto gen current node.\n | SourceLocationNodeAutoGenerate;\n"]}
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../lib/types.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * Type that is used by the Traqula core package to type raw objects/ Data Transfer Objects (DTO).\n * Enforces the presence of a type string, and that in case the subType key is present, it also be a string.\n */\nexport interface Typed<Type extends string = string> {\n type: Type;\n subType?: string;\n}\n\n/**\n * A {@link Typed} object that is sure to have a subType\n */\nexport interface SubTyped<Type extends string = string, SubType extends string = string> extends Typed<Type> {\n subType: SubType;\n}\n\n/**\n * Type used by the parser and generator builders of the core Traqula package to annotate\n * the relation between AST objects and the source string.\n */\nexport interface Localized {\n loc: SourceLocation;\n}\n\n/**\n * Wrapper type for localization,\n * can be used to state localization information about any other type (including primitive types)\n */\nexport interface Wrap<T> extends Localized {\n val: T;\n}\n\n/**\n * An AST node. Nodes are indexable by their types.\n * When generating, the SUBRULES called should be located within the current location range.\n */\nexport interface Node extends Localized, Typed {}\n\nexport interface SourceLocationBase {\n sourceLocationType: string;\n}\n\n/**\n * SourceLocation type that annotates that the node represents the AST representation of\n * the given range in the source string.\n */\nexport interface SourceLocationSource extends SourceLocationBase {\n sourceLocationType: 'source';\n start: number;\n end: number;\n}\n\n/**\n * A {@link SourceLocation} that replaces a given range of the generators current source with some other source.\n * The SourceLocation of the node itself is described using the {@link loc} key,\n * and the state of the generator catches up the new source until {@link startOnNew}.\n */\nexport interface SourceLocationInlinedSource extends SourceLocationBase, Localized {\n sourceLocationType: 'inlinedSource';\n /**\n * The string that will be used as the source for this node and the descends of this node.\n * Note that the generator will print the characters from newSource[0] until start. Likewise for the suffix.\n */\n newSource: string;\n /**\n * Behavior of the current loc, after replacing the source string.\n * @deprecated There is in fact no subLocation handling, there never was.\n */\n loc: SourceLocation;\n /**\n * The range that this node replaces in the context of the original source.\n */\n start: number;\n end: number;\n /**\n * The range of characters within the {@link newSource} that can be targeted by descendants of this node.\n * This means anything outside this range in the newSource, will be generated by localization handling.\n */\n startOnNew: number;\n endOnNew: number;\n}\n\n/**\n * NoStringManifestation means the node does not have a string representation.\n * For example the literal '5' has an integer type (which is an AST node),\n * but the type does not have an associated string representation.\n * When set to true, the node will not be printed, start and end are meaningless in this case.\n */\nexport interface SourceLocationNoMaterialize extends SourceLocationBase {\n sourceLocationType: 'noMaterialize';\n}\n\n/**\n * SourceLocation type that annotates that the node has been replaced\n * in relation to the original string by a new string.\n * It means that this node should be generated, and that the source string from start to end has been changed.\n */\nexport interface SourceLocationStringReplace extends SourceLocationBase {\n sourceLocationType: 'stringReplace';\n /**\n * The string that will replace the given range in the original source.\n */\n newSource: string;\n /**\n * The start of the region in the original source string that this node replaces.\n */\n start: number;\n /**\n * The end of the region in the original source string that this node replaces.\n */\n end: number;\n}\n\n/**\n * SourceLocation type that annotates that the node has been replaced in relation to the original string.\n * It means that this node should be generated, and that the source string from start to end has been changed.\n */\nexport interface SourceLocationNodeReplace extends SourceLocationBase {\n sourceLocationType: 'nodeReplace';\n /**\n * The start of the region in the original source string that this node replaces.\n */\n start: number;\n /**\n * The end of the region in the original source string that this node replaces.\n */\n end: number;\n}\n/**\n * Must have an ancestor of type {@link SourceLocationNodeReplace}\n */\nexport interface SourceLocationNodeAutoGenerate extends SourceLocationBase {\n sourceLocationType: 'autoGenerate';\n}\n\nexport type SourceLocation =\n // Relate yourself to the source\n | SourceLocationSource\n // Add a new source\n | SourceLocationInlinedSource\n // No not generate anything for the current node and descendants\n | SourceLocationNoMaterialize\n // Replace some range by a string\n | SourceLocationStringReplace\n // Replace this node by some autogen\n | SourceLocationNodeReplace\n // Auto gen current node.\n | SourceLocationNodeAutoGenerate;\n"]}
{
"name": "@traqula/core",
"type": "module",
"version": "1.0.2",
"version": "1.0.3",
"description": "Core components of Traqula",

@@ -46,3 +46,3 @@ "lsd:module": true,

},
"gitHead": "d5135b2edbc6354ea0c353dd16e062784740cd13"
"gitHead": "100f8110af8ae3288390f37652e516c8d4d5d124"
}