Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/extensions/copilot/src/platform/inlineEdits/common/utils/tsExpr.ts
13405 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
export class TsExpr {
7
static str(value: string): TsExpr;
8
static str(strings: TemplateStringsArray, ...values: unknown[]): TsExpr;
9
static str(strings: TemplateStringsArray | string, ...values: unknown[]): TsExpr {
10
if (typeof strings === 'string') {
11
return new TsExpr([strings]);
12
} else {
13
const parts: (string | { value: unknown })[] = [];
14
for (let i = 0; i < strings.length; i++) {
15
parts.push(strings[i]);
16
if (i < values.length) {
17
parts.push({ value: values[i] });
18
}
19
}
20
21
// TODO remove indentation
22
23
return new TsExpr(parts);
24
}
25
26
}
27
28
constructor(public readonly parts: (string | { value: unknown })[]) { }
29
30
toString() {
31
return _serializeToTs(this, 0);
32
}
33
}
34
35
function _serializeToTs(data: unknown, newLineIndentation: number): string {
36
if (data && typeof data === 'object') {
37
38
if (data instanceof TsExpr) {
39
let lastIndentation = 0;
40
const result = data.parts.map(p => {
41
if (typeof p === 'string') {
42
lastIndentation = getIndentOfLastLine(p);
43
return p;
44
} else {
45
return _serializeToTs(p.value, lastIndentation);
46
}
47
}).join('');
48
49
return indentNonFirstLines(result, newLineIndentation);
50
}
51
52
if (Array.isArray(data)) {
53
const entries: string[] = [];
54
for (const value of data) {
55
entries.push(_serializeToTs(value, newLineIndentation + 1));
56
}
57
58
return `[\n`
59
+ entries.map(e => indentLine(e, newLineIndentation + 1) + ',\n').join('')
60
+ indentLine(`]`, newLineIndentation);
61
}
62
63
const entries: string[] = [];
64
for (const [key, value] of Object.entries(data)) {
65
entries.push(`${serializeObjectKey(key)}: ${_serializeToTs(value, newLineIndentation + 1)},\n`);
66
}
67
return `{\n`
68
+ entries.map(e => indentLine(e, newLineIndentation + 1)).join('')
69
+ indentLine(`}`, newLineIndentation);
70
}
71
72
if (data === undefined) {
73
return indentNonFirstLines('undefined', newLineIndentation);
74
}
75
76
return indentNonFirstLines(JSON.stringify(data, undefined, '\t'), newLineIndentation);
77
}
78
79
function getIndentOfLastLine(str: string): number {
80
const lines = str.split('\n');
81
const lastLine = lines[lines.length - 1];
82
return lastLine.length - lastLine.trimStart().length;
83
}
84
85
function indentNonFirstLines(str: string, indentation: number): string {
86
const lines = str.split('\n');
87
return lines.map((line, i) => i === 0 ? line : indentLine(line, indentation)).join('\n');
88
}
89
90
function indentLine(str: string, indentation: number): string {
91
return '\t'.repeat(indentation) + str;
92
}
93
94
function serializeObjectKey(key: string): string {
95
if (/^[a-zA-Z_]\w*$/.test(key)) {
96
return key;
97
}
98
return JSON.stringify(key);
99
}
100
101