-
-
Notifications
You must be signed in to change notification settings - Fork 188
/
createRenderFunction.ts
129 lines (118 loc) · 4.2 KB
/
createRenderFunction.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
129
import MagicString from 'magic-string';
import { Node } from 'estree-walker';
import { ComponentEvents } from './nodes/ComponentEvents';
import { InstanceScriptProcessResult } from './processInstanceScriptContent';
import { surroundWithIgnoreComments } from '../utils/ignore';
export interface CreateRenderFunctionPara extends InstanceScriptProcessResult {
str: MagicString;
scriptTag: Node;
scriptDestination: number;
slots: Map<string, Map<string, string>>;
events: ComponentEvents;
isTsFile: boolean;
uses$$SlotsInterface: boolean;
mode?: 'ts' | 'tsx' | 'dts';
}
export function createRenderFunction({
str,
scriptTag,
scriptDestination,
slots,
events,
exportedNames,
isTsFile,
uses$$props,
uses$$restProps,
uses$$slots,
uses$$SlotsInterface,
generics,
mode
}: CreateRenderFunctionPara) {
const useNewTransformation = mode === 'ts';
const htmlx = str.original;
let propsDecl = '';
if (uses$$props) {
propsDecl += ' let $$props = __sveltets_1_allPropsType();';
}
if (uses$$restProps) {
propsDecl += ' let $$restProps = __sveltets_1_restPropsType();';
}
if (uses$$slots) {
propsDecl +=
' let $$slots = __sveltets_1_slotsType({' +
Array.from(slots.keys())
.map((name) => `'${name}': ''`)
.join(', ') +
'});';
}
const slotsDeclaration =
slots.size > 0 && mode !== 'dts'
? '\n' +
surroundWithIgnoreComments(
useNewTransformation
? ';const __sveltets_createSlot = __sveltets_2_createCreateSlot' +
(uses$$SlotsInterface ? '<$$Slots>' : '') +
'();'
: ';const __sveltets_ensureSlot = __sveltets_1_createEnsureSlot' +
(uses$$SlotsInterface ? '<$$Slots>' : '') +
'();'
)
: '';
if (scriptTag) {
//I couldn't get magicstring to let me put the script before the <> we prepend during conversion of the template to jsx, so we just close it instead
const scriptTagEnd = htmlx.lastIndexOf('>', scriptTag.content.start) + 1;
str.overwrite(scriptTag.start, scriptTag.start + 1, useNewTransformation ? ';' : '</>;');
str.overwrite(
scriptTag.start + 1,
scriptTagEnd,
`function render${generics.toDefinitionString(true)}() {${propsDecl}\n`
);
const scriptEndTagStart = htmlx.lastIndexOf('<', scriptTag.end - 1);
// wrap template with callback
str.overwrite(
scriptEndTagStart,
scriptTag.end,
useNewTransformation
? `${slotsDeclaration};\nasync () => {`
: `${slotsDeclaration};\n() => (<>`,
{
contentOnly: true
}
);
} else {
str.prependRight(
scriptDestination,
`${useNewTransformation ? '' : '</>'};function render${generics.toDefinitionString(
true
)}() {` +
`${propsDecl}${slotsDeclaration}\n${useNewTransformation ? 'async () => {' : '<>'}`
);
}
const slotsAsDef = uses$$SlotsInterface
? '{} as unknown as $$Slots'
: '{' +
Array.from(slots.entries())
.map(([name, attrs]) => {
const attrsAsString = Array.from(attrs.entries())
.map(([exportName, expr]) =>
exportName.startsWith('__spread__')
? `...${expr}`
: `${exportName}:${expr}`
)
.join(', ');
return `'${name}': {${attrsAsString}}`;
})
.join(', ') +
'}';
const returnString =
`\nreturn { props: ${exportedNames.createPropsStr(isTsFile)}` +
`, slots: ${slotsAsDef}` +
`, events: ${events.toDefString()} }}`;
// wrap template with callback
if (useNewTransformation) {
str.append('};');
} else if (scriptTag) {
str.append(');');
}
str.append(returnString);
}