@deepkit/core
Advanced tools
Comparing version 1.0.1-alpha.48 to 1.0.1-alpha.52
export declare class CompilerContext { | ||
readonly context: Map<string, any>; | ||
protected constVariables: Map<any, string>; | ||
maxReservedVariable: number; | ||
protected reservedNames: Set<string>; | ||
protected variableContext: { | ||
[name: string]: any; | ||
}; | ||
/** | ||
@@ -9,2 +14,10 @@ * Code that is executed in the context, but before the actual function is generated. | ||
preCode: string; | ||
initialiseVariables: string[]; | ||
constructor(); | ||
reserveName(name: string): string; | ||
/** | ||
* Returns always the same variable name for the same value. | ||
* The variable name should not be set afterwards. | ||
*/ | ||
reserveConst(value: any, name?: string): string; | ||
reserveVariable(name?: string, value?: any): string; | ||
@@ -11,0 +24,0 @@ raw(functionCode: string): Function; |
@@ -16,3 +16,6 @@ "use strict"; | ||
this.context = new Map(); | ||
this.constVariables = new Map(); | ||
this.maxReservedVariable = 10000; | ||
this.reservedNames = new Set(); | ||
this.variableContext = {}; | ||
/** | ||
@@ -23,8 +26,10 @@ * Code that is executed in the context, but before the actual function is generated. | ||
this.preCode = ''; | ||
this.initialiseVariables = []; | ||
this.context.set('_context', this.variableContext); | ||
} | ||
reserveVariable(name = 'var', value) { | ||
reserveName(name) { | ||
for (let i = 0; i < this.maxReservedVariable; i++) { | ||
const candidate = name + '_' + i; | ||
if (!this.context.has(candidate)) { | ||
this.context.set(candidate, value); | ||
if (!this.reservedNames.has(candidate)) { | ||
this.reservedNames.add(candidate); | ||
return candidate; | ||
@@ -35,4 +40,31 @@ } | ||
} | ||
/** | ||
* 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) { | ||
return new Function(...this.context.keys(), functionCode)(...this.context.values()); | ||
return new Function(...this.context.keys(), `'use strict';\n` + functionCode)(...this.context.values()); | ||
} | ||
@@ -52,3 +84,3 @@ build(functionCode, ...args) { | ||
catch (error) { | ||
throw new Error('Could not build function: ' + error + functionCode); | ||
throw new Error(`Could not build function(${[...this.context.keys()].join(',')}): ` + error + functionCode); | ||
} | ||
@@ -55,0 +87,0 @@ } |
@@ -110,3 +110,3 @@ /** | ||
*/ | ||
export declare function changeClass<T>(value: any, newClass: ClassType<T>): T; | ||
export declare function changeClass<T>(value: object, newClass: ClassType<T>): T; | ||
export declare function prettyPrintObject(object: object): string; | ||
@@ -113,0 +113,0 @@ /** |
@@ -7,16 +7,17 @@ "use strict"; | ||
const compiler = new compiler_1.CompilerContext(); | ||
globals_1.expect(compiler.reserveVariable('a')).toBe('a_0'); | ||
globals_1.expect(compiler.reserveVariable('a')).toBe('a_1'); | ||
globals_1.expect(compiler.reserveVariable('a')).toBe('a_2'); | ||
globals_1.expect(compiler.reserveVariable('a')).toBe('a_3'); | ||
globals_1.expect(compiler.reserveVariable('a')).toBe('a_4'); | ||
globals_1.expect(compiler.reserveVariable('a')).toBe('a_5'); | ||
globals_1.expect(compiler.reserveVariable('a')).toBe('a_6'); | ||
globals_1.expect(compiler.reserveVariable('a')).toBe('a_7'); | ||
globals_1.expect(compiler.reserveVariable('a')).toBe('a_8'); | ||
globals_1.expect(compiler.reserveVariable('a')).toBe('a_9'); | ||
globals_1.expect(compiler.reserveVariable('a')).toBe('a_10'); | ||
globals_1.expect(compiler.reserveVariable('a')).toBe('a_11'); | ||
globals_1.expect(compiler.reserveVariable('a')).toBe('a_12'); | ||
globals_1.expect(compiler.reserveVariable('a')).toBe('a_13'); | ||
globals_1.expect(compiler.reserveVariable('a', true)).toBe('a_0'); | ||
globals_1.expect(compiler.reserveVariable('a', false)).toBe('a_1'); | ||
globals_1.expect(compiler.reserveVariable('a', 0)).toBe('a_2'); | ||
globals_1.expect(compiler.reserveVariable('a', 1)).toBe('a_3'); | ||
globals_1.expect(compiler.reserveVariable('a', '')).toBe('a_4'); | ||
globals_1.expect(compiler.reserveVariable('a', 'bar')).toBe('a_5'); | ||
globals_1.expect(compiler.reserveVariable('a', 'bar')).toBe('a_6'); | ||
globals_1.expect(compiler.reserveVariable('a', 'bar')).toBe('a_7'); | ||
globals_1.expect(compiler.reserveVariable('a', 'bar')).toBe('a_8'); | ||
globals_1.expect(compiler.reserveVariable('a', 'bar')).toBe('a_9'); | ||
globals_1.expect(compiler.reserveVariable('a', 'bar')).toBe('a_10'); | ||
globals_1.expect(compiler.reserveVariable('a', 'bar')).toBe('a_11'); | ||
globals_1.expect(compiler.reserveVariable('a', 'bar')).toBe('a_12'); | ||
globals_1.expect(compiler.reserveVariable('a', 'bar')).toBe('a_13'); | ||
globals_1.expect(compiler.reserveVariable('a')).toBe('_context.a_14'); | ||
}); | ||
@@ -23,0 +24,0 @@ globals_1.test('compiler code', () => { |
export declare class CompilerContext { | ||
readonly context: Map<string, any>; | ||
protected constVariables: Map<any, string>; | ||
maxReservedVariable: number; | ||
protected reservedNames: Set<string>; | ||
protected variableContext: { | ||
[name: string]: any; | ||
}; | ||
/** | ||
@@ -9,2 +14,10 @@ * Code that is executed in the context, but before the actual function is generated. | ||
preCode: string; | ||
initialiseVariables: string[]; | ||
constructor(); | ||
reserveName(name: string): string; | ||
/** | ||
* Returns always the same variable name for the same value. | ||
* The variable name should not be set afterwards. | ||
*/ | ||
reserveConst(value: any, name?: string): string; | ||
reserveVariable(name?: string, value?: any): string; | ||
@@ -11,0 +24,0 @@ raw(functionCode: string): Function; |
@@ -13,3 +13,6 @@ /* | ||
this.context = new Map(); | ||
this.constVariables = new Map(); | ||
this.maxReservedVariable = 10000; | ||
this.reservedNames = new Set(); | ||
this.variableContext = {}; | ||
/** | ||
@@ -20,8 +23,10 @@ * Code that is executed in the context, but before the actual function is generated. | ||
this.preCode = ''; | ||
this.initialiseVariables = []; | ||
this.context.set('_context', this.variableContext); | ||
} | ||
reserveVariable(name = 'var', value) { | ||
reserveName(name) { | ||
for (let i = 0; i < this.maxReservedVariable; i++) { | ||
const candidate = name + '_' + i; | ||
if (!this.context.has(candidate)) { | ||
this.context.set(candidate, value); | ||
if (!this.reservedNames.has(candidate)) { | ||
this.reservedNames.add(candidate); | ||
return candidate; | ||
@@ -32,4 +37,31 @@ } | ||
} | ||
/** | ||
* 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) { | ||
return new Function(...this.context.keys(), functionCode)(...this.context.values()); | ||
return new Function(...this.context.keys(), `'use strict';\n` + functionCode)(...this.context.values()); | ||
} | ||
@@ -49,3 +81,3 @@ build(functionCode, ...args) { | ||
catch (error) { | ||
throw new Error('Could not build function: ' + error + functionCode); | ||
throw new Error(`Could not build function(${[...this.context.keys()].join(',')}): ` + error + functionCode); | ||
} | ||
@@ -52,0 +84,0 @@ } |
@@ -110,3 +110,3 @@ /** | ||
*/ | ||
export declare function changeClass<T>(value: any, newClass: ClassType<T>): T; | ||
export declare function changeClass<T>(value: object, newClass: ClassType<T>): T; | ||
export declare function prettyPrintObject(object: object): string; | ||
@@ -113,0 +113,0 @@ /** |
@@ -5,16 +5,17 @@ import { expect, test } from '@jest/globals'; | ||
const compiler = new CompilerContext(); | ||
expect(compiler.reserveVariable('a')).toBe('a_0'); | ||
expect(compiler.reserveVariable('a')).toBe('a_1'); | ||
expect(compiler.reserveVariable('a')).toBe('a_2'); | ||
expect(compiler.reserveVariable('a')).toBe('a_3'); | ||
expect(compiler.reserveVariable('a')).toBe('a_4'); | ||
expect(compiler.reserveVariable('a')).toBe('a_5'); | ||
expect(compiler.reserveVariable('a')).toBe('a_6'); | ||
expect(compiler.reserveVariable('a')).toBe('a_7'); | ||
expect(compiler.reserveVariable('a')).toBe('a_8'); | ||
expect(compiler.reserveVariable('a')).toBe('a_9'); | ||
expect(compiler.reserveVariable('a')).toBe('a_10'); | ||
expect(compiler.reserveVariable('a')).toBe('a_11'); | ||
expect(compiler.reserveVariable('a')).toBe('a_12'); | ||
expect(compiler.reserveVariable('a')).toBe('a_13'); | ||
expect(compiler.reserveVariable('a', true)).toBe('a_0'); | ||
expect(compiler.reserveVariable('a', false)).toBe('a_1'); | ||
expect(compiler.reserveVariable('a', 0)).toBe('a_2'); | ||
expect(compiler.reserveVariable('a', 1)).toBe('a_3'); | ||
expect(compiler.reserveVariable('a', '')).toBe('a_4'); | ||
expect(compiler.reserveVariable('a', 'bar')).toBe('a_5'); | ||
expect(compiler.reserveVariable('a', 'bar')).toBe('a_6'); | ||
expect(compiler.reserveVariable('a', 'bar')).toBe('a_7'); | ||
expect(compiler.reserveVariable('a', 'bar')).toBe('a_8'); | ||
expect(compiler.reserveVariable('a', 'bar')).toBe('a_9'); | ||
expect(compiler.reserveVariable('a', 'bar')).toBe('a_10'); | ||
expect(compiler.reserveVariable('a', 'bar')).toBe('a_11'); | ||
expect(compiler.reserveVariable('a', 'bar')).toBe('a_12'); | ||
expect(compiler.reserveVariable('a', 'bar')).toBe('a_13'); | ||
expect(compiler.reserveVariable('a')).toBe('_context.a_14'); | ||
}); | ||
@@ -21,0 +22,0 @@ test('compiler code', () => { |
{ | ||
"name": "@deepkit/core", | ||
"version": "1.0.1-alpha.48", | ||
"version": "1.0.1-alpha.52", | ||
"description": "Deepkit core library", | ||
@@ -40,3 +40,3 @@ "type": "commonjs", | ||
}, | ||
"gitHead": "8e7a12c811318244eb165e32b526a51cb50b95c1" | ||
"gitHead": "537ea1f1691917da4697c8f31f8ce9f1d7c16679" | ||
} |
@@ -13,4 +13,7 @@ /* | ||
public readonly context = new Map<string, any>(); | ||
protected constVariables = new Map<any, string>(); | ||
public maxReservedVariable: number = 10_000; | ||
protected reservedNames = new Set<string>(); | ||
protected variableContext: { [name: string]: any } = {}; | ||
@@ -23,7 +26,13 @@ /** | ||
reserveVariable(name: string = 'var', value?: any): string { | ||
public initialiseVariables: string[] = []; | ||
constructor() { | ||
this.context.set('_context', this.variableContext); | ||
} | ||
reserveName(name: string): string { | ||
for (let i = 0; i < this.maxReservedVariable; i++) { | ||
const candidate = name + '_' + i; | ||
if (!this.context.has(candidate)) { | ||
this.context.set(candidate, value); | ||
if (!this.reservedNames.has(candidate)) { | ||
this.reservedNames.add(candidate); | ||
return candidate; | ||
@@ -36,4 +45,32 @@ } | ||
/** | ||
* Returns always the same variable name for the same value. | ||
* The variable name should not be set afterwards. | ||
*/ | ||
reserveConst(value: any, name: string = 'constVar'): string { | ||
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: string = 'var', value?: any): string { | ||
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: string): Function { | ||
return new Function(...this.context.keys(), functionCode)(...this.context.values()); | ||
return new Function(...this.context.keys(), `'use strict';\n` + functionCode)(...this.context.values()); | ||
} | ||
@@ -53,3 +90,3 @@ | ||
} catch (error) { | ||
throw new Error('Could not build function: ' + error + functionCode); | ||
throw new Error(`Could not build function(${[...this.context.keys()].join(',')}): ` + error + functionCode); | ||
} | ||
@@ -56,0 +93,0 @@ } |
@@ -177,3 +177,3 @@ /* | ||
*/ | ||
export function changeClass<T>(value: any, newClass: ClassType<T>): T { | ||
export function changeClass<T>(value: object, newClass: ClassType<T>): T { | ||
return Object.assign(Object.create(newClass.prototype), value); | ||
@@ -180,0 +180,0 @@ } |
@@ -7,16 +7,19 @@ import { expect, test } from '@jest/globals'; | ||
expect(compiler.reserveVariable('a')).toBe('a_0'); | ||
expect(compiler.reserveVariable('a')).toBe('a_1'); | ||
expect(compiler.reserveVariable('a')).toBe('a_2'); | ||
expect(compiler.reserveVariable('a')).toBe('a_3'); | ||
expect(compiler.reserveVariable('a')).toBe('a_4'); | ||
expect(compiler.reserveVariable('a')).toBe('a_5'); | ||
expect(compiler.reserveVariable('a')).toBe('a_6'); | ||
expect(compiler.reserveVariable('a')).toBe('a_7'); | ||
expect(compiler.reserveVariable('a')).toBe('a_8'); | ||
expect(compiler.reserveVariable('a')).toBe('a_9'); | ||
expect(compiler.reserveVariable('a')).toBe('a_10'); | ||
expect(compiler.reserveVariable('a')).toBe('a_11'); | ||
expect(compiler.reserveVariable('a')).toBe('a_12'); | ||
expect(compiler.reserveVariable('a')).toBe('a_13'); | ||
expect(compiler.reserveVariable('a', true)).toBe('a_0'); | ||
expect(compiler.reserveVariable('a', false)).toBe('a_1'); | ||
expect(compiler.reserveVariable('a', 0)).toBe('a_2'); | ||
expect(compiler.reserveVariable('a', 1)).toBe('a_3'); | ||
expect(compiler.reserveVariable('a', '')).toBe('a_4'); | ||
expect(compiler.reserveVariable('a', 'bar')).toBe('a_5'); | ||
expect(compiler.reserveVariable('a', 'bar')).toBe('a_6'); | ||
expect(compiler.reserveVariable('a', 'bar')).toBe('a_7'); | ||
expect(compiler.reserveVariable('a', 'bar')).toBe('a_8'); | ||
expect(compiler.reserveVariable('a', 'bar')).toBe('a_9'); | ||
expect(compiler.reserveVariable('a', 'bar')).toBe('a_10'); | ||
expect(compiler.reserveVariable('a', 'bar')).toBe('a_11'); | ||
expect(compiler.reserveVariable('a', 'bar')).toBe('a_12'); | ||
expect(compiler.reserveVariable('a', 'bar')).toBe('a_13'); | ||
expect(compiler.reserveVariable('a')).toBe('_context.a_14'); | ||
}); | ||
@@ -23,0 +26,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
510895
9036