@deepkit/core
Version:
Deepkit core library
128 lines • 5.67 kB
JavaScript
"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