-
Notifications
You must be signed in to change notification settings - Fork 3
/
dynamic-function-registry.ts
61 lines (52 loc) · 2.24 KB
/
dynamic-function-registry.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
import {IFunctionDefinition} from "./function-defintion";
import {SimpleMap} from "../util/simple-map";
import {IFunctionId, functionId, isFunctionId} from "./function-id";
import {getFunctionName} from "../util/function-name";
/**
* Lookup table for resolving dynamic functions and their definitions
*/
export class DynamicFunctionRegistry {
private ids = new SimpleMap<string, IFunctionId>();
private definitions = new SimpleMap<string, IFunctionDefinition>();
private lastId = 0;
/**
* Returns the unique id for the passed in function or assigns a new id to the given function and returns the newly assigned id
* @param func the function for which the unique id should be determined
* @returns the id of this function
*/
public getOrSetId(func: Function | IFunctionId): IFunctionId {
if (isFunctionId(func)) {
return func;
}
const source = func.toString();
let identifier = this.ids.get(source);
if (typeof (identifier) === "undefined") {
identifier = functionId("dynamic", ++this.lastId);
this.initDefinition(func, identifier);
}
return identifier;
}
/**
* Returns the definition of the function with the given id or undefined, if the id is not assigned to any function definition
* @param id the id of the function to resolve
* @returns the resolved function definition or undefined
* @throws if the function is a static function and therefore no definition exists.
*/
public getDefinition(id: IFunctionId): IFunctionDefinition | undefined {
return this.definitions.get(id.identifier);
}
private initDefinition(func: Function, id: IFunctionId) {
const source = func.toString();
const name = getFunctionName(func);
const args = source.substring(source.indexOf("(") + 1, source.indexOf(")")).split(",");
const body = source.substring(source.indexOf("{") + 1, source.lastIndexOf("}")).trim();
const definition = {
argumentNames: args.map(arg => arg.trim()),
body,
id,
name: name ? name : undefined
};
this.ids.set(source, id);
this.definitions.set(id.identifier, definition);
}
}