-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
/
generateCodeSnippets.ts
128 lines (120 loc) · 4.02 KB
/
generateCodeSnippets.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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
import { NormalizedOutputOptions } from '../rollup/types';
import { RESERVED_NAMES } from './reservedNames';
export interface GenerateCodeSnippets {
_: string;
cnst: string;
n: string;
s: string;
getDirectReturnFunction(
params: string[],
options: {
functionReturn: boolean;
lineBreakIndent: string | false;
name: string | null;
t: string;
}
): { left: string; right: string };
getDirectReturnIifeLeft(
params: string[],
returned: string,
options: {
needsArrowReturnParens: boolean | undefined;
needsWrappedFunction: boolean | undefined;
}
): string;
getFunctionIntro(params: string[], options: { isAsync: boolean; name: string | null }): string;
getNonArrowFunctionIntro(
params: string[],
options: { isAsync: boolean; name: string | null }
): string;
// TODO Lukas adjust line-break handling with functions, change in System wrapper
getObject(
fields: [key: string | null, value: string][],
options: { lineBreakIndent: string | false }
): string;
getPropertyAccess(name: string): string;
}
export function getGenerateCodeSnippets({
compact,
generatedCode: { arrowFunctions, constBindings, objectShorthand, reservedNamesAsProps }
}: NormalizedOutputOptions): GenerateCodeSnippets {
const { _, n, s } = compact ? { _: '', n: '', s: '' } : { _: ' ', n: '\n', s: ';' };
const cnst = constBindings ? 'const' : 'var';
const getNonArrowFunctionIntro: GenerateCodeSnippets['getNonArrowFunctionIntro'] = (
params,
{ isAsync, name }
) =>
`${isAsync ? `async ` : ''}function${name ? ` ${name}` : ''}${_}(${params.join(`,${_}`)})${_}`;
const getFunctionIntro: GenerateCodeSnippets['getFunctionIntro'] = arrowFunctions
? (params, { isAsync, name }) => {
const singleParam = params.length === 1;
const asyncString = isAsync ? `async${singleParam ? ' ' : _}` : '';
return `${name ? `${cnst} ${name}${_}=${_}` : ''}${asyncString}${
singleParam ? params[0] : `(${params.join(`,${_}`)})`
}${_}=>${_}`;
}
: getNonArrowFunctionIntro;
const getDirectReturnFunction: GenerateCodeSnippets['getDirectReturnFunction'] = (
params,
{ functionReturn, t, lineBreakIndent, name }
) => ({
left: `${getFunctionIntro(params, {
isAsync: false,
name
})}${
arrowFunctions
? lineBreakIndent
? `${n}${lineBreakIndent}${t}`
: ''
: `{${lineBreakIndent ? `${n}${lineBreakIndent}${t}` : _}${functionReturn ? 'return ' : ''}`
}`,
right: arrowFunctions
? `${name ? ';' : ''}${lineBreakIndent ? `${n}${lineBreakIndent}` : ''}`
: `${s}${lineBreakIndent ? `${n}${lineBreakIndent}` : _}}`
});
const isValidPropName = reservedNamesAsProps
? (name: string): boolean => validPropName.test(name)
: (name: string): boolean => !RESERVED_NAMES[name] && validPropName.test(name);
return {
_,
cnst,
getDirectReturnFunction,
getDirectReturnIifeLeft: (
params,
returned,
{ needsArrowReturnParens, needsWrappedFunction }
) => {
const { left, right } = getDirectReturnFunction(params, {
functionReturn: true,
lineBreakIndent: false,
name: null,
t: ''
});
return `${wrapIfNeeded(
`${left}${wrapIfNeeded(returned, arrowFunctions && needsArrowReturnParens)}${right}`,
arrowFunctions || needsWrappedFunction
)}(`;
},
getFunctionIntro,
getNonArrowFunctionIntro,
getObject(fields, { lineBreakIndent }) {
const prefix = lineBreakIndent === false ? _ : `${n}${lineBreakIndent}`;
return `{${fields
.map(([key, value]) => {
if (key === null) return `${prefix}${value}`;
const needsQuotes = !isValidPropName(key);
return key === value && objectShorthand && !needsQuotes
? prefix + key
: `${prefix}${needsQuotes ? `'${key}'` : key}:${_}${value}`;
})
.join(`,`)}${fields.length === 0 ? '' : lineBreakIndent === false ? _ : n}}`;
},
getPropertyAccess: (name: string): string =>
isValidPropName(name) ? `.${name}` : `[${JSON.stringify(name)}]`,
n,
s
};
}
const wrapIfNeeded = (code: string, needsParens: boolean | undefined): string =>
needsParens ? `(${code})` : code;
const validPropName = /^(?!\d)[\w$]+$/;