MCPcopy Create free account
hub / github.com/Snapchat/Valdi / templateFunctionStr

Function templateFunctionStr

valdi/vscode_debugger/src/adapter/templates/index.ts:49–109  ·  view source on GitHub ↗
(
  stringified: string,
)

Source from the content-addressed store, hash-verified

47}
48
49export function templateFunctionStr<Args extends string[]>(
50 stringified: string,
51): (...args: Args) => string {
52 const sourceFile = ts.createSourceFile('test.js', stringified, ts.ScriptTarget.ESNext, true);
53
54 // 1. Find the function.
55 let decl: ts.FunctionLike | undefined;
56 ts.forEachChild(sourceFile, function traverse(node) {
57 if (ts.isFunctionLike(node)) {
58 decl = node;
59 } else {
60 ts.forEachChild(node, traverse);
61 }
62 });
63
64 if (!decl || !('body' in decl) || !decl.body) {
65 throw new Error(`Could not find function declaration for:\n\n${stringified}`);
66 }
67
68 // 2. Get parameter names.
69 const params = decl.parameters.map(p => {
70 if (!ts.isIdentifier(p.name)) {
71 throw new Error('Parameter must be identifier');
72 }
73
74 return p.name.text;
75 });
76
77 // 3. Gather usages of the parameter in the source.
78 const replacements: { start: number; end: number; param: number }[] = [];
79 ts.forEachChild(decl.body, function traverse(node) {
80 if (ts.isIdentifier(node) && params.includes(node.text)) {
81 replacements.push({
82 start: node.getStart(),
83 end: node.getEnd(),
84 param: params.indexOf(node.text),
85 });
86 }
87
88 ts.forEachChild(node, traverse);
89 });
90
91 replacements.sort((a, b) => b.end - a.end);
92
93 // 4. Sort usages and slice up the function appropriately, wraping in an IIFE.
94 const parts: string[] = [];
95 let lastIndex = decl.body.getEnd() - 1;
96 for (const replacement of replacements) {
97 parts.push(stringified.slice(replacement.end, lastIndex));
98 parts.push(`__args${replacement.param}`);
99 lastIndex = replacement.start;
100 }
101
102 parts.push(stringified.slice(decl.body.getStart() + 1, lastIndex));
103 const body = parts.reverse().join('');
104
105 return (...args) => `(() => {
106 ${args.map((a, i) => `let __args${i} = ${a}`).join('; ')};

Callers 1

templateFunctionFunction · 0.85

Calls 8

isIdentifierMethod · 0.80
getEndMethod · 0.80
sortMethod · 0.65
createSourceFileMethod · 0.45
mapMethod · 0.45
pushMethod · 0.45
indexOfMethod · 0.45
joinMethod · 0.45

Tested by

no test coverage detected