UNPKG

@deepkit/core

Version:

Deepkit core library

128 lines 5.67 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.CompilerContext = void 0; const __ΩPartial = ['T', 'Partial', 'l+e#!e"!fRb!Pde"!gN#"w"y']; /* * Deepkit Framework * Copyright (C) 2021 Deepkit UG, Marc J. Schmidt * * This program is free software: you can redistribute it and/or modify * it under the terms of the MIT License. * * You should have received a copy of the MIT License along with this program. */ // @ts-ignore const indent_js_1 = require("./indent.js"); const core_js_1 = require("./core.js"); const indentCode = ('undefined' !== typeof process && process.env?.DEBUG || '').includes('deepkit'); class CompilerContext { constructor(config = {}) { this.context = (Map.Ω = [['&'], ['"']], new Map()); this.constVariables = (Map.Ω = [['"'], ['&']], new Map()); this.maxReservedVariable = 10000; this.reservedNames = (Set.Ω = [['&']], new Set()); this.variableContext = {}; /** * Code that is executed in the context, but before the actual function is generated. * This helps for example to initialize dynamically some context variables. */ this.preCode = ''; this.initialiseVariables = []; this.config = { indent: false }; Object.assign(this.config, config); this.context.set('_context', this.variableContext); } reserveName(name) { for (let i = 0; i < this.maxReservedVariable; i++) { const candidate = name + '_' + i; if (!this.reservedNames.has(candidate)) { this.reservedNames.add(candidate); return candidate; } } throw new Error(`Too many context variables (max ${this.maxReservedVariable})`); } set(values) { for (const i in values) { if (!(0, core_js_1.hasProperty)(values, i)) { continue; } this.context.set(i, values[i]); } } /** * Returns always the same variable name for the same value. * The variable name should not be set afterwards. */ reserveConst(value, name = 'constVar') { if (value === undefined) throw new Error('Can not reserve const for undefined value'); let constName = this.constVariables.get(value); if (!constName) { constName = this.reserveName(name); this.constVariables.set(value, constName); this.context.set(constName, value); } return constName; } reserveVariable(name = 'var', value) { const freeName = this.reserveName(name); if (value === undefined) { //to get monomorphic variables, we return a reference to an unassigned object property (which has no type per se) return '_context.' + freeName; } else { //in case when the variable has a value, we simply store it, since it (hopefully) is monomorphic. this.context.set(freeName, value); return freeName; } } raw(functionCode) { try { return new Function(...this.context.keys(), `'use strict';\n` + functionCode)(...this.context.values()); } catch (error) { throw new Error('Could not build function: ' + error + functionCode); } } format(code) { if (indentCode || this.config.indent) return indent_js_1.indent.js(code, { tabString: ' ' }); return code; } build(functionCode, ...args) { functionCode = this.format(` 'use strict'; ${this.preCode} return function self(${args.join(', ')}){ 'use strict'; ${functionCode} }; `); try { return new Function(...this.context.keys(), functionCode)(...this.context.values()); } catch (error) { throw new Error(`Could not build function(${[...this.context.keys()].join(',')}): ` + error + functionCode); } } buildAsync(functionCode, ...args) { functionCode = ` 'use strict'; ${this.preCode} return async function self(${args.join(', ')}){ 'use strict'; ${functionCode} }; `; try { return new Function(...this.context.keys(), this.format(functionCode))(...this.context.values()); } catch (error) { throw new Error('Could not build function: ' + error + functionCode); } } } exports.CompilerContext = CompilerContext; CompilerContext.__type = ['context', function () { return (Map.Ω = [['&'], ['"']], new Map()); }, 'constVariables', function () { return (Map.Ω = [['"'], ['&']], new Map()); }, 'maxReservedVariable', function () { return 10000; }, 'reservedNames', function () { return (Set.Ω = [['&']], new Set()); }, 'variableContext', function () { return {}; }, 'preCode', function () { return ''; }, 'initialiseVariables', function () { return []; }, 'indent', 'config', function () { return { indent: false }; }, () => __ΩPartial, () => CompilerContext, "config", () => ({}), 'constructor', 'name', 'reserveName', 'values', 'set', 'value', () => "constVar", 'reserveConst', () => "var", 'reserveVariable', 'functionCode', () => Function, 'raw', 'code', 'format', 'args', 'build', () => Function, 'buildAsync', 'CompilerContext', '!3!9>"!3#<>$\'3%>&!3\'<>(P&"LM3)<>*&3+>,&F3->.P)4/M30>1PP73.4fo2"20>5"06P&27&08PP&"LM29"0:P"2;&27><&0=P&27>>"2;8&0?P&2@PuA0BP&2C&0D<P&2@&@2E"0FP&2@&@2EPuG0H5wI']; //# sourceMappingURL=compiler.js.map