@traqula/core 0.0.23 → 0.0.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/dist/cjs/lib/AstCoreFactory.js +181 -149
- package/dist/cjs/lib/AstCoreFactory.js.map +1 -0
- package/dist/cjs/lib/generator-builder/builderTypes.js +2 -15
- package/dist/cjs/lib/generator-builder/builderTypes.js.map +1 -0
- package/dist/cjs/lib/generator-builder/dynamicGenerator.js +209 -200
- package/dist/cjs/lib/generator-builder/dynamicGenerator.js.map +1 -0
- package/dist/cjs/lib/generator-builder/generatorBuilder.js +103 -117
- package/dist/cjs/lib/generator-builder/generatorBuilder.js.map +1 -0
- package/dist/cjs/lib/generator-builder/generatorTypes.js +2 -15
- package/dist/cjs/lib/generator-builder/generatorTypes.js.map +1 -0
- package/dist/cjs/lib/index.js +39 -57
- package/dist/cjs/lib/index.js.map +1 -0
- package/dist/cjs/lib/indirection-builder/IndirBuilder.js +63 -85
- package/dist/cjs/lib/indirection-builder/IndirBuilder.js.map +1 -0
- package/dist/cjs/lib/indirection-builder/dynamicIndirected.js +28 -50
- package/dist/cjs/lib/indirection-builder/dynamicIndirected.js.map +1 -0
- package/dist/cjs/lib/indirection-builder/helpers.js +11 -31
- package/dist/cjs/lib/indirection-builder/helpers.js.map +1 -0
- package/dist/cjs/lib/lexer-builder/LexerBuilder.js +92 -114
- package/dist/cjs/lib/lexer-builder/LexerBuilder.js.map +1 -0
- package/dist/cjs/lib/parser-builder/builderTypes.js +2 -15
- package/dist/cjs/lib/parser-builder/builderTypes.js.map +1 -0
- package/dist/cjs/lib/parser-builder/dynamicParser.js +116 -136
- package/dist/cjs/lib/parser-builder/dynamicParser.js.map +1 -0
- package/dist/cjs/lib/parser-builder/parserBuilder.js +167 -169
- package/dist/cjs/lib/parser-builder/parserBuilder.js.map +1 -0
- package/dist/cjs/lib/parser-builder/ruleDefTypes.js +2 -15
- package/dist/cjs/lib/parser-builder/ruleDefTypes.js.map +1 -0
- package/dist/cjs/lib/transformers/TransformerObject.js +196 -198
- package/dist/cjs/lib/transformers/TransformerObject.js.map +1 -0
- package/dist/cjs/lib/transformers/TransformerSubTyped.js +110 -141
- package/dist/cjs/lib/transformers/TransformerSubTyped.js.map +1 -0
- package/dist/cjs/lib/transformers/TransformerTyped.js +87 -120
- package/dist/cjs/lib/transformers/TransformerTyped.js.map +1 -0
- package/dist/cjs/lib/types.js +2 -15
- package/dist/cjs/lib/types.js.map +1 -0
- package/dist/cjs/lib/utils.js +20 -34
- package/dist/cjs/lib/utils.js.map +1 -0
- package/dist/esm/lib/AstCoreFactory.d.ts +19 -7
- package/dist/esm/lib/AstCoreFactory.js +50 -5
- package/dist/esm/lib/AstCoreFactory.js.map +1 -1
- package/dist/esm/lib/generator-builder/dynamicGenerator.d.ts +5 -0
- package/dist/esm/lib/generator-builder/dynamicGenerator.js +20 -0
- package/dist/esm/lib/generator-builder/dynamicGenerator.js.map +1 -1
- package/dist/esm/lib/parser-builder/dynamicParser.js +1 -0
- package/dist/esm/lib/parser-builder/dynamicParser.js.map +1 -1
- package/dist/esm/lib/parser-builder/parserBuilder.js +2 -2
- package/dist/esm/lib/parser-builder/parserBuilder.js.map +1 -1
- package/dist/esm/lib/transformers/TransformerObject.d.ts +1 -1
- package/dist/esm/lib/transformers/TransformerObject.js.map +1 -1
- package/dist/esm/lib/transformers/TransformerSubTyped.d.ts +31 -22
- package/dist/esm/lib/transformers/TransformerSubTyped.js +30 -40
- package/dist/esm/lib/transformers/TransformerSubTyped.js.map +1 -1
- package/dist/esm/lib/transformers/TransformerTyped.d.ts +24 -20
- package/dist/esm/lib/transformers/TransformerTyped.js +23 -35
- package/dist/esm/lib/transformers/TransformerTyped.js.map +1 -1
- package/dist/esm/lib/types.d.ts +67 -5
- package/dist/esm/lib/types.js.map +1 -1
- package/dist/esm/lib/utils.d.ts +10 -0
- package/dist/esm/lib/utils.js +7 -0
- package/dist/esm/lib/utils.js.map +1 -1
- package/package.json +9 -9
- package/dist/cjs/test/generatorBuilder/generatorBuilder.types.test.js +0 -30
- package/dist/cjs/test/grammar-builder/parserBuilder.types.test.js +0 -27
- package/dist/cjs/test/transformer.test.js +0 -82
- package/dist/esm/test/generatorBuilder/generatorBuilder.types.test.d.ts +0 -1
- package/dist/esm/test/generatorBuilder/generatorBuilder.types.test.js +0 -38
- package/dist/esm/test/generatorBuilder/generatorBuilder.types.test.js.map +0 -1
- package/dist/esm/test/grammar-builder/parserBuilder.types.test.d.ts +0 -1
- package/dist/esm/test/grammar-builder/parserBuilder.types.test.js +0 -38
- package/dist/esm/test/grammar-builder/parserBuilder.types.test.js.map +0 -1
- package/dist/esm/test/transformer.test.d.ts +0 -1
- package/dist/esm/test/transformer.test.js +0 -82
- package/dist/esm/test/transformer.test.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
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 protected 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"]}
|
|
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"]}
|
|
@@ -1,17 +1,25 @@
|
|
|
1
1
|
import type { SubTyped, Typed } from '../types.js';
|
|
2
|
-
import type {
|
|
2
|
+
import type { TransformContext, VisitContext } from './TransformerObject.js';
|
|
3
3
|
import type { DefaultNodePreVisitor, Safeness, SafeWrap } from './TransformerTyped.js';
|
|
4
4
|
import { TransformerTyped } from './TransformerTyped.js';
|
|
5
5
|
export declare class TransformerSubTyped<Nodes extends Typed> extends TransformerTyped<Nodes> {
|
|
6
6
|
constructor(defaultContext?: TransformContext, defaultNodePreVisitor?: DefaultNodePreVisitor<Nodes>);
|
|
7
7
|
clone(newDefaultContext?: TransformContext, newDefaultNodePreVisitor?: DefaultNodePreVisitor<Nodes>): TransformerSubTyped<Nodes>;
|
|
8
8
|
/**
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* @param nodeCallBacks
|
|
14
|
-
*
|
|
9
|
+
* Transform a single node ({@link Typed}).
|
|
10
|
+
* Similar to {@link this.transformNode} but also allowing you to target the subTypes.
|
|
11
|
+
* @param startObject the object from which we will start the transformation,
|
|
12
|
+
* potentially visiting and transforming its descendants along the way.
|
|
13
|
+
* @param nodeCallBacks a dictionary mapping the various operation types to objects optionally
|
|
14
|
+
* containing preVisitor and transformer.
|
|
15
|
+
* The preVisitor allows you to provide {@link TransformContext} for the current object,
|
|
16
|
+
* altering how it will be transformed.
|
|
17
|
+
* The transformer allows you to manipulate the copy of the current object,
|
|
18
|
+
* and expects you to return the value that should take the current objects place.
|
|
19
|
+
* @param nodeSpecificCallBacks Same as nodeCallBacks but using an additional level of indirection to
|
|
20
|
+
* indicate the subType.
|
|
21
|
+
* @return the result of transforming the requested descendant operations (based on the preVisitor)
|
|
22
|
+
* using a transformer that works its way back up from the descendant to the startObject.
|
|
15
23
|
*/
|
|
16
24
|
transformNodeSpecific<Safe extends Safeness = 'safe', OutType = unknown>(startObject: object, nodeCallBacks: {
|
|
17
25
|
[T in Nodes['type']]?: {
|
|
@@ -27,8 +35,22 @@ export declare class TransformerSubTyped<Nodes extends Typed> extends Transforme
|
|
|
27
35
|
};
|
|
28
36
|
}): Safe extends 'unsafe' ? OutType : unknown;
|
|
29
37
|
/**
|
|
30
|
-
*
|
|
31
|
-
*
|
|
38
|
+
* Visit a selected subTree given a startObject, steering the visits based on {@link Typed} nodes.
|
|
39
|
+
* Similar to {@link this.visitNode}, but also allowing you to target subTypes.
|
|
40
|
+
* Will call the preVisitor on the outer distinct, then the visitor of the special distinct,
|
|
41
|
+
* followed by the visiting the outer distinct, printing '231'.
|
|
42
|
+
* The pre-visitor visits starting from the root, going deeper, while the actual visitor goes in reverse.
|
|
43
|
+
* @param startObject the object from which we will start visiting,
|
|
44
|
+
* potentially visiting its descendants along the way.
|
|
45
|
+
* @param nodeCallBacks a dictionary mapping the various operation types to objects optionally
|
|
46
|
+
* containing preVisitor and visitor.
|
|
47
|
+
* The preVisitor allows you to provide {@link VisitContext} for the current object,
|
|
48
|
+
* altering how it will be visited.
|
|
49
|
+
* The visitor allows you to visit the object from deepest to the outermost object.
|
|
50
|
+
* This is useful if you for example want to manipulate the objects you visit during your visits,
|
|
51
|
+
* similar to {@link mapOperation}.
|
|
52
|
+
* @param nodeSpecificCallBacks Same as nodeCallBacks but using an additional level of indirection to
|
|
53
|
+
* indicate the subType.
|
|
32
54
|
*/
|
|
33
55
|
visitNodeSpecific(startObject: object, nodeCallBacks: {
|
|
34
56
|
[T in Nodes['type']]?: {
|
|
@@ -43,17 +65,4 @@ export declare class TransformerSubTyped<Nodes extends Typed> extends Transforme
|
|
|
43
65
|
};
|
|
44
66
|
};
|
|
45
67
|
}): void;
|
|
46
|
-
/**
|
|
47
|
-
* Similar to {@link this.traverseNodes} but also allows you to match based on the subtype of objects.
|
|
48
|
-
* @param currentNode
|
|
49
|
-
* @param traverseNode
|
|
50
|
-
* @param traverseSubNode
|
|
51
|
-
*/
|
|
52
|
-
traverseSubNodes(currentNode: Nodes, traverseNode: {
|
|
53
|
-
[Type in Nodes['type']]?: (op: Extract<Nodes, Typed<Type>>) => SelectiveTraversalContext<Nodes>;
|
|
54
|
-
}, traverseSubNode: {
|
|
55
|
-
[Type in Nodes['type']]?: {
|
|
56
|
-
[Subtype in Extract<Nodes, SubTyped<Type>>['subType']]?: (op: Extract<Nodes, SubTyped<Type, Subtype>>) => SelectiveTraversalContext<Nodes>;
|
|
57
|
-
};
|
|
58
|
-
}): void;
|
|
59
68
|
}
|
|
@@ -8,12 +8,20 @@ export class TransformerSubTyped extends TransformerTyped {
|
|
|
8
8
|
return new TransformerSubTyped({ ...this.defaultContext, ...newDefaultContext }, { ...this.defaultNodePreVisitor, ...newDefaultNodePreVisitor });
|
|
9
9
|
}
|
|
10
10
|
/**
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* @param nodeCallBacks
|
|
16
|
-
*
|
|
11
|
+
* Transform a single node ({@link Typed}).
|
|
12
|
+
* Similar to {@link this.transformNode} but also allowing you to target the subTypes.
|
|
13
|
+
* @param startObject the object from which we will start the transformation,
|
|
14
|
+
* potentially visiting and transforming its descendants along the way.
|
|
15
|
+
* @param nodeCallBacks a dictionary mapping the various operation types to objects optionally
|
|
16
|
+
* containing preVisitor and transformer.
|
|
17
|
+
* The preVisitor allows you to provide {@link TransformContext} for the current object,
|
|
18
|
+
* altering how it will be transformed.
|
|
19
|
+
* The transformer allows you to manipulate the copy of the current object,
|
|
20
|
+
* and expects you to return the value that should take the current objects place.
|
|
21
|
+
* @param nodeSpecificCallBacks Same as nodeCallBacks but using an additional level of indirection to
|
|
22
|
+
* indicate the subType.
|
|
23
|
+
* @return the result of transforming the requested descendant operations (based on the preVisitor)
|
|
24
|
+
* using a transformer that works its way back up from the descendant to the startObject.
|
|
17
25
|
*/
|
|
18
26
|
transformNodeSpecific(startObject, nodeCallBacks, nodeSpecificCallBacks) {
|
|
19
27
|
const transformWrapper = (copy, orig) => {
|
|
@@ -47,8 +55,22 @@ export class TransformerSubTyped extends TransformerTyped {
|
|
|
47
55
|
return this.transformObject(startObject, transformWrapper, preVisitWrapper);
|
|
48
56
|
}
|
|
49
57
|
/**
|
|
50
|
-
*
|
|
51
|
-
*
|
|
58
|
+
* Visit a selected subTree given a startObject, steering the visits based on {@link Typed} nodes.
|
|
59
|
+
* Similar to {@link this.visitNode}, but also allowing you to target subTypes.
|
|
60
|
+
* Will call the preVisitor on the outer distinct, then the visitor of the special distinct,
|
|
61
|
+
* followed by the visiting the outer distinct, printing '231'.
|
|
62
|
+
* The pre-visitor visits starting from the root, going deeper, while the actual visitor goes in reverse.
|
|
63
|
+
* @param startObject the object from which we will start visiting,
|
|
64
|
+
* potentially visiting its descendants along the way.
|
|
65
|
+
* @param nodeCallBacks a dictionary mapping the various operation types to objects optionally
|
|
66
|
+
* containing preVisitor and visitor.
|
|
67
|
+
* The preVisitor allows you to provide {@link VisitContext} for the current object,
|
|
68
|
+
* altering how it will be visited.
|
|
69
|
+
* The visitor allows you to visit the object from deepest to the outermost object.
|
|
70
|
+
* This is useful if you for example want to manipulate the objects you visit during your visits,
|
|
71
|
+
* similar to {@link mapOperation}.
|
|
72
|
+
* @param nodeSpecificCallBacks Same as nodeCallBacks but using an additional level of indirection to
|
|
73
|
+
* indicate the subType.
|
|
52
74
|
*/
|
|
53
75
|
visitNodeSpecific(startObject, nodeCallBacks, nodeSpecificCallBacks) {
|
|
54
76
|
const visitWrapper = (curObject) => {
|
|
@@ -83,37 +105,5 @@ export class TransformerSubTyped extends TransformerTyped {
|
|
|
83
105
|
};
|
|
84
106
|
this.visitObject(startObject, visitWrapper, preVisitWrapper);
|
|
85
107
|
}
|
|
86
|
-
/**
|
|
87
|
-
* Similar to {@link this.traverseNodes} but also allows you to match based on the subtype of objects.
|
|
88
|
-
* @param currentNode
|
|
89
|
-
* @param traverseNode
|
|
90
|
-
* @param traverseSubNode
|
|
91
|
-
*/
|
|
92
|
-
traverseSubNodes(currentNode, traverseNode, traverseSubNode) {
|
|
93
|
-
let didShortCut = false;
|
|
94
|
-
const recurse = (curNode) => {
|
|
95
|
-
let traverser;
|
|
96
|
-
const subObj = traverseSubNode[curNode.type];
|
|
97
|
-
if (subObj) {
|
|
98
|
-
traverser = subObj[curNode.subType];
|
|
99
|
-
}
|
|
100
|
-
if (!traverser) {
|
|
101
|
-
traverser = traverseNode[curNode.type];
|
|
102
|
-
}
|
|
103
|
-
if (traverser) {
|
|
104
|
-
const { next, shortcut } = traverser(curNode);
|
|
105
|
-
didShortCut = shortcut ?? false;
|
|
106
|
-
if (!didShortCut) {
|
|
107
|
-
for (const node of next ?? []) {
|
|
108
|
-
if (didShortCut) {
|
|
109
|
-
return;
|
|
110
|
-
}
|
|
111
|
-
recurse(node);
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
};
|
|
116
|
-
recurse(currentNode);
|
|
117
|
-
}
|
|
118
108
|
}
|
|
119
109
|
//# sourceMappingURL=TransformerSubTyped.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TransformerSubTyped.js","sourceRoot":"","sources":["../../../../lib/transformers/TransformerSubTyped.ts"],"names":[],"mappings":"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","sourcesContent":["import type { SubTyped, Typed } from '../types.js';\nimport type {\n SelectiveTraversalContext,\n TransformContext,\n VisitContext,\n} from './TransformerObject.js';\nimport type { DefaultNodePreVisitor, Safeness, SafeWrap } from './TransformerTyped.js';\nimport { TransformerTyped } from './TransformerTyped.js';\n\nexport class TransformerSubTyped<Nodes extends Typed> extends TransformerTyped<Nodes> {\n public constructor(\n defaultContext: TransformContext = {},\n defaultNodePreVisitor: DefaultNodePreVisitor<Nodes> = {},\n ) {\n super(defaultContext, defaultNodePreVisitor);\n };\n\n public override clone(\n newDefaultContext: TransformContext = {},\n newDefaultNodePreVisitor: DefaultNodePreVisitor<Nodes> = {},\n ): TransformerSubTyped<Nodes> {\n return new TransformerSubTyped(\n { ...this.defaultContext, ...newDefaultContext },\n { ...this.defaultNodePreVisitor, ...newDefaultNodePreVisitor },\n );\n }\n\n /**\n * Shares the functionality and first two arguments with {@link this.transformNode}.\n * The third argument allows you to also transform based on the subType of objects.\n * Note that when a callback for the subtype is provided, the callback for the general type is **NOT** executed.\n * @param startObject\n * @param nodeCallBacks\n * @param nodeSpecificCallBacks\n */\n public transformNodeSpecific<Safe extends Safeness = 'safe', OutType = unknown>(\n startObject: object,\n nodeCallBacks: {[T in Nodes['type']]?: {\n transform?: (copy: SafeWrap<Safe, Extract<Nodes, Typed<T>>>, orig: Extract<Nodes, Typed<T>>) => unknown;\n preVisitor?: (orig: Extract<Nodes, Typed<T>>) => TransformContext;\n }},\n nodeSpecificCallBacks: {[Type in Nodes['type']]?: {\n [SubType in Extract<Nodes, SubTyped<Type>>['subType']]?: {\n transform?: (op: SafeWrap<Safe, Extract<Nodes, SubTyped<Type, SubType>>>) => unknown;\n preVisitor?: (op: Extract<Nodes, SubTyped<Type, SubType>>) => TransformContext;\n }}},\n ): Safe extends 'unsafe' ? OutType : unknown {\n const transformWrapper = (copy: object, orig: object): unknown => {\n let ogTransform: ((copy: any, orig: any) => unknown) | undefined;\n const casted = <SubTyped<Nodes['type']>>copy;\n if (casted.type && casted.subType) {\n const specific = nodeSpecificCallBacks[casted.type];\n if (specific) {\n ogTransform = specific[<keyof typeof specific> casted.subType]?.transform;\n }\n if (!ogTransform) {\n ogTransform = nodeCallBacks[casted.type]?.transform;\n }\n }\n return ogTransform ? ogTransform(casted, orig) : copy;\n };\n const preVisitWrapper = (curObject: object): VisitContext => {\n let ogPreVisit: ((node: any) => VisitContext) | undefined;\n const casted = <SubTyped<Nodes['type']>>curObject;\n if (casted.type && casted.subType) {\n const specific = nodeSpecificCallBacks[casted.type];\n if (specific) {\n ogPreVisit = specific[<keyof typeof specific> casted.subType]?.preVisitor;\n }\n if (!ogPreVisit) {\n ogPreVisit = nodeCallBacks[casted.type]?.preVisitor;\n }\n }\n return ogPreVisit ? ogPreVisit(casted) : {};\n };\n return <any> this.transformObject(startObject, transformWrapper, preVisitWrapper);\n }\n\n /**\n * Similar to {@link this.visitNode} but also allows you to match based on the subtype of objects.\n * When both nodeCallBack and NodeSpecific callBack are matched, will only visit nodeSpecifCallback\n */\n public visitNodeSpecific(\n startObject: object,\n nodeCallBacks: {[T in Nodes['type']]?: {\n visitor?: (op: Extract<Nodes, Typed<T>>) => void;\n preVisitor?: (op: Extract<Nodes, Typed<T>>) => VisitContext;\n }},\n nodeSpecificCallBacks: {[Type in Nodes['type']]?:\n {[Subtype in Extract<Nodes, SubTyped<Type>>['subType']]?: {\n visitor?: (op: Extract<Nodes, SubTyped<Type, Subtype>>) => void;\n preVisitor?: (op: Extract<Nodes, SubTyped<Type, Subtype>>) => VisitContext;\n }}},\n ): void {\n const visitWrapper = (curObject: object): void => {\n let ogTransform: ((node: any) => void) | undefined;\n const casted = <SubTyped<Nodes['type']>>curObject;\n if (casted.type && casted.subType) {\n const specific = nodeSpecificCallBacks[casted.type];\n if (specific) {\n ogTransform = specific[<keyof typeof specific> casted.subType]?.visitor;\n }\n if (!ogTransform) {\n ogTransform = nodeCallBacks[casted.type]?.visitor;\n }\n }\n if (ogTransform) {\n ogTransform(casted);\n }\n };\n const preVisitWrapper = (curObject: object): VisitContext => {\n let ogPreVisit: ((node: any) => VisitContext) | undefined;\n const casted = <SubTyped<Nodes['type']>>curObject;\n if (casted.type && casted.subType) {\n const specific = nodeSpecificCallBacks[casted.type];\n if (specific) {\n ogPreVisit = specific[<keyof typeof specific> casted.subType]?.preVisitor;\n }\n if (!ogPreVisit) {\n ogPreVisit = nodeCallBacks[casted.type]?.preVisitor;\n }\n }\n return ogPreVisit ? ogPreVisit(casted) : {};\n };\n this.visitObject(startObject, visitWrapper, preVisitWrapper);\n }\n\n /**\n * Similar to {@link this.traverseNodes} but also allows you to match based on the subtype of objects.\n * @param currentNode\n * @param traverseNode\n * @param traverseSubNode\n */\n public traverseSubNodes(\n currentNode: Nodes,\n traverseNode: {[Type in Nodes['type']]?:\n (op: Extract<Nodes, Typed<Type>>) => SelectiveTraversalContext<Nodes> },\n traverseSubNode: {[Type in Nodes['type']]?:\n {[Subtype in Extract<Nodes, SubTyped<Type>>['subType']]?:\n (op: Extract<Nodes, SubTyped<Type, Subtype>>) => SelectiveTraversalContext<Nodes> }},\n ): void {\n let didShortCut = false;\n\n const recurse = (curNode: Nodes): void => {\n let traverser: ((call: any) => SelectiveTraversalContext<Nodes>) | undefined;\n const subObj = traverseSubNode[<Nodes['type']>curNode.type];\n if (subObj) {\n traverser = subObj[<keyof typeof subObj>curNode.subType];\n }\n if (!traverser) {\n traverser = traverseNode[<Nodes['type']>curNode.type];\n }\n if (traverser) {\n const { next, shortcut } = traverser(<any>curNode);\n didShortCut = shortcut ?? false;\n if (!didShortCut) {\n for (const node of next ?? []) {\n if (didShortCut) {\n return;\n }\n recurse(node);\n }\n }\n }\n };\n\n recurse(currentNode);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"TransformerSubTyped.js","sourceRoot":"","sources":["../../../../lib/transformers/TransformerSubTyped.ts"],"names":[],"mappings":"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","sourcesContent":["import type { SubTyped, Typed } from '../types.js';\nimport type {\n TransformContext,\n VisitContext,\n} from './TransformerObject.js';\nimport type { DefaultNodePreVisitor, Safeness, SafeWrap } from './TransformerTyped.js';\nimport { TransformerTyped } from './TransformerTyped.js';\n\nexport class TransformerSubTyped<Nodes extends Typed> extends TransformerTyped<Nodes> {\n public constructor(\n defaultContext: TransformContext = {},\n defaultNodePreVisitor: DefaultNodePreVisitor<Nodes> = {},\n ) {\n super(defaultContext, defaultNodePreVisitor);\n };\n\n public override clone(\n newDefaultContext: TransformContext = {},\n newDefaultNodePreVisitor: DefaultNodePreVisitor<Nodes> = {},\n ): TransformerSubTyped<Nodes> {\n return new TransformerSubTyped(\n { ...this.defaultContext, ...newDefaultContext },\n { ...this.defaultNodePreVisitor, ...newDefaultNodePreVisitor },\n );\n }\n\n /**\n * Transform a single node ({@link Typed}).\n * Similar to {@link this.transformNode} but also allowing you to target the subTypes.\n * @param startObject the object from which we will start the transformation,\n * potentially visiting and transforming its descendants along the way.\n * @param nodeCallBacks a dictionary mapping the various operation types to objects optionally\n * containing preVisitor and transformer.\n * The preVisitor allows you to provide {@link TransformContext} for the current object,\n * altering how it will be transformed.\n * The transformer allows you to manipulate the copy of the current object,\n * and expects you to return the value that should take the current objects place.\n * @param nodeSpecificCallBacks Same as nodeCallBacks but using an additional level of indirection to\n * indicate the subType.\n * @return the result of transforming the requested descendant operations (based on the preVisitor)\n * using a transformer that works its way back up from the descendant to the startObject.\n */\n public transformNodeSpecific<Safe extends Safeness = 'safe', OutType = unknown>(\n startObject: object,\n nodeCallBacks: {[T in Nodes['type']]?: {\n transform?: (copy: SafeWrap<Safe, Extract<Nodes, Typed<T>>>, orig: Extract<Nodes, Typed<T>>) => unknown;\n preVisitor?: (orig: Extract<Nodes, Typed<T>>) => TransformContext;\n }},\n nodeSpecificCallBacks: {[Type in Nodes['type']]?: {\n [SubType in Extract<Nodes, SubTyped<Type>>['subType']]?: {\n transform?: (op: SafeWrap<Safe, Extract<Nodes, SubTyped<Type, SubType>>>) => unknown;\n preVisitor?: (op: Extract<Nodes, SubTyped<Type, SubType>>) => TransformContext;\n }}},\n ): Safe extends 'unsafe' ? OutType : unknown {\n const transformWrapper = (copy: object, orig: object): unknown => {\n let ogTransform: ((copy: any, orig: any) => unknown) | undefined;\n const casted = <SubTyped<Nodes['type']>>copy;\n if (casted.type && casted.subType) {\n const specific = nodeSpecificCallBacks[casted.type];\n if (specific) {\n ogTransform = specific[<keyof typeof specific> casted.subType]?.transform;\n }\n if (!ogTransform) {\n ogTransform = nodeCallBacks[casted.type]?.transform;\n }\n }\n return ogTransform ? ogTransform(casted, orig) : copy;\n };\n const preVisitWrapper = (curObject: object): VisitContext => {\n let ogPreVisit: ((node: any) => VisitContext) | undefined;\n const casted = <SubTyped<Nodes['type']>>curObject;\n if (casted.type && casted.subType) {\n const specific = nodeSpecificCallBacks[casted.type];\n if (specific) {\n ogPreVisit = specific[<keyof typeof specific> casted.subType]?.preVisitor;\n }\n if (!ogPreVisit) {\n ogPreVisit = nodeCallBacks[casted.type]?.preVisitor;\n }\n }\n return ogPreVisit ? ogPreVisit(casted) : {};\n };\n return <any> this.transformObject(startObject, transformWrapper, preVisitWrapper);\n }\n\n /**\n * Visit a selected subTree given a startObject, steering the visits based on {@link Typed} nodes.\n * Similar to {@link this.visitNode}, but also allowing you to target subTypes.\n * Will call the preVisitor on the outer distinct, then the visitor of the special distinct,\n * followed by the visiting the outer distinct, printing '231'.\n * The pre-visitor visits starting from the root, going deeper, while the actual visitor goes in reverse.\n * @param startObject the object from which we will start visiting,\n * potentially visiting its descendants along the way.\n * @param nodeCallBacks a dictionary mapping the various operation types to objects optionally\n * containing preVisitor and visitor.\n * The preVisitor allows you to provide {@link VisitContext} for the current object,\n * altering how it will be visited.\n * The visitor allows you to visit the object from deepest to the outermost object.\n * This is useful if you for example want to manipulate the objects you visit during your visits,\n * similar to {@link mapOperation}.\n * @param nodeSpecificCallBacks Same as nodeCallBacks but using an additional level of indirection to\n * indicate the subType.\n */\n public visitNodeSpecific(\n startObject: object,\n nodeCallBacks: {[T in Nodes['type']]?: {\n visitor?: (op: Extract<Nodes, Typed<T>>) => void;\n preVisitor?: (op: Extract<Nodes, Typed<T>>) => VisitContext;\n }},\n nodeSpecificCallBacks: {[Type in Nodes['type']]?:\n {[Subtype in Extract<Nodes, SubTyped<Type>>['subType']]?: {\n visitor?: (op: Extract<Nodes, SubTyped<Type, Subtype>>) => void;\n preVisitor?: (op: Extract<Nodes, SubTyped<Type, Subtype>>) => VisitContext;\n }}},\n ): void {\n const visitWrapper = (curObject: object): void => {\n let ogTransform: ((node: any) => void) | undefined;\n const casted = <SubTyped<Nodes['type']>>curObject;\n if (casted.type && casted.subType) {\n const specific = nodeSpecificCallBacks[casted.type];\n if (specific) {\n ogTransform = specific[<keyof typeof specific> casted.subType]?.visitor;\n }\n if (!ogTransform) {\n ogTransform = nodeCallBacks[casted.type]?.visitor;\n }\n }\n if (ogTransform) {\n ogTransform(casted);\n }\n };\n const preVisitWrapper = (curObject: object): VisitContext => {\n let ogPreVisit: ((node: any) => VisitContext) | undefined;\n const casted = <SubTyped<Nodes['type']>>curObject;\n if (casted.type && casted.subType) {\n const specific = nodeSpecificCallBacks[casted.type];\n if (specific) {\n ogPreVisit = specific[<keyof typeof specific> casted.subType]?.preVisitor;\n }\n if (!ogPreVisit) {\n ogPreVisit = nodeCallBacks[casted.type]?.preVisitor;\n }\n }\n return ogPreVisit ? ogPreVisit(casted) : {};\n };\n this.visitObject(startObject, visitWrapper, preVisitWrapper);\n }\n}\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Typed } from '../types.js';
|
|
2
|
-
import type {
|
|
2
|
+
import type { TransformContext, VisitContext } from './TransformerObject.js';
|
|
3
3
|
import { TransformerObject } from './TransformerObject.js';
|
|
4
4
|
export type Safeness = 'safe' | 'unsafe';
|
|
5
5
|
export type SafeWrap<Safe extends Safeness, obj extends object> = Safe extends 'safe' ? {
|
|
@@ -13,14 +13,17 @@ export declare class TransformerTyped<Nodes extends Typed> extends TransformerOb
|
|
|
13
13
|
constructor(defaultContext?: TransformContext, defaultNodePreVisitor?: DefaultNodePreVisitor<Nodes>);
|
|
14
14
|
clone(newDefaultContext?: TransformContext, newDefaultNodePreVisitor?: DefaultNodePreVisitor<Nodes>): TransformerTyped<Nodes>;
|
|
15
15
|
/**
|
|
16
|
-
* Transform a single node.
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
16
|
+
* Transform a single node ({@link Typed}).
|
|
17
|
+
* @param startObject the object from which we will start the transformation,
|
|
18
|
+
* potentially visiting and transforming its descendants along the way.
|
|
19
|
+
* @param nodeCallBacks a dictionary mapping the various node types to objects optionally
|
|
20
|
+
* containing preVisitor and transformer.
|
|
21
|
+
* The preVisitor allows you to provide {@link TransformContext} for the current object,
|
|
22
|
+
* altering how it will be transformed.
|
|
23
|
+
* The transformer allows you to manipulate the copy of the current object,
|
|
24
|
+
* and expects you to return the value that should take the current objects place.
|
|
25
|
+
* @return the result of transforming the requested descendant operations (based on the preVisitor)
|
|
26
|
+
* using a transformer that works its way back up from the descendant to the startObject.
|
|
24
27
|
*/
|
|
25
28
|
transformNode<Safe extends Safeness = 'safe', OutType = unknown>(startObject: object, nodeCallBacks: {
|
|
26
29
|
[T in Nodes['type']]?: {
|
|
@@ -29,10 +32,19 @@ export declare class TransformerTyped<Nodes extends Typed> extends TransformerOb
|
|
|
29
32
|
};
|
|
30
33
|
}): Safe extends 'unsafe' ? OutType : unknown;
|
|
31
34
|
/**
|
|
32
|
-
*
|
|
35
|
+
* Visit a selected subTree given a startObject, steering the visits based on {@link Typed} nodes.
|
|
36
|
+
* Will first call the preVisitor on the project and notice it should not iterate on its descendants.
|
|
37
|
+
* It then visits the project, and the outermost distinct, printing '21'.
|
|
33
38
|
* The pre-visitor visits starting from the root, going deeper, while the actual visitor goes in reverse.
|
|
34
|
-
* @param startObject
|
|
35
|
-
*
|
|
39
|
+
* @param startObject the object from which we will start visiting,
|
|
40
|
+
* potentially visiting its descendants along the way.
|
|
41
|
+
* @param nodeCallBacks a dictionary mapping the various operation types to objects optionally
|
|
42
|
+
* containing preVisitor and visitor.
|
|
43
|
+
* The preVisitor allows you to provide {@link VisitContext} for the current object,
|
|
44
|
+
* altering how it will be visited.
|
|
45
|
+
* The visitor allows you to visit the object from deepest to the outermost object.
|
|
46
|
+
* This is useful if you for example want to manipulate the objects you visit during your visits,
|
|
47
|
+
* similar to {@link this.transformNode}.
|
|
36
48
|
*/
|
|
37
49
|
visitNode(startObject: object, nodeCallBacks: {
|
|
38
50
|
[T in Nodes['type']]?: {
|
|
@@ -40,12 +52,4 @@ export declare class TransformerTyped<Nodes extends Typed> extends TransformerOb
|
|
|
40
52
|
preVisitor?: (op: Extract<Nodes, Typed<T>>) => VisitContext;
|
|
41
53
|
};
|
|
42
54
|
}): void;
|
|
43
|
-
/**
|
|
44
|
-
* Traverses only selected nodes as returned by the function.
|
|
45
|
-
* @param currentNode
|
|
46
|
-
* @param traverse
|
|
47
|
-
*/
|
|
48
|
-
traverseNodes(currentNode: Nodes, traverse: {
|
|
49
|
-
[T in Nodes['type']]?: (op: Extract<Nodes, Typed<T>>) => SelectiveTraversalContext<Nodes>;
|
|
50
|
-
}): void;
|
|
51
55
|
}
|
|
@@ -10,14 +10,17 @@ export class TransformerTyped extends TransformerObject {
|
|
|
10
10
|
return new TransformerTyped({ ...this.defaultContext, ...newDefaultContext }, { ...this.defaultNodePreVisitor, ...newDefaultNodePreVisitor });
|
|
11
11
|
}
|
|
12
12
|
/**
|
|
13
|
-
* Transform a single node.
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
13
|
+
* Transform a single node ({@link Typed}).
|
|
14
|
+
* @param startObject the object from which we will start the transformation,
|
|
15
|
+
* potentially visiting and transforming its descendants along the way.
|
|
16
|
+
* @param nodeCallBacks a dictionary mapping the various node types to objects optionally
|
|
17
|
+
* containing preVisitor and transformer.
|
|
18
|
+
* The preVisitor allows you to provide {@link TransformContext} for the current object,
|
|
19
|
+
* altering how it will be transformed.
|
|
20
|
+
* The transformer allows you to manipulate the copy of the current object,
|
|
21
|
+
* and expects you to return the value that should take the current objects place.
|
|
22
|
+
* @return the result of transforming the requested descendant operations (based on the preVisitor)
|
|
23
|
+
* using a transformer that works its way back up from the descendant to the startObject.
|
|
21
24
|
*/
|
|
22
25
|
transformNode(startObject, nodeCallBacks) {
|
|
23
26
|
const transformWrapper = (copy, orig) => {
|
|
@@ -42,10 +45,19 @@ export class TransformerTyped extends TransformerObject {
|
|
|
42
45
|
return this.transformObject(startObject, transformWrapper, preVisitWrapper);
|
|
43
46
|
}
|
|
44
47
|
/**
|
|
45
|
-
*
|
|
48
|
+
* Visit a selected subTree given a startObject, steering the visits based on {@link Typed} nodes.
|
|
49
|
+
* Will first call the preVisitor on the project and notice it should not iterate on its descendants.
|
|
50
|
+
* It then visits the project, and the outermost distinct, printing '21'.
|
|
46
51
|
* The pre-visitor visits starting from the root, going deeper, while the actual visitor goes in reverse.
|
|
47
|
-
* @param startObject
|
|
48
|
-
*
|
|
52
|
+
* @param startObject the object from which we will start visiting,
|
|
53
|
+
* potentially visiting its descendants along the way.
|
|
54
|
+
* @param nodeCallBacks a dictionary mapping the various operation types to objects optionally
|
|
55
|
+
* containing preVisitor and visitor.
|
|
56
|
+
* The preVisitor allows you to provide {@link VisitContext} for the current object,
|
|
57
|
+
* altering how it will be visited.
|
|
58
|
+
* The visitor allows you to visit the object from deepest to the outermost object.
|
|
59
|
+
* This is useful if you for example want to manipulate the objects you visit during your visits,
|
|
60
|
+
* similar to {@link this.transformNode}.
|
|
49
61
|
*/
|
|
50
62
|
visitNode(startObject, nodeCallBacks) {
|
|
51
63
|
const visitorWrapper = (curObject) => {
|
|
@@ -70,29 +82,5 @@ export class TransformerTyped extends TransformerObject {
|
|
|
70
82
|
};
|
|
71
83
|
return this.visitObject(startObject, visitorWrapper, preVisitWrapper);
|
|
72
84
|
}
|
|
73
|
-
/**
|
|
74
|
-
* Traverses only selected nodes as returned by the function.
|
|
75
|
-
* @param currentNode
|
|
76
|
-
* @param traverse
|
|
77
|
-
*/
|
|
78
|
-
traverseNodes(currentNode, traverse) {
|
|
79
|
-
let didShortCut = false;
|
|
80
|
-
const recurse = (curNode) => {
|
|
81
|
-
const traverser = traverse[curNode.type];
|
|
82
|
-
if (traverser) {
|
|
83
|
-
const { next, shortcut } = traverser(curNode);
|
|
84
|
-
didShortCut = shortcut ?? false;
|
|
85
|
-
if (!didShortCut) {
|
|
86
|
-
for (const node of next ?? []) {
|
|
87
|
-
if (didShortCut) {
|
|
88
|
-
return;
|
|
89
|
-
}
|
|
90
|
-
recurse(node);
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
};
|
|
95
|
-
recurse(currentNode);
|
|
96
|
-
}
|
|
97
85
|
}
|
|
98
86
|
//# sourceMappingURL=TransformerTyped.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TransformerTyped.js","sourceRoot":"","sources":["../../../../lib/transformers/TransformerTyped.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAQ3D,MAAM,OAAO,gBAAsC,SAAQ,iBAAiB;IAG9D;IAFZ,YACE,iBAAmC,EAAE,EAC3B,wBAAsD,EAAE;QAElE,KAAK,CAAC,cAAc,CAAC,CAAC;QAFZ,0BAAqB,GAArB,qBAAqB,CAAmC;IAGpE,CAAC;IAAA,CAAC;IAEc,KAAK,CACnB,oBAAsC,EAAE,EACxC,2BAAyD,EAAE;QAE3D,OAAO,IAAI,gBAAgB,CACzB,EAAE,GAAG,IAAI,CAAC,cAAc,EAAE,GAAG,iBAAiB,EAAE,EAChD,EAAE,GAAG,IAAI,CAAC,qBAAqB,EAAE,GAAG,wBAAwB,EAAE,CAC/D,CAAC;IACJ,CAAC;IAED
|
|
1
|
+
{"version":3,"file":"TransformerTyped.js","sourceRoot":"","sources":["../../../../lib/transformers/TransformerTyped.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Typed } from '../types.js';\nimport type { TransformContext, VisitContext } from './TransformerObject.js';\nimport { TransformerObject } from './TransformerObject.js';\n\nexport type Safeness = 'safe' | 'unsafe';\nexport type SafeWrap<Safe extends Safeness, obj extends object> =\n Safe extends 'safe' ? {[key in keyof obj]: unknown } : obj;\n\nexport type DefaultNodePreVisitor<Nodes extends Typed> = {[T in Nodes['type']]?: TransformContext };\n\nexport class TransformerTyped<Nodes extends Typed> extends TransformerObject {\n public constructor(\n defaultContext: TransformContext = {},\n protected defaultNodePreVisitor: DefaultNodePreVisitor<Nodes> = {},\n ) {\n super(defaultContext);\n };\n\n public override clone(\n newDefaultContext: TransformContext = {},\n newDefaultNodePreVisitor: DefaultNodePreVisitor<Nodes> = {},\n ): TransformerTyped<Nodes> {\n return new TransformerTyped(\n { ...this.defaultContext, ...newDefaultContext },\n { ...this.defaultNodePreVisitor, ...newDefaultNodePreVisitor },\n );\n }\n\n /**\n * Transform a single node ({@link Typed}).\n * @param startObject the object from which we will start the transformation,\n * potentially visiting and transforming its descendants along the way.\n * @param nodeCallBacks a dictionary mapping the various node types to objects optionally\n * containing preVisitor and transformer.\n * The preVisitor allows you to provide {@link TransformContext} for the current object,\n * altering how it will be transformed.\n * The transformer allows you to manipulate the copy of the current object,\n * and expects you to return the value that should take the current objects place.\n * @return the result of transforming the requested descendant operations (based on the preVisitor)\n * using a transformer that works its way back up from the descendant to the startObject.\n */\n public transformNode<Safe extends Safeness = 'safe', OutType = unknown>(\n startObject: object,\n nodeCallBacks: {[T in Nodes['type']]?: {\n transform?: (copy: SafeWrap<Safe, Extract<Nodes, Typed<T>>>, orig: Extract<Nodes, Typed<T>>) => unknown;\n preVisitor?: (orig: Extract<Nodes, Typed<T>>) => TransformContext;\n }},\n ): Safe extends 'unsafe' ? OutType : unknown {\n const transformWrapper = (copy: object, orig: object): unknown => {\n let ogTransform: ((copy: any, orig: any) => unknown) | undefined;\n const casted = <Typed<Nodes['type']>>copy;\n if (casted.type) {\n ogTransform = nodeCallBacks[casted.type]?.transform;\n }\n return ogTransform ? ogTransform(casted, orig) : copy;\n };\n const nodeDefaults = this.defaultNodePreVisitor;\n const preVisitWrapper = (curObject: object): VisitContext => {\n let ogPreVisit: ((node: any) => VisitContext) | undefined;\n let nodeContext: VisitContext = {};\n const casted = <Typed<Nodes['type']>>curObject;\n if (casted.type) {\n ogPreVisit = nodeCallBacks[casted.type]?.preVisitor;\n nodeContext = nodeDefaults[casted.type] ?? nodeContext;\n }\n return ogPreVisit ? { ...nodeContext, ...ogPreVisit(casted) } : nodeContext;\n };\n return <any> this.transformObject(startObject, transformWrapper, preVisitWrapper);\n }\n\n /**\n * Visit a selected subTree given a startObject, steering the visits based on {@link Typed} nodes.\n * Will first call the preVisitor on the project and notice it should not iterate on its descendants.\n * It then visits the project, and the outermost distinct, printing '21'.\n * The pre-visitor visits starting from the root, going deeper, while the actual visitor goes in reverse.\n * @param startObject the object from which we will start visiting,\n * potentially visiting its descendants along the way.\n * @param nodeCallBacks a dictionary mapping the various operation types to objects optionally\n * containing preVisitor and visitor.\n * The preVisitor allows you to provide {@link VisitContext} for the current object,\n * altering how it will be visited.\n * The visitor allows you to visit the object from deepest to the outermost object.\n * This is useful if you for example want to manipulate the objects you visit during your visits,\n * similar to {@link this.transformNode}.\n */\n public visitNode(\n startObject: object,\n nodeCallBacks: {[T in Nodes['type']]?: {\n visitor?: (op: Extract<Nodes, Typed<T>>) => void;\n preVisitor?: (op: Extract<Nodes, Typed<T>>) => VisitContext;\n }},\n ): void {\n const visitorWrapper = (curObject: object): void => {\n const casted = <Typed<Nodes['type']>>curObject;\n if (casted.type) {\n const ogTransform = nodeCallBacks[casted.type]?.visitor;\n if (ogTransform) {\n ogTransform(<any> casted);\n }\n }\n };\n const nodeDefaults = this.defaultNodePreVisitor;\n const preVisitWrapper = (curObject: object): VisitContext => {\n let ogPreVisit: ((node: any) => VisitContext) | undefined;\n let nodeContext: VisitContext = {};\n const casted = <Typed<Nodes['type']>>curObject;\n if (casted.type) {\n ogPreVisit = nodeCallBacks[casted.type]?.preVisitor;\n nodeContext = nodeDefaults[casted.type] ?? nodeContext;\n }\n return ogPreVisit ? { ...nodeContext, ...ogPreVisit(casted) } : nodeContext;\n };\n return this.visitObject(startObject, visitorWrapper, preVisitWrapper);\n }\n}\n"]}
|
package/dist/esm/lib/types.d.ts
CHANGED
|
@@ -1,17 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type that is used by the Traqula core package to type raw objects/ Data Transfer Objects (DTO).
|
|
3
|
+
* Enforces the presence of a type string, and that in case the subType key is present, it also be a string.
|
|
4
|
+
*/
|
|
1
5
|
export interface Typed<Type extends string = string> {
|
|
2
6
|
type: Type;
|
|
3
7
|
subType?: string;
|
|
4
8
|
}
|
|
9
|
+
/**
|
|
10
|
+
* A {@link Typed} object that is sure to have a subType
|
|
11
|
+
*/
|
|
5
12
|
export interface SubTyped<Type extends string = string, SubType extends string = string> extends Typed<Type> {
|
|
6
13
|
subType: SubType;
|
|
7
14
|
}
|
|
15
|
+
/**
|
|
16
|
+
* Type used by the parser and generator builders of the core Traqula package to annotate
|
|
17
|
+
* the relation between AST objects and the source string.
|
|
18
|
+
*/
|
|
8
19
|
export interface Localized {
|
|
9
|
-
/**
|
|
10
|
-
* Location undefined means the node does have a string representation, but it was not clarified.
|
|
11
|
-
* This happens when an AST node is patched by a client of the lib.
|
|
12
|
-
*/
|
|
13
20
|
loc: SourceLocation;
|
|
14
21
|
}
|
|
22
|
+
/**
|
|
23
|
+
* Wrapper type for localization,
|
|
24
|
+
* can be used to state localization information about any other type (including primitive types)
|
|
25
|
+
*/
|
|
15
26
|
export interface Wrap<T> extends Localized {
|
|
16
27
|
val: T;
|
|
17
28
|
}
|
|
@@ -24,11 +35,38 @@ export interface Node extends Localized, Typed {
|
|
|
24
35
|
export interface SourceLocationBase {
|
|
25
36
|
sourceLocationType: string;
|
|
26
37
|
}
|
|
38
|
+
/**
|
|
39
|
+
* SourceLocation type that annotates that the node represents the AST representation of
|
|
40
|
+
* the given range in the source string.
|
|
41
|
+
*/
|
|
27
42
|
export interface SourceLocationSource extends SourceLocationBase {
|
|
28
43
|
sourceLocationType: 'source';
|
|
29
44
|
start: number;
|
|
30
45
|
end: number;
|
|
31
46
|
}
|
|
47
|
+
/**
|
|
48
|
+
* Similar to {@link SourceLocationSource} but also carrying the source it related too.
|
|
49
|
+
* All sourceLocation nodes that are descends of this one, relate themselves to this source.
|
|
50
|
+
*/
|
|
51
|
+
export interface SourceLocationInlinedSource extends SourceLocationBase, Localized {
|
|
52
|
+
sourceLocationType: 'inlinedSource';
|
|
53
|
+
/**
|
|
54
|
+
* The string that will be used as the source for this node and the descends of this node.
|
|
55
|
+
* Note that the generator will print the characters from newSource[0] until start. Likewise for the suffix.
|
|
56
|
+
*/
|
|
57
|
+
newSource: string;
|
|
58
|
+
/**
|
|
59
|
+
* Behavior of the current loc, after replacing the source string.
|
|
60
|
+
*/
|
|
61
|
+
loc: SourceLocation;
|
|
62
|
+
/**
|
|
63
|
+
* The range that this node replaces in the context of the original source.
|
|
64
|
+
*/
|
|
65
|
+
start: number;
|
|
66
|
+
end: number;
|
|
67
|
+
startOnNew: number;
|
|
68
|
+
endOnNew: number;
|
|
69
|
+
}
|
|
32
70
|
/**
|
|
33
71
|
* NoStringManifestation means the node does not have a string representation.
|
|
34
72
|
* For example the literal '5' has an integer type (which is an AST node),
|
|
@@ -38,15 +76,39 @@ export interface SourceLocationSource extends SourceLocationBase {
|
|
|
38
76
|
export interface SourceLocationNoMaterialize extends SourceLocationBase {
|
|
39
77
|
sourceLocationType: 'noMaterialize';
|
|
40
78
|
}
|
|
79
|
+
/**
|
|
80
|
+
* SourceLocation type that annotates that the node has been replaced
|
|
81
|
+
* in relation to the original string by a new string.
|
|
82
|
+
* It means that this node should be generated, and that the source string from start to end has been changed.
|
|
83
|
+
*/
|
|
41
84
|
export interface SourceLocationStringReplace extends SourceLocationBase {
|
|
42
85
|
sourceLocationType: 'stringReplace';
|
|
86
|
+
/**
|
|
87
|
+
* The string that will replace the given range in the original source.
|
|
88
|
+
*/
|
|
43
89
|
newSource: string;
|
|
90
|
+
/**
|
|
91
|
+
* The start of the region in the original source string that this node replaces.
|
|
92
|
+
*/
|
|
44
93
|
start: number;
|
|
94
|
+
/**
|
|
95
|
+
* The end of the region in the original source string that this node replaces.
|
|
96
|
+
*/
|
|
45
97
|
end: number;
|
|
46
98
|
}
|
|
99
|
+
/**
|
|
100
|
+
* SourceLocation type that annotates that the node has been replaced in relation to the original string.
|
|
101
|
+
* It means that this node should be generated, and that the source string from start to end has been changed.
|
|
102
|
+
*/
|
|
47
103
|
export interface SourceLocationNodeReplace extends SourceLocationBase {
|
|
48
104
|
sourceLocationType: 'nodeReplace';
|
|
105
|
+
/**
|
|
106
|
+
* The start of the region in the original source string that this node replaces.
|
|
107
|
+
*/
|
|
49
108
|
start: number;
|
|
109
|
+
/**
|
|
110
|
+
* The end of the region in the original source string that this node replaces.
|
|
111
|
+
*/
|
|
50
112
|
end: number;
|
|
51
113
|
}
|
|
52
114
|
/**
|
|
@@ -55,4 +117,4 @@ export interface SourceLocationNodeReplace extends SourceLocationBase {
|
|
|
55
117
|
export interface SourceLocationNodeAutoGenerate extends SourceLocationBase {
|
|
56
118
|
sourceLocationType: 'autoGenerate';
|
|
57
119
|
}
|
|
58
|
-
export type SourceLocation = SourceLocationSource | SourceLocationNoMaterialize | SourceLocationStringReplace | SourceLocationNodeReplace | SourceLocationNodeAutoGenerate;
|
|
120
|
+
export type SourceLocation = SourceLocationSource | SourceLocationInlinedSource | SourceLocationNoMaterialize | SourceLocationStringReplace | SourceLocationNodeReplace | SourceLocationNodeAutoGenerate;
|