transone-cli 0.6.3 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +20 -3
- package/README.zh-CN.md +31 -0
- package/dist/app/analyze.d.ts +2 -1
- package/dist/app/components.d.ts +4 -0
- package/dist/app/types.d.ts +3 -0
- package/dist/{build-mp-vk5ap2cw.js → build-mp-y5pwahsy.js} +824 -271
- package/dist/build-mp-y5pwahsy.js.map +24 -0
- package/dist/build.d.ts +3 -1
- package/dist/bundle-inputs.d.ts +6 -0
- package/dist/cli.d.ts +4 -2
- package/dist/cli.js +49 -16
- package/dist/cli.js.map +3 -3
- package/dist/components/discovery.d.ts +5 -0
- package/dist/components/index.d.ts +4 -0
- package/dist/components/report.d.ts +48 -0
- package/dist/components/resolution.d.ts +7 -0
- package/dist/components/types.d.ts +56 -0
- package/dist/components/web.d.ts +11 -0
- package/dist/config-inputs.d.ts +4 -0
- package/dist/create.d.ts +4 -4
- package/dist/document-styles.d.ts +7 -0
- package/dist/index-2g3e5sjt.js +3388 -0
- package/dist/index-2g3e5sjt.js.map +32 -0
- package/dist/index-d51tp4y9.js +1402 -0
- package/dist/index-d51tp4y9.js.map +11 -0
- package/dist/index-j4h0wd27.js +489 -0
- package/dist/index-j4h0wd27.js.map +14 -0
- package/dist/index-xgn9fbc6.js +298 -0
- package/dist/index-xgn9fbc6.js.map +13 -0
- package/dist/index.d.ts +5 -2
- package/dist/index.js +12 -4
- package/dist/index.js.map +2 -2
- package/dist/mp/inheritance.d.ts +17 -0
- package/dist/mp/inline.d.ts +22 -0
- package/dist/mp/methods.d.ts +1 -0
- package/dist/mp/source.d.ts +11 -0
- package/dist/mp/types.d.ts +8 -0
- package/dist/output-transaction.d.ts +19 -0
- package/dist/{project-ybacfze8.js → project-6tft5e77.js} +38 -6
- package/dist/{project-ybacfze8.js.map → project-6tft5e77.js.map} +3 -3
- package/dist/project.d.ts +2 -1
- package/dist/safe-path.d.ts +1 -0
- package/dist/scaffold.d.ts +6 -0
- package/dist/target/types.d.ts +7 -6
- package/dist/target/web-target.d.ts +1 -0
- package/dist/types.d.ts +13 -1
- package/dist/web-bundle.d.ts +17 -0
- package/dist/web-styles.d.ts +9 -0
- package/package.json +2 -2
- package/dist/build-mp-vk5ap2cw.js.map +0 -22
- package/dist/index-8k9x2k6m.js +0 -2288
- package/dist/index-8k9x2k6m.js.map +0 -27
- package/dist/index-k1qfvp0y.js +0 -19
- package/dist/index-k1qfvp0y.js.map +0 -10
- package/dist/index-yb2wsc7f.js +0 -7
- package/dist/index-yb2wsc7f.js.map +0 -9
|
@@ -1,16 +1,28 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
buildInputPaths,
|
|
4
|
+
buildOutputPath,
|
|
5
|
+
loadTypescript,
|
|
6
|
+
withBuildOutput
|
|
7
|
+
} from "./index-xgn9fbc6.js";
|
|
8
|
+
import {
|
|
9
|
+
createComponentIndex
|
|
10
|
+
} from "./index-j4h0wd27.js";
|
|
6
11
|
|
|
7
12
|
// src/mp/build-mp.ts
|
|
8
|
-
import { cp, mkdir, readdir,
|
|
9
|
-
import { existsSync as
|
|
13
|
+
import { cp, mkdir, readdir, writeFile } from "fs/promises";
|
|
14
|
+
import { existsSync as existsSync3 } from "fs";
|
|
10
15
|
import { fileURLToPath } from "url";
|
|
11
|
-
import { basename, dirname as
|
|
16
|
+
import { basename, dirname as dirname4, join as join4, relative, resolve as resolve3 } from "path";
|
|
12
17
|
|
|
13
18
|
// src/mp/analyze.ts
|
|
19
|
+
import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
|
|
20
|
+
import { dirname as dirname2, join as join2, resolve as resolve2 } from "path";
|
|
21
|
+
|
|
22
|
+
// src/mp/inheritance.ts
|
|
23
|
+
import { createHash } from "crypto";
|
|
24
|
+
|
|
25
|
+
// src/mp/source.ts
|
|
14
26
|
import { existsSync, readFileSync } from "fs";
|
|
15
27
|
import { dirname, join, resolve } from "path";
|
|
16
28
|
|
|
@@ -27,6 +39,217 @@ function mpError(file, message) {
|
|
|
27
39
|
return new MpCompileError(file, message);
|
|
28
40
|
}
|
|
29
41
|
|
|
42
|
+
// src/mp/source.ts
|
|
43
|
+
function runtimeOwner(context, reference) {
|
|
44
|
+
if (!reference.source.isDeclarationFile)
|
|
45
|
+
return { ...reference, reference };
|
|
46
|
+
const cache = context.packageSources ??= new Map;
|
|
47
|
+
const cached = cache.get(reference.id);
|
|
48
|
+
if (cached)
|
|
49
|
+
return cached;
|
|
50
|
+
let directory = dirname(reference.filePath);
|
|
51
|
+
let entry;
|
|
52
|
+
for (;; ) {
|
|
53
|
+
const manifest = join(directory, "package.json");
|
|
54
|
+
if (existsSync(manifest)) {
|
|
55
|
+
const pkg = JSON.parse(readFileSync(manifest, "utf8"));
|
|
56
|
+
if (typeof pkg.source !== "string" || !pkg.source)
|
|
57
|
+
throw mpError(reference.filePath, "\u58F0\u660E\u7EC4\u4EF6\u6240\u5728\u5305\u7F3A\u5C11 source \u5B57\u6BB5\uFF1A\u5C0F\u7A0B\u5E8F\u9700\u8981\u53EF\u7F16\u8BD1\u7684 TypeScript \u6E90\u7801");
|
|
58
|
+
const base = resolve(directory, pkg.source);
|
|
59
|
+
entry = [base, `${base}.ts`, `${base}.tsx`].find(existsSync);
|
|
60
|
+
if (!entry)
|
|
61
|
+
throw mpError(reference.filePath, `\u5305 source \u6307\u5411\u7684\u6587\u4EF6\u4E0D\u5B58\u5728: ${pkg.source}`);
|
|
62
|
+
break;
|
|
63
|
+
}
|
|
64
|
+
const parent = dirname(directory);
|
|
65
|
+
if (parent === directory)
|
|
66
|
+
throw mpError(reference.filePath, "\u65E0\u6CD5\u5B9A\u4F4D\u58F0\u660E\u7EC4\u4EF6\u7684 package.json/source");
|
|
67
|
+
directory = parent;
|
|
68
|
+
}
|
|
69
|
+
const owner = {
|
|
70
|
+
...loadSourceExport(context, entry, [reference.exportName, reference.className].filter((name) => !!name)),
|
|
71
|
+
reference
|
|
72
|
+
};
|
|
73
|
+
cache.set(reference.id, owner);
|
|
74
|
+
return owner;
|
|
75
|
+
}
|
|
76
|
+
function loadSourceExport(context, entry, names) {
|
|
77
|
+
const program = sourceProgram(context, entry);
|
|
78
|
+
const checker = program.getTypeChecker();
|
|
79
|
+
const source = program.getSourceFile(entry);
|
|
80
|
+
const module = checker.getSymbolAtLocation(source);
|
|
81
|
+
const exports = module ? checker.getExportsOfModule(module) : [];
|
|
82
|
+
const exported = names.map((name) => exports.find((symbol2) => symbol2.name === name)).find(Boolean);
|
|
83
|
+
const symbol = exported && unalias(context, checker, exported);
|
|
84
|
+
const declaration = symbol?.valueDeclaration ?? symbol?.declarations?.find(context.ts.isClassDeclaration);
|
|
85
|
+
if (!declaration || !context.ts.isClassDeclaration(declaration))
|
|
86
|
+
throw mpError(entry, `source \u4E2D\u627E\u4E0D\u5230\u7EC4\u4EF6\u7C7B ${names.join(" / ")}`);
|
|
87
|
+
const owner = {
|
|
88
|
+
filePath: declaration.getSourceFile().fileName,
|
|
89
|
+
source: declaration.getSourceFile(),
|
|
90
|
+
declaration,
|
|
91
|
+
className: declaration.name?.text ?? names[0]
|
|
92
|
+
};
|
|
93
|
+
(context.packageComponentSources ??= new Set).add(owner.source);
|
|
94
|
+
return owner;
|
|
95
|
+
}
|
|
96
|
+
function sourceProgram(context, entry) {
|
|
97
|
+
const programs = context.sourcePrograms ??= new Map;
|
|
98
|
+
const cached = programs.get(entry);
|
|
99
|
+
if (cached)
|
|
100
|
+
return cached;
|
|
101
|
+
const { ts } = context;
|
|
102
|
+
const configPath = ts.findConfigFile(context.root, ts.sys.fileExists);
|
|
103
|
+
const config = configPath && ts.readConfigFile(configPath, ts.sys.readFile);
|
|
104
|
+
const options = configPath && config && !config.error ? ts.parseJsonConfigFileContent(config.config, ts.sys, dirname(configPath)).options : {
|
|
105
|
+
target: ts.ScriptTarget.ESNext,
|
|
106
|
+
module: ts.ModuleKind.ESNext,
|
|
107
|
+
moduleResolution: ts.ModuleResolutionKind.Bundler
|
|
108
|
+
};
|
|
109
|
+
const program = ts.createProgram([entry], { ...options, noEmit: true });
|
|
110
|
+
program.getTypeChecker();
|
|
111
|
+
for (const source of program.getSourceFiles()) {
|
|
112
|
+
if (source.isDeclarationFile)
|
|
113
|
+
continue;
|
|
114
|
+
programs.set(source.fileName, program);
|
|
115
|
+
context.files.set(source.fileName, source);
|
|
116
|
+
}
|
|
117
|
+
programs.set(entry, program);
|
|
118
|
+
return program;
|
|
119
|
+
}
|
|
120
|
+
function sourceSymbolAt(context, node, source = node.getSourceFile()) {
|
|
121
|
+
const indexed = context.index?.symbolAt(node, source);
|
|
122
|
+
if (indexed)
|
|
123
|
+
return indexed;
|
|
124
|
+
const program = context.sourcePrograms?.get(source.fileName);
|
|
125
|
+
if (!program)
|
|
126
|
+
return;
|
|
127
|
+
const { ts } = context;
|
|
128
|
+
const checker = program.getTypeChecker();
|
|
129
|
+
const original = ts.getOriginalNode(node);
|
|
130
|
+
let symbol = ts.isIdentifier(original) && ts.isShorthandPropertyAssignment(original.parent) ? checker.getShorthandAssignmentValueSymbol(original.parent) : checker.getSymbolAtLocation(original);
|
|
131
|
+
if (!symbol && ts.isElementAccessExpression(original) && (ts.isStringLiteralLike(original.argumentExpression) || ts.isNumericLiteral(original.argumentExpression))) {
|
|
132
|
+
symbol = checker.getPropertyOfType(checker.getTypeAtLocation(original.expression), original.argumentExpression.text);
|
|
133
|
+
}
|
|
134
|
+
return symbol && unalias(context, checker, symbol);
|
|
135
|
+
}
|
|
136
|
+
function unalias(context, checker, symbol) {
|
|
137
|
+
const seen = new Set;
|
|
138
|
+
while (symbol.flags & context.ts.SymbolFlags.Alias && !seen.has(symbol)) {
|
|
139
|
+
seen.add(symbol);
|
|
140
|
+
symbol = checker.getAliasedSymbol(symbol);
|
|
141
|
+
}
|
|
142
|
+
return symbol;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// src/mp/inheritance.ts
|
|
146
|
+
function reference(context, source) {
|
|
147
|
+
return source.reference ?? context.index?.findClass(source.filePath, source.className);
|
|
148
|
+
}
|
|
149
|
+
function selected(context, ref) {
|
|
150
|
+
const implementation = context.index.select(ref);
|
|
151
|
+
return { ...runtimeOwner(context, implementation), logical: ref };
|
|
152
|
+
}
|
|
153
|
+
function ownedMethods(context, source) {
|
|
154
|
+
const ref = reference(context, source);
|
|
155
|
+
const effectiveOwners = new Set(ref && context.index ? context.index.members(ref).filter((member) => context.ts.isMethodDeclaration(member.declaration)).map((member) => member.owner.id) : []);
|
|
156
|
+
const owners = ref && context.index ? context.index.hierarchy(ref).filter((owner) => !owner.source.isDeclarationFile || effectiveOwners.has(owner.id)).map((owner) => runtimeOwner(context, owner)) : [source];
|
|
157
|
+
const effective = new Map;
|
|
158
|
+
for (const owner of owners) {
|
|
159
|
+
for (const declaration of owner.declaration.members) {
|
|
160
|
+
if (!declaration.name)
|
|
161
|
+
continue;
|
|
162
|
+
const isStatic = context.ts.canHaveModifiers(declaration) && context.ts.getModifiers(declaration)?.some((item) => item.kind === context.ts.SyntaxKind.StaticKeyword);
|
|
163
|
+
const name = context.ts.isIdentifier(declaration.name) || context.ts.isStringLiteralLike(declaration.name) ? declaration.name.text : declaration.name.getText(owner.source);
|
|
164
|
+
effective.set(`${isStatic ? "static:" : ""}${name}`, {
|
|
165
|
+
owner,
|
|
166
|
+
declaration
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
const members = [...effective.values()];
|
|
171
|
+
return members.filter((item) => context.ts.isMethodDeclaration(item.declaration) && !item.declaration.modifiers?.some((m) => m.kind === context.ts.SyntaxKind.StaticKeyword)).map((item) => ({ owner: item.owner, declaration: item.declaration }));
|
|
172
|
+
}
|
|
173
|
+
function ownedMethod(context, source, name) {
|
|
174
|
+
return ownedMethods(context, source).find((item) => item.declaration.name.getText(item.owner.source) === name);
|
|
175
|
+
}
|
|
176
|
+
function parentSource(context, source) {
|
|
177
|
+
const ref = reference(context, source);
|
|
178
|
+
return ref && context.index?.metadata(ref).parent;
|
|
179
|
+
}
|
|
180
|
+
function stableTag(context, source) {
|
|
181
|
+
const ref = source.logical ?? reference(context, source);
|
|
182
|
+
const name = ref?.className ?? source.className;
|
|
183
|
+
const normalize = (value) => value.replace(/([a-z0-9])([A-Z])/g, "$1-$2").replace(/[^A-Za-z0-9-]/g, "").toLowerCase();
|
|
184
|
+
const tag = normalize(name);
|
|
185
|
+
if (!tag)
|
|
186
|
+
throw new Error(`\u65E0\u6CD5\u4ECE\u7C7B\u540D "${name}" \u751F\u6210\u7EC4\u4EF6\u6807\u7B7E\u540D`);
|
|
187
|
+
if (!ref || !context.index)
|
|
188
|
+
return tag;
|
|
189
|
+
const metadata = context.index.metadata(ref);
|
|
190
|
+
const explicitImplementation = metadata.platforms.length > 0;
|
|
191
|
+
const collides = context.index.classes.some((other) => {
|
|
192
|
+
if (other.id === ref.id || !context.index.isComponent(other))
|
|
193
|
+
return false;
|
|
194
|
+
const otherMetadata = context.index.metadata(other);
|
|
195
|
+
if (!explicitImplementation && otherMetadata.platforms.length > 0)
|
|
196
|
+
return false;
|
|
197
|
+
return normalize(other.className) === tag;
|
|
198
|
+
});
|
|
199
|
+
return collides ? `${tag}-${createHash("sha256").update(ref.id.replace(context.root, "")).digest("hex").slice(0, 8)}` : tag;
|
|
200
|
+
}
|
|
201
|
+
function moduleConstants(context, source) {
|
|
202
|
+
const api = context.ts;
|
|
203
|
+
const constants = new Map;
|
|
204
|
+
const expand = (expression, seen = new Set) => {
|
|
205
|
+
if (!context.index)
|
|
206
|
+
return expression;
|
|
207
|
+
const result = api.transform(expression, [
|
|
208
|
+
(transformContext) => (root) => {
|
|
209
|
+
const visit = (node) => {
|
|
210
|
+
if (api.isShorthandPropertyAssignment(node)) {
|
|
211
|
+
return api.factory.createPropertyAssignment(node.name.text, visit(node.name));
|
|
212
|
+
}
|
|
213
|
+
const keyOnly = api.isIdentifier(node) && node.parent && (api.isPropertyAssignment(node.parent) && node.parent.name === node || api.isPropertyAccessExpression(node.parent) && node.parent.name === node);
|
|
214
|
+
if (!keyOnly && (api.isIdentifier(node) || api.isPropertyAccessExpression(node))) {
|
|
215
|
+
const declaration = sourceSymbolAt(context, node)?.valueDeclaration;
|
|
216
|
+
if (declaration && api.isVariableDeclaration(declaration) && declaration.initializer && !seen.has(declaration) && api.isVariableDeclarationList(declaration.parent) && declaration.parent.flags & api.NodeFlags.Const) {
|
|
217
|
+
return expand(declaration.initializer, new Set([...seen, declaration]));
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
return api.visitEachChild(node, visit, transformContext);
|
|
221
|
+
};
|
|
222
|
+
return api.visitNode(root, visit);
|
|
223
|
+
}
|
|
224
|
+
]);
|
|
225
|
+
const value = result.transformed[0];
|
|
226
|
+
result.dispose();
|
|
227
|
+
return value;
|
|
228
|
+
};
|
|
229
|
+
for (const statement of source.source.statements) {
|
|
230
|
+
if (api.isVariableStatement(statement) && statement.declarationList.flags & api.NodeFlags.Const) {
|
|
231
|
+
for (const declaration of statement.declarationList.declarations) {
|
|
232
|
+
if (api.isIdentifier(declaration.name) && declaration.initializer)
|
|
233
|
+
constants.set(declaration.name.text, expand(declaration.initializer));
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
if (context.index && api.isImportDeclaration(statement)) {
|
|
237
|
+
const clause = statement.importClause;
|
|
238
|
+
const bindings = clause?.namedBindings;
|
|
239
|
+
const names = [
|
|
240
|
+
...clause?.name ? [clause.name] : [],
|
|
241
|
+
...bindings && api.isNamedImports(bindings) ? bindings.elements.map((item) => item.name) : []
|
|
242
|
+
];
|
|
243
|
+
for (const name of names) {
|
|
244
|
+
const declaration = sourceSymbolAt(context, name)?.valueDeclaration;
|
|
245
|
+
if (declaration && api.isVariableDeclaration(declaration) && declaration.initializer)
|
|
246
|
+
constants.set(name.text, expand(declaration.initializer));
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
return constants;
|
|
251
|
+
}
|
|
252
|
+
|
|
30
253
|
// src/mp/fold.ts
|
|
31
254
|
function foldExpression(ts, node, consts, seen = new Set) {
|
|
32
255
|
node = unwrapParentheses(ts, node);
|
|
@@ -104,6 +327,13 @@ function foldExpression(ts, node, consts, seen = new Set) {
|
|
|
104
327
|
if (ts.isObjectLiteralExpression(node)) {
|
|
105
328
|
const result = {};
|
|
106
329
|
for (const property of node.properties) {
|
|
330
|
+
if (ts.isSpreadAssignment(property)) {
|
|
331
|
+
const spread = foldExpression(ts, property.expression, consts, seen);
|
|
332
|
+
if (!spread || typeof spread !== "object" || Array.isArray(spread))
|
|
333
|
+
return;
|
|
334
|
+
Object.assign(result, spread);
|
|
335
|
+
continue;
|
|
336
|
+
}
|
|
107
337
|
if (ts.isPropertyAssignment(property)) {
|
|
108
338
|
const key = propertyNameText(ts, property.name);
|
|
109
339
|
const value = foldExpression(ts, property.initializer, consts, seen);
|
|
@@ -238,10 +468,10 @@ function readSource(context, filePath) {
|
|
|
238
468
|
if (cached) {
|
|
239
469
|
return cached;
|
|
240
470
|
}
|
|
241
|
-
if (!
|
|
471
|
+
if (!existsSync2(filePath)) {
|
|
242
472
|
throw mpError(filePath, "\u6E90\u6587\u4EF6\u4E0D\u5B58\u5728");
|
|
243
473
|
}
|
|
244
|
-
const text =
|
|
474
|
+
const text = readFileSync2(filePath, "utf8");
|
|
245
475
|
const source = context.ts.createSourceFile(filePath, text, context.ts.ScriptTarget.Latest, true, context.ts.ScriptKind.TS);
|
|
246
476
|
context.files.set(filePath, source);
|
|
247
477
|
return source;
|
|
@@ -280,12 +510,8 @@ function findRootClass(context, filePath) {
|
|
|
280
510
|
declaration: statement,
|
|
281
511
|
className: name
|
|
282
512
|
})) {
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
source,
|
|
286
|
-
declaration: statement,
|
|
287
|
-
className: name
|
|
288
|
-
};
|
|
513
|
+
const ref = context.index?.findClass(filePath, name);
|
|
514
|
+
return ref ? selected(context, ref) : { filePath, source, declaration: statement, className: name };
|
|
289
515
|
}
|
|
290
516
|
}
|
|
291
517
|
for (const [name, declaration] of localClasses) {
|
|
@@ -295,13 +521,17 @@ function findRootClass(context, filePath) {
|
|
|
295
521
|
declaration,
|
|
296
522
|
className: name
|
|
297
523
|
})) {
|
|
298
|
-
|
|
524
|
+
const ref = context.index?.findClass(filePath, name);
|
|
525
|
+
return ref ? selected(context, ref) : { filePath, source, declaration, className: name };
|
|
299
526
|
}
|
|
300
527
|
}
|
|
301
528
|
throw mpError(filePath, "\u672A\u627E\u5230\u53EF\u7F16\u8BD1\u7684\u9875\u9762\u7EC4\u4EF6\uFF1A\u9700\u8981 createApp({ root }) \u6216\u5BFC\u51FA\u7684 Component \u5B50\u7C7B");
|
|
302
529
|
}
|
|
303
530
|
function resolveClassReference(context, from, expr) {
|
|
304
531
|
const { ts } = context;
|
|
532
|
+
const indexed = context.index?.resolve(expr, from.source);
|
|
533
|
+
if (indexed)
|
|
534
|
+
return selected(context, indexed);
|
|
305
535
|
expr = unwrapParentheses(ts, expr);
|
|
306
536
|
if (ts.isClassExpression(expr) || ts.isClassDeclaration(expr)) {
|
|
307
537
|
const name2 = expr.name?.text;
|
|
@@ -337,6 +567,9 @@ function resolveClassReference(context, from, expr) {
|
|
|
337
567
|
}
|
|
338
568
|
function isComponentSubclass(context, classSource) {
|
|
339
569
|
const { ts } = context;
|
|
570
|
+
const indexed = reference(context, classSource);
|
|
571
|
+
if (indexed && context.index.isComponent(indexed))
|
|
572
|
+
return true;
|
|
340
573
|
const heritage = classSource.declaration.heritageClauses ?? [];
|
|
341
574
|
const imports = collectImports(ts, classSource.source);
|
|
342
575
|
for (const clause of heritage) {
|
|
@@ -396,6 +629,8 @@ function resolvePackageClass(context, from, localName, binding) {
|
|
|
396
629
|
if (!targetPath) {
|
|
397
630
|
throw mpError(from.filePath, `\u5305 "${binding.specifier}" \u7684 "source" \u6307\u5411\u7684\u6587\u4EF6\u4E0D\u5B58\u5728: ${sourceField}`);
|
|
398
631
|
}
|
|
632
|
+
if (context.index)
|
|
633
|
+
return loadSourceExport(context, targetPath, [binding.importedName]);
|
|
399
634
|
const source = readSource(context, targetPath);
|
|
400
635
|
const importedName = binding.importedName;
|
|
401
636
|
const found = findExportedClass(context, source, importedName, new Set);
|
|
@@ -411,19 +646,22 @@ function resolvePackageClass(context, from, localName, binding) {
|
|
|
411
646
|
}
|
|
412
647
|
function findPackageInfo(fromFile, specifier) {
|
|
413
648
|
const segments = specifier.split("/");
|
|
414
|
-
const packageJsonRelative =
|
|
415
|
-
let current =
|
|
649
|
+
const packageJsonRelative = join2("node_modules", ...segments, "package.json");
|
|
650
|
+
let current = dirname2(fromFile);
|
|
416
651
|
for (;; ) {
|
|
417
|
-
const candidate =
|
|
418
|
-
if (
|
|
652
|
+
const candidate = join2(current, packageJsonRelative);
|
|
653
|
+
if (existsSync2(candidate)) {
|
|
419
654
|
try {
|
|
420
|
-
const json = JSON.parse(
|
|
421
|
-
return {
|
|
655
|
+
const json = JSON.parse(readFileSync2(candidate, "utf8"));
|
|
656
|
+
return {
|
|
657
|
+
dir: join2(current, "node_modules", ...segments),
|
|
658
|
+
source: json.source
|
|
659
|
+
};
|
|
422
660
|
} catch {
|
|
423
661
|
return;
|
|
424
662
|
}
|
|
425
663
|
}
|
|
426
|
-
const parent =
|
|
664
|
+
const parent = dirname2(current);
|
|
427
665
|
if (parent === current) {
|
|
428
666
|
return;
|
|
429
667
|
}
|
|
@@ -431,9 +669,9 @@ function findPackageInfo(fromFile, specifier) {
|
|
|
431
669
|
}
|
|
432
670
|
}
|
|
433
671
|
function resolvePackageSource(packageDir, sourceField) {
|
|
434
|
-
const base =
|
|
672
|
+
const base = resolve2(packageDir, sourceField);
|
|
435
673
|
const candidates = [base, `${base}.ts`, `${base}.tsx`];
|
|
436
|
-
return candidates.find((candidate) =>
|
|
674
|
+
return candidates.find((candidate) => existsSync2(candidate));
|
|
437
675
|
}
|
|
438
676
|
function findExportedClass(context, source, name, seen) {
|
|
439
677
|
const { ts } = context;
|
|
@@ -544,15 +782,15 @@ function collectImports(ts, source) {
|
|
|
544
782
|
return imports;
|
|
545
783
|
}
|
|
546
784
|
function resolveImportPath(fromFile, specifier) {
|
|
547
|
-
const base =
|
|
785
|
+
const base = resolve2(dirname2(fromFile), specifier);
|
|
548
786
|
const candidates = [
|
|
549
787
|
base,
|
|
550
788
|
`${base}.ts`,
|
|
551
789
|
`${base}.tsx`,
|
|
552
|
-
|
|
553
|
-
|
|
790
|
+
join2(base, "index.ts"),
|
|
791
|
+
join2(base, "index.tsx")
|
|
554
792
|
];
|
|
555
|
-
return candidates.find((candidate) =>
|
|
793
|
+
return candidates.find((candidate) => existsSync2(candidate));
|
|
556
794
|
}
|
|
557
795
|
function isExported(ts, declaration) {
|
|
558
796
|
return (declaration.modifiers ?? []).some((modifier) => modifier.kind === ts.SyntaxKind.ExportKeyword);
|
|
@@ -941,7 +1179,10 @@ function eventNameFromProp(key) {
|
|
|
941
1179
|
}
|
|
942
1180
|
function compileTemplate(context, classSource, _kind, hoverSelectors = new Set) {
|
|
943
1181
|
const { ts } = context;
|
|
944
|
-
const
|
|
1182
|
+
const owned = ownedMethod(context, classSource, "render");
|
|
1183
|
+
const renderMethod = owned?.declaration;
|
|
1184
|
+
if (owned)
|
|
1185
|
+
classSource = owned.owner;
|
|
945
1186
|
if (!renderMethod) {
|
|
946
1187
|
throw mpError(classSource.filePath, `\u7EC4\u4EF6 ${classSource.className} \u7F3A\u5C11 render() \u65B9\u6CD5`);
|
|
947
1188
|
}
|
|
@@ -1218,7 +1459,9 @@ function compileConditional(context, classSource, node, env, depth) {
|
|
|
1218
1459
|
const condition = toBinding(bindingContext(context, classSource, env), node.condition);
|
|
1219
1460
|
const whenTrue = buildNodeLines(context, classSource, node.whenTrue, env, depth + 1);
|
|
1220
1461
|
const whenFalse = buildNodeLines(context, classSource, node.whenFalse, env, depth + 1);
|
|
1221
|
-
const lines = [
|
|
1462
|
+
const lines = [
|
|
1463
|
+
indent(env.indent) + `<block ${context.dialect.directivePrefix}if="{{${condition}}}">`
|
|
1464
|
+
];
|
|
1222
1465
|
lines.push(...whenTrue.map((line) => indent(env.indent + 1) + line));
|
|
1223
1466
|
lines.push(indent(env.indent) + "</block>");
|
|
1224
1467
|
if (whenFalse.length > 0) {
|
|
@@ -1360,7 +1603,7 @@ function compileComponent(context, classSource, classExpr, propsExpr, childrenEx
|
|
|
1360
1603
|
if (!isComponentSubclass(context, target)) {
|
|
1361
1604
|
throw mpError(classSource.filePath, `createComponent \u53EA\u63A5\u53D7 Component \u5B50\u7C7B: ${target.className}`);
|
|
1362
1605
|
}
|
|
1363
|
-
const tag =
|
|
1606
|
+
const tag = stableTag(context, target);
|
|
1364
1607
|
env.builder.usedComponents.set(tag, target);
|
|
1365
1608
|
const attrs = [...env.extraAttrs];
|
|
1366
1609
|
const callSiteProps = {};
|
|
@@ -1480,7 +1723,12 @@ function compileEmitterHandler(context, _classSource, handlerExpr) {
|
|
|
1480
1723
|
const { ts } = context;
|
|
1481
1724
|
handlerExpr = unwrapParentheses(ts, handlerExpr);
|
|
1482
1725
|
if (ts.isPropertyAccessExpression(handlerExpr) && isThisExpression(ts, handlerExpr.expression)) {
|
|
1483
|
-
return {
|
|
1726
|
+
return {
|
|
1727
|
+
event: "pending",
|
|
1728
|
+
method: handlerExpr.name.text,
|
|
1729
|
+
passArgs: true,
|
|
1730
|
+
key: ""
|
|
1731
|
+
};
|
|
1484
1732
|
}
|
|
1485
1733
|
if (!ts.isArrowFunction(handlerExpr)) {
|
|
1486
1734
|
return;
|
|
@@ -1760,22 +2008,7 @@ function objectProperty(ts, object, key) {
|
|
|
1760
2008
|
return;
|
|
1761
2009
|
}
|
|
1762
2010
|
function collectModuleConsts(context, classSource) {
|
|
1763
|
-
|
|
1764
|
-
for (const statement of classSource.source.statements) {
|
|
1765
|
-
if (!context.ts.isVariableStatement(statement)) {
|
|
1766
|
-
continue;
|
|
1767
|
-
}
|
|
1768
|
-
const isConst = statement.declarationList.flags & context.ts.NodeFlags.Const;
|
|
1769
|
-
if (!isConst) {
|
|
1770
|
-
continue;
|
|
1771
|
-
}
|
|
1772
|
-
for (const declaration of statement.declarationList.declarations) {
|
|
1773
|
-
if (context.ts.isIdentifier(declaration.name) && declaration.initializer) {
|
|
1774
|
-
consts.set(declaration.name.text, declaration.initializer);
|
|
1775
|
-
}
|
|
1776
|
-
}
|
|
1777
|
-
}
|
|
1778
|
-
return consts;
|
|
2011
|
+
return moduleConstants(context, classSource);
|
|
1779
2012
|
}
|
|
1780
2013
|
function collectFactoryOrigins(ts, source) {
|
|
1781
2014
|
const origins = new Map;
|
|
@@ -1847,10 +2080,6 @@ function escapeAttr(value) {
|
|
|
1847
2080
|
function indent(level) {
|
|
1848
2081
|
return " ".repeat(level);
|
|
1849
2082
|
}
|
|
1850
|
-
function findMethod(context, classSource, name) {
|
|
1851
|
-
const { ts } = context;
|
|
1852
|
-
return classSource.declaration.members.find((member) => ts.isMethodDeclaration(member) && member.name.getText() === name);
|
|
1853
|
-
}
|
|
1854
2083
|
|
|
1855
2084
|
// src/mp/styles.ts
|
|
1856
2085
|
var UNITLESS_PROPERTIES = new Set([
|
|
@@ -1871,29 +2100,39 @@ var UNITLESS_PROPERTIES = new Set([
|
|
|
1871
2100
|
]);
|
|
1872
2101
|
function compileStyles(context, classSource) {
|
|
1873
2102
|
const { ts } = context;
|
|
1874
|
-
const
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
2103
|
+
const entries = new Map;
|
|
2104
|
+
const collect = (source) => {
|
|
2105
|
+
const owned = ownedMethod(context, source, "initStyles");
|
|
2106
|
+
if (!owned?.declaration.body)
|
|
2107
|
+
return;
|
|
2108
|
+
const owner = owned.owner;
|
|
2109
|
+
const consts = collectModuleConsts2(context, owner);
|
|
2110
|
+
for (const statement of owned.declaration.body.statements) {
|
|
2111
|
+
if (ts.isEmptyStatement(statement))
|
|
2112
|
+
continue;
|
|
2113
|
+
if (!ts.isExpressionStatement(statement))
|
|
2114
|
+
throw mpError(owner.filePath, "initStyles() \u53EA\u652F\u6301 this.styleManager.addStyle(...) \u4E0E super.initStyles() \u8C03\u7528");
|
|
2115
|
+
const expression = statement.expression;
|
|
2116
|
+
if (ts.isCallExpression(expression) && ts.isPropertyAccessExpression(expression.expression) && expression.expression.expression.kind === ts.SyntaxKind.SuperKeyword && expression.expression.name.text === "initStyles" && expression.arguments.length === 0) {
|
|
2117
|
+
const parent = parentSource(context, owner);
|
|
2118
|
+
if (parent)
|
|
2119
|
+
collect(parent);
|
|
2120
|
+
continue;
|
|
2121
|
+
}
|
|
2122
|
+
const entry = addStyleEntry(context, owner, expression, consts);
|
|
2123
|
+
if (entry && ts.isCallExpression(expression)) {
|
|
2124
|
+
const name = expression.arguments[0] && foldExpression(ts, expression.arguments[0], consts);
|
|
2125
|
+
if (typeof name !== "string")
|
|
2126
|
+
throw mpError(owner.filePath, "addStyle \u540D\u79F0\u5FC5\u987B\u80FD\u9759\u6001\u6C42\u503C");
|
|
2127
|
+
entries.set(name, entry);
|
|
2128
|
+
}
|
|
1891
2129
|
}
|
|
1892
|
-
}
|
|
2130
|
+
};
|
|
2131
|
+
collect(classSource);
|
|
1893
2132
|
const local = [];
|
|
1894
2133
|
const global = [];
|
|
1895
2134
|
const hoverSelectors = new Set;
|
|
1896
|
-
for (const entry of entries) {
|
|
2135
|
+
for (const entry of entries.values()) {
|
|
1897
2136
|
const target = entry.selector === "body" ? global : local;
|
|
1898
2137
|
target.push(renderStyle(entry, context.lengthUnit));
|
|
1899
2138
|
if (entry.hover && entry.selector !== "body") {
|
|
@@ -2035,28 +2274,16 @@ function objectProperty2(ts, object, key) {
|
|
|
2035
2274
|
return;
|
|
2036
2275
|
}
|
|
2037
2276
|
function collectModuleConsts2(context, classSource) {
|
|
2038
|
-
|
|
2039
|
-
for (const statement of classSource.source.statements) {
|
|
2040
|
-
if (!context.ts.isVariableStatement(statement)) {
|
|
2041
|
-
continue;
|
|
2042
|
-
}
|
|
2043
|
-
const isConst = statement.declarationList.flags & context.ts.NodeFlags.Const;
|
|
2044
|
-
if (!isConst) {
|
|
2045
|
-
continue;
|
|
2046
|
-
}
|
|
2047
|
-
for (const declaration of statement.declarationList.declarations) {
|
|
2048
|
-
if (context.ts.isIdentifier(declaration.name) && declaration.initializer) {
|
|
2049
|
-
consts.set(declaration.name.text, declaration.initializer);
|
|
2050
|
-
}
|
|
2051
|
-
}
|
|
2052
|
-
}
|
|
2053
|
-
return consts;
|
|
2277
|
+
return moduleConstants(context, classSource);
|
|
2054
2278
|
}
|
|
2055
2279
|
|
|
2056
2280
|
// src/mp/state.ts
|
|
2057
2281
|
function compileState(context, classSource) {
|
|
2058
2282
|
const { ts } = context;
|
|
2059
|
-
const
|
|
2283
|
+
const owned = ownedMethod(context, classSource, "initState");
|
|
2284
|
+
const method = owned?.declaration;
|
|
2285
|
+
if (owned)
|
|
2286
|
+
classSource = owned.owner;
|
|
2060
2287
|
if (!method?.body) {
|
|
2061
2288
|
return "{}";
|
|
2062
2289
|
}
|
|
@@ -2086,29 +2313,435 @@ function compileState(context, classSource) {
|
|
|
2086
2313
|
throw mpError(classSource.filePath, "initState() \u5FC5\u987B\u4EE5 return \u8868\u8FBE\u5F0F\u7ED3\u675F");
|
|
2087
2314
|
}
|
|
2088
2315
|
const allConsts = new Map([...consts, ...locals]);
|
|
2089
|
-
const
|
|
2316
|
+
const replaceSuper = (expression) => {
|
|
2317
|
+
const transformed = ts.transform(expression, [
|
|
2318
|
+
(transformContext) => (node) => {
|
|
2319
|
+
const visit = (current) => {
|
|
2320
|
+
if (ts.isCallExpression(current) && ts.isPropertyAccessExpression(current.expression) && current.expression.expression.kind === ts.SyntaxKind.SuperKeyword && current.expression.name.text === "initState" && current.arguments.length === 0) {
|
|
2321
|
+
const parent = parentSource(context, classSource);
|
|
2322
|
+
const text = parent ? compileState(context, parent) : "{}";
|
|
2323
|
+
return ts.createSourceFile("state.ts", `(${text})`, ts.ScriptTarget.Latest, true).statements.filter(ts.isExpressionStatement)[0].expression;
|
|
2324
|
+
}
|
|
2325
|
+
return ts.visitEachChild(current, visit, transformContext);
|
|
2326
|
+
};
|
|
2327
|
+
return ts.visitNode(node, visit);
|
|
2328
|
+
}
|
|
2329
|
+
]);
|
|
2330
|
+
const result = transformed.transformed[0];
|
|
2331
|
+
transformed.dispose();
|
|
2332
|
+
return result;
|
|
2333
|
+
};
|
|
2334
|
+
for (const [name, value2] of allConsts)
|
|
2335
|
+
allConsts.set(name, replaceSuper(value2));
|
|
2336
|
+
const value = foldExpression(ts, replaceSuper(returnStatement.expression), allConsts);
|
|
2090
2337
|
if (value === undefined) {
|
|
2091
2338
|
throw mpError(classSource.filePath, "initState() \u7684\u7ED3\u679C\u5FC5\u987B\u80FD\u9759\u6001\u6C42\u503C\uFF08\u53EA\u652F\u6301\u5B57\u9762\u91CF\u3001\u6A21\u5757/\u5C40\u90E8\u5E38\u91CF\u4E0E\u7B80\u5355\u8868\u8FBE\u5F0F\uFF09");
|
|
2092
2339
|
}
|
|
2093
2340
|
return JSON.stringify(value, null, 2);
|
|
2094
2341
|
}
|
|
2095
2342
|
function collectModuleConsts3(context, classSource) {
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2343
|
+
return moduleConstants(context, classSource);
|
|
2344
|
+
}
|
|
2345
|
+
|
|
2346
|
+
// src/mp/inline.ts
|
|
2347
|
+
import { dirname as dirname3, join as join3 } from "path";
|
|
2348
|
+
function collectInlineModules(context, classSource) {
|
|
2349
|
+
const { ts } = context;
|
|
2350
|
+
const output = [];
|
|
2351
|
+
const seen = new Set;
|
|
2352
|
+
const stack = new Set;
|
|
2353
|
+
const walk = (source) => {
|
|
2354
|
+
const filePath = source.fileName;
|
|
2355
|
+
if (seen.has(filePath)) {
|
|
2356
|
+
return;
|
|
2357
|
+
}
|
|
2358
|
+
for (const statement of source.statements) {
|
|
2359
|
+
if (!ts.isImportDeclaration(statement)) {
|
|
2360
|
+
continue;
|
|
2361
|
+
}
|
|
2362
|
+
const specifier = statement.moduleSpecifier;
|
|
2363
|
+
if (!ts.isStringLiteral(specifier)) {
|
|
2364
|
+
continue;
|
|
2365
|
+
}
|
|
2366
|
+
const target = resolveRelativeModule(context, filePath, specifier.text);
|
|
2367
|
+
if (!target) {
|
|
2368
|
+
continue;
|
|
2369
|
+
}
|
|
2370
|
+
if (stack.has(target)) {
|
|
2371
|
+
warn(context, `\u6A21\u5757\u5FAA\u73AF\u5F15\u7528\u5DF2\u8DF3\u8FC7: ${target}`);
|
|
2372
|
+
continue;
|
|
2373
|
+
}
|
|
2374
|
+
stack.add(target);
|
|
2375
|
+
walk(readSource(context, target));
|
|
2376
|
+
stack.delete(target);
|
|
2377
|
+
}
|
|
2378
|
+
seen.add(filePath);
|
|
2379
|
+
output.push(compileInlineModule(context, source));
|
|
2380
|
+
};
|
|
2381
|
+
walk(classSource.source);
|
|
2382
|
+
return output;
|
|
2383
|
+
}
|
|
2384
|
+
function resolveRelativeModule(context, fromFile, specifier) {
|
|
2385
|
+
if (!specifier.startsWith("./") && !specifier.startsWith("../")) {
|
|
2386
|
+
return null;
|
|
2387
|
+
}
|
|
2388
|
+
const base = specifier.endsWith(".ts") ? specifier : `${specifier}.ts`;
|
|
2389
|
+
const resolved = join3(dirname3(fromFile), base);
|
|
2390
|
+
if (isComponentFile(context, resolved)) {
|
|
2391
|
+
return null;
|
|
2392
|
+
}
|
|
2393
|
+
return resolved;
|
|
2394
|
+
}
|
|
2395
|
+
function isComponentFile(context, filePath) {
|
|
2396
|
+
const { ts } = context;
|
|
2397
|
+
const source = readSource(context, filePath);
|
|
2398
|
+
for (const statement of source.statements) {
|
|
2399
|
+
if (!ts.isClassDeclaration(statement)) {
|
|
2400
|
+
continue;
|
|
2401
|
+
}
|
|
2402
|
+
const name = statement.name?.text;
|
|
2403
|
+
if (!name) {
|
|
2404
|
+
continue;
|
|
2405
|
+
}
|
|
2406
|
+
const isExported2 = statement.modifiers?.some((m) => m.kind === ts.SyntaxKind.ExportKeyword);
|
|
2407
|
+
if (!isExported2) {
|
|
2099
2408
|
continue;
|
|
2100
2409
|
}
|
|
2101
|
-
const
|
|
2102
|
-
|
|
2410
|
+
const heritage = statement.heritageClauses?.some((clause) => clause.types.some((type) => {
|
|
2411
|
+
const expr = type.expression;
|
|
2412
|
+
if (!ts.isIdentifier(expr)) {
|
|
2413
|
+
return false;
|
|
2414
|
+
}
|
|
2415
|
+
return expr.text === "Component" || expr.text.endsWith("Component");
|
|
2416
|
+
}));
|
|
2417
|
+
if (heritage) {
|
|
2418
|
+
return true;
|
|
2419
|
+
}
|
|
2420
|
+
}
|
|
2421
|
+
return false;
|
|
2422
|
+
}
|
|
2423
|
+
function compileInlineModule(context, source) {
|
|
2424
|
+
const { ts } = context;
|
|
2425
|
+
const kept = [];
|
|
2426
|
+
const requestImports = [];
|
|
2427
|
+
for (const statement of source.statements) {
|
|
2428
|
+
if (ts.isImportDeclaration(statement) && ts.isStringLiteral(statement.moduleSpecifier) && statement.moduleSpecifier.text === "transone/request" && !statement.importClause?.isTypeOnly) {
|
|
2429
|
+
const clause = statement.importClause;
|
|
2430
|
+
if (clause?.name)
|
|
2431
|
+
requestImports.push(`const ${clause.name.text} = getApp().__transoneRequest.default;`);
|
|
2432
|
+
const bindings = clause?.namedBindings;
|
|
2433
|
+
if (bindings && ts.isNamespaceImport(bindings)) {
|
|
2434
|
+
requestImports.push(`const ${bindings.name.text} = getApp().__transoneRequest;`);
|
|
2435
|
+
} else if (bindings && ts.isNamedImports(bindings)) {
|
|
2436
|
+
for (const item of bindings.elements) {
|
|
2437
|
+
if (!item.isTypeOnly)
|
|
2438
|
+
requestImports.push(`const ${item.name.text} = getApp().__transoneRequest[${JSON.stringify(item.propertyName?.text ?? item.name.text)}];`);
|
|
2439
|
+
}
|
|
2440
|
+
}
|
|
2441
|
+
}
|
|
2442
|
+
if (ts.isImportDeclaration(statement) || ts.isExportDeclaration(statement) || ts.isExportAssignment(statement) || ts.isInterfaceDeclaration(statement) || ts.isTypeAliasDeclaration(statement)) {
|
|
2443
|
+
continue;
|
|
2444
|
+
}
|
|
2445
|
+
if (ts.isClassDeclaration(statement) && statement.heritageClauses?.some((clause) => clause.types.some((type) => ts.isIdentifier(type.expression) && (type.expression.text === "Component" || type.expression.text.endsWith("Component")))))
|
|
2103
2446
|
continue;
|
|
2447
|
+
if (ts.isVariableStatement(statement)) {
|
|
2448
|
+
const declarations = statement.declarationList.declarations.filter((declaration) => !(declaration.initializer && ts.isCallExpression(declaration.initializer) && ts.isIdentifier(declaration.initializer.expression) && declaration.initializer.expression.text === "createApp"));
|
|
2449
|
+
if (declarations.length === 0)
|
|
2450
|
+
continue;
|
|
2451
|
+
kept.push(ts.factory.updateVariableStatement(statement, statement.modifiers, ts.factory.updateVariableDeclarationList(statement.declarationList, declarations)));
|
|
2452
|
+
continue;
|
|
2453
|
+
}
|
|
2454
|
+
kept.push(statement);
|
|
2455
|
+
}
|
|
2456
|
+
const printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed });
|
|
2457
|
+
const printed = printer.printList(ts.ListFormat.MultiLine, ts.factory.createNodeArray(kept), source);
|
|
2458
|
+
const transpiled = ts.transpileModule(printed, {
|
|
2459
|
+
compilerOptions: {
|
|
2460
|
+
target: ts.ScriptTarget.ESNext,
|
|
2461
|
+
module: ts.ModuleKind.ES2015
|
|
2462
|
+
},
|
|
2463
|
+
reportDiagnostics: false
|
|
2464
|
+
});
|
|
2465
|
+
return [
|
|
2466
|
+
...requestImports,
|
|
2467
|
+
transpiled.outputText.replace(/^export\s+/gm, "").trim()
|
|
2468
|
+
].join(`
|
|
2469
|
+
`);
|
|
2470
|
+
}
|
|
2471
|
+
|
|
2472
|
+
class MethodModuleLinker {
|
|
2473
|
+
context;
|
|
2474
|
+
names = new Map;
|
|
2475
|
+
entries = new Map;
|
|
2476
|
+
dependencies = new Map;
|
|
2477
|
+
constructor(context) {
|
|
2478
|
+
this.context = context;
|
|
2479
|
+
}
|
|
2480
|
+
modules() {
|
|
2481
|
+
const { ts } = this.context;
|
|
2482
|
+
let size = -1;
|
|
2483
|
+
const linkedSize = () => this.names.size + [...this.entries.values()].reduce((count, entries) => count + entries.size, 0);
|
|
2484
|
+
while (size !== linkedSize()) {
|
|
2485
|
+
size = linkedSize();
|
|
2486
|
+
for (const [source, entries] of this.entries) {
|
|
2487
|
+
const componentModule = this.context.packageComponentSources?.has(source) || this.context.index.classes.some((ref) => ref.source === source && this.context.index.isComponent(ref));
|
|
2488
|
+
for (const statement of source.statements) {
|
|
2489
|
+
if (ts.isImportDeclaration(statement)) {
|
|
2490
|
+
if (!statement.importClause && !componentModule)
|
|
2491
|
+
throw mpError(source.fileName, `\u5C0F\u7A0B\u5E8F helper \u6682\u4E0D\u652F\u6301\u526F\u4F5C\u7528\u5BFC\u5165: ${statement.moduleSpecifier.getText(source)}`);
|
|
2492
|
+
continue;
|
|
2493
|
+
}
|
|
2494
|
+
if (ts.isVariableStatement(statement)) {
|
|
2495
|
+
for (const declaration of statement.declarationList.declarations) {
|
|
2496
|
+
if (componentModule && !this.names.has(declaration) && (!declaration.initializer || !this.referencesLinkedValue(declaration.initializer)))
|
|
2497
|
+
continue;
|
|
2498
|
+
if (!componentModule && !this.names.has(declaration) && (!declaration.initializer || !this.mayInitialize(declaration.initializer)))
|
|
2499
|
+
continue;
|
|
2500
|
+
if (!ts.isIdentifier(declaration.name))
|
|
2501
|
+
throw mpError(source.fileName, "\u5C0F\u7A0B\u5E8F helper \u9876\u5C42\u89E3\u6784\u521D\u59CB\u5316\u6682\u4E0D\u652F\u6301");
|
|
2502
|
+
this.link(declaration);
|
|
2503
|
+
}
|
|
2504
|
+
continue;
|
|
2505
|
+
}
|
|
2506
|
+
if (ts.isClassDeclaration(statement) && !componentModule && !this.names.has(statement) && statement.members.some((member) => ts.isClassStaticBlockDeclaration(member) || ts.isPropertyDeclaration(member) && member.initializer && member.modifiers?.some((modifier) => modifier.kind === ts.SyntaxKind.StaticKeyword))) {
|
|
2507
|
+
throw mpError(source.fileName, `\u5C0F\u7A0B\u5E8F helper \u672A\u5F15\u7528\u7C7B\u7684\u9759\u6001\u521D\u59CB\u5316\u6682\u4E0D\u652F\u6301: ${statement.name?.text ?? "default"}`);
|
|
2508
|
+
}
|
|
2509
|
+
if (ts.isFunctionDeclaration(statement) || ts.isClassDeclaration(statement) || ts.isInterfaceDeclaration(statement) || ts.isTypeAliasDeclaration(statement) || ts.isExportDeclaration(statement))
|
|
2510
|
+
continue;
|
|
2511
|
+
if (componentModule && !this.referencesLinkedValue(statement))
|
|
2512
|
+
continue;
|
|
2513
|
+
if (ts.isExportAssignment(statement) || ts.isEnumDeclaration(statement) || ts.isModuleDeclaration(statement)) {
|
|
2514
|
+
throw mpError(source.fileName, `\u5C0F\u7A0B\u5E8F helper \u4E0D\u652F\u6301\u6B64\u521D\u59CB\u5316\u8BED\u53E5: ${statement.getText(source).slice(0, 80)}`);
|
|
2515
|
+
}
|
|
2516
|
+
entries.set(statement, this.rewrite(statement, source));
|
|
2517
|
+
}
|
|
2518
|
+
}
|
|
2104
2519
|
}
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2520
|
+
const output = [];
|
|
2521
|
+
const visited = new Set;
|
|
2522
|
+
const active = new Set;
|
|
2523
|
+
const emit = (source) => {
|
|
2524
|
+
if (visited.has(source))
|
|
2525
|
+
return;
|
|
2526
|
+
if (active.has(source))
|
|
2527
|
+
throw mpError(source.fileName, "\u5C0F\u7A0B\u5E8F helper \u6A21\u5757\u5B58\u5728\u5FAA\u73AF\u521D\u59CB\u5316\u4F9D\u8D56");
|
|
2528
|
+
active.add(source);
|
|
2529
|
+
for (const dependency of this.orderedDependencies(source))
|
|
2530
|
+
emit(dependency);
|
|
2531
|
+
active.delete(source);
|
|
2532
|
+
visited.add(source);
|
|
2533
|
+
const statements = [...this.entries.get(source)?.entries() ?? []].sort(([a], [b]) => a.pos - b.pos).map(([, node]) => node);
|
|
2534
|
+
const printer = ts.createPrinter();
|
|
2535
|
+
const printed = statements.map((node) => printer.printNode(ts.EmitHint.Unspecified, node, source)).join(`
|
|
2536
|
+
`);
|
|
2537
|
+
const result = ts.transpileModule(printed, {
|
|
2538
|
+
compilerOptions: {
|
|
2539
|
+
target: ts.ScriptTarget.ESNext,
|
|
2540
|
+
module: ts.ModuleKind.ESNext
|
|
2541
|
+
},
|
|
2542
|
+
reportDiagnostics: true
|
|
2543
|
+
});
|
|
2544
|
+
const error = result.diagnostics?.find((item) => item.category === ts.DiagnosticCategory.Error);
|
|
2545
|
+
if (error)
|
|
2546
|
+
throw mpError(source.fileName, `helper \u8F6C\u6362\u5931\u8D25: ${ts.flattenDiagnosticMessageText(error.messageText, " ")}`);
|
|
2547
|
+
output.push(result.outputText.replace(/^export\s+(default\s+)?/gm, "").trim());
|
|
2548
|
+
};
|
|
2549
|
+
const dependedOn = new Set([...this.dependencies.values()].flatMap((values) => [...values]));
|
|
2550
|
+
for (const source of this.entries.keys())
|
|
2551
|
+
if (!dependedOn.has(source))
|
|
2552
|
+
emit(source);
|
|
2553
|
+
for (const source of this.entries.keys())
|
|
2554
|
+
emit(source);
|
|
2555
|
+
return output;
|
|
2556
|
+
}
|
|
2557
|
+
mayInitialize(node) {
|
|
2558
|
+
const { ts } = this.context;
|
|
2559
|
+
if (ts.isArrowFunction(node) || ts.isFunctionExpression(node) || ts.isIdentifier(node) || ts.isStringLiteralLike(node) || ts.isNumericLiteral(node) || [
|
|
2560
|
+
ts.SyntaxKind.TrueKeyword,
|
|
2561
|
+
ts.SyntaxKind.FalseKeyword,
|
|
2562
|
+
ts.SyntaxKind.NullKeyword
|
|
2563
|
+
].includes(node.kind))
|
|
2564
|
+
return false;
|
|
2565
|
+
if (ts.isParenthesizedExpression(node) || ts.isAsExpression(node) || ts.isTypeAssertionExpression(node) || ts.isSatisfiesExpression(node) || ts.isNonNullExpression(node))
|
|
2566
|
+
return this.mayInitialize(node.expression);
|
|
2567
|
+
if (ts.isArrayLiteralExpression(node))
|
|
2568
|
+
return node.elements.some((item) => ts.isSpreadElement(item) || this.mayInitialize(item));
|
|
2569
|
+
if (ts.isObjectLiteralExpression(node))
|
|
2570
|
+
return node.properties.some((property) => {
|
|
2571
|
+
if (ts.isSpreadAssignment(property))
|
|
2572
|
+
return true;
|
|
2573
|
+
if (property.name && ts.isComputedPropertyName(property.name) && this.mayInitialize(property.name.expression))
|
|
2574
|
+
return true;
|
|
2575
|
+
return ts.isPropertyAssignment(property) && this.mayInitialize(property.initializer);
|
|
2576
|
+
});
|
|
2577
|
+
return true;
|
|
2578
|
+
}
|
|
2579
|
+
orderedDependencies(source) {
|
|
2580
|
+
const { ts } = this.context;
|
|
2581
|
+
const order = new Map;
|
|
2582
|
+
source.statements.forEach((statement, position) => {
|
|
2583
|
+
if (!ts.isImportDeclaration(statement))
|
|
2584
|
+
return;
|
|
2585
|
+
const clause = statement.importClause;
|
|
2586
|
+
const bindings = clause?.namedBindings;
|
|
2587
|
+
const names = [
|
|
2588
|
+
statement.moduleSpecifier,
|
|
2589
|
+
...clause?.name ? [clause.name] : [],
|
|
2590
|
+
...bindings && ts.isNamedImports(bindings) ? bindings.elements.map((item) => item.name) : bindings ? [bindings.name] : []
|
|
2591
|
+
];
|
|
2592
|
+
for (const name of names) {
|
|
2593
|
+
const symbol = sourceSymbolAt(this.context, name, source);
|
|
2594
|
+
for (const declaration of symbol?.declarations ?? []) {
|
|
2595
|
+
const owner = declaration.getSourceFile();
|
|
2596
|
+
if (!order.has(owner))
|
|
2597
|
+
order.set(owner, position);
|
|
2598
|
+
}
|
|
2108
2599
|
}
|
|
2600
|
+
});
|
|
2601
|
+
return [...this.dependencies.get(source) ?? []].sort((a, b) => (order.get(a) ?? Number.MAX_SAFE_INTEGER) - (order.get(b) ?? Number.MAX_SAFE_INTEGER));
|
|
2602
|
+
}
|
|
2603
|
+
referencesLinkedValue(node, seen = new Set) {
|
|
2604
|
+
const { ts } = this.context;
|
|
2605
|
+
if (seen.has(node))
|
|
2606
|
+
return false;
|
|
2607
|
+
seen.add(node);
|
|
2608
|
+
if (ts.isIdentifier(node) || ts.isPropertyAccessExpression(node)) {
|
|
2609
|
+
const declaration = sourceSymbolAt(this.context, node)?.valueDeclaration;
|
|
2610
|
+
if (declaration && this.names.has(declaration))
|
|
2611
|
+
return true;
|
|
2612
|
+
if (declaration && !seen.has(declaration)) {
|
|
2613
|
+
if (ts.isFunctionDeclaration(declaration) && declaration.body && this.referencesLinkedValue(declaration.body, seen))
|
|
2614
|
+
return true;
|
|
2615
|
+
if (ts.isVariableDeclaration(declaration) && declaration.initializer && this.referencesLinkedValue(declaration.initializer, seen))
|
|
2616
|
+
return true;
|
|
2617
|
+
}
|
|
2618
|
+
}
|
|
2619
|
+
return ts.forEachChild(node, (child) => this.referencesLinkedValue(child, seen) || undefined) ?? false;
|
|
2620
|
+
}
|
|
2621
|
+
linkFrom(declaration, source) {
|
|
2622
|
+
const name = this.link(declaration);
|
|
2623
|
+
const dependency = declaration.getSourceFile();
|
|
2624
|
+
if (name && dependency !== source) {
|
|
2625
|
+
if (!this.entries.has(source))
|
|
2626
|
+
this.entries.set(source, new Map);
|
|
2627
|
+
const dependencies = this.dependencies.get(source) ?? new Set;
|
|
2628
|
+
dependencies.add(dependency);
|
|
2629
|
+
this.dependencies.set(source, dependencies);
|
|
2630
|
+
}
|
|
2631
|
+
return name;
|
|
2632
|
+
}
|
|
2633
|
+
rewrite(node, source) {
|
|
2634
|
+
const { ts } = this.context;
|
|
2635
|
+
const result = ts.transform(node, [
|
|
2636
|
+
(transformContext) => (root) => {
|
|
2637
|
+
const visit = (current) => {
|
|
2638
|
+
if (ts.isShorthandPropertyAssignment(current)) {
|
|
2639
|
+
const request = this.requestReference(current.name, source);
|
|
2640
|
+
if (request)
|
|
2641
|
+
return ts.factory.createPropertyAssignment(current.name.text, request);
|
|
2642
|
+
const original = ts.getOriginalNode(current.name);
|
|
2643
|
+
const declaration = original.pos >= 0 && original.getSourceFile() ? sourceSymbolAt(this.context, original, source)?.valueDeclaration : undefined;
|
|
2644
|
+
const linked = declaration && this.linkFrom(declaration, source);
|
|
2645
|
+
if (linked)
|
|
2646
|
+
return ts.factory.createPropertyAssignment(current.name.text, ts.factory.createIdentifier(linked));
|
|
2647
|
+
return current;
|
|
2648
|
+
}
|
|
2649
|
+
if (ts.isIdentifier(current) || ts.isPropertyAccessExpression(current)) {
|
|
2650
|
+
const parent = current.parent;
|
|
2651
|
+
const keyOnly = ts.isIdentifier(current) && parent && (ts.isPropertyAccessExpression(parent) && parent.name === current || ts.isPropertyAssignment(parent) && parent.name === current || ts.isMethodDeclaration(parent) && parent.name === current);
|
|
2652
|
+
if (!keyOnly) {
|
|
2653
|
+
const request = this.requestReference(current, source);
|
|
2654
|
+
if (request)
|
|
2655
|
+
return request;
|
|
2656
|
+
const original = ts.getOriginalNode(current);
|
|
2657
|
+
const symbol = original.pos >= 0 && original.getSourceFile() ? sourceSymbolAt(this.context, original, source) : undefined;
|
|
2658
|
+
const declaration = symbol?.valueDeclaration;
|
|
2659
|
+
const linked = declaration && this.linkFrom(declaration, source);
|
|
2660
|
+
if (linked)
|
|
2661
|
+
return ts.factory.createIdentifier(linked);
|
|
2662
|
+
}
|
|
2663
|
+
}
|
|
2664
|
+
return ts.visitEachChild(current, visit, transformContext);
|
|
2665
|
+
};
|
|
2666
|
+
return ts.visitNode(root, visit);
|
|
2667
|
+
}
|
|
2668
|
+
]);
|
|
2669
|
+
const transformed = result.transformed[0];
|
|
2670
|
+
result.dispose();
|
|
2671
|
+
return transformed;
|
|
2672
|
+
}
|
|
2673
|
+
requestReference(node, source) {
|
|
2674
|
+
const { ts } = this.context;
|
|
2675
|
+
const parent = node.parent;
|
|
2676
|
+
if (parent && ts.isIdentifier(node) && (ts.isParameter(parent) || ts.isVariableDeclaration(parent) || ts.isFunctionDeclaration(parent) || ts.isClassDeclaration(parent) || ts.isBindingElement(parent)) && parent.name === node)
|
|
2677
|
+
return;
|
|
2678
|
+
let local;
|
|
2679
|
+
let member;
|
|
2680
|
+
if (ts.isIdentifier(node))
|
|
2681
|
+
local = node.text;
|
|
2682
|
+
if (ts.isPropertyAccessExpression(node) && ts.isIdentifier(node.expression)) {
|
|
2683
|
+
local = node.expression.text;
|
|
2684
|
+
member = node.name.text;
|
|
2685
|
+
}
|
|
2686
|
+
if (!local)
|
|
2687
|
+
return;
|
|
2688
|
+
const original = ts.getOriginalNode(ts.isPropertyAccessExpression(node) ? node.expression : node);
|
|
2689
|
+
if (original.pos < 0 || !original.getSourceFile())
|
|
2690
|
+
return;
|
|
2691
|
+
const symbol = sourceSymbolAt(this.context, original, source);
|
|
2692
|
+
if (!symbol)
|
|
2693
|
+
return;
|
|
2694
|
+
const sameBinding = (name) => name.text === local && sourceSymbolAt(this.context, name, source) === symbol;
|
|
2695
|
+
for (const statement of source.statements) {
|
|
2696
|
+
if (!ts.isImportDeclaration(statement) || !ts.isStringLiteral(statement.moduleSpecifier) || statement.moduleSpecifier.text !== "transone/request")
|
|
2697
|
+
continue;
|
|
2698
|
+
const clause = statement.importClause;
|
|
2699
|
+
const bindings = clause?.namedBindings;
|
|
2700
|
+
let exported;
|
|
2701
|
+
if (clause?.name && sameBinding(clause.name))
|
|
2702
|
+
exported = "default";
|
|
2703
|
+
if (bindings && ts.isNamedImports(bindings))
|
|
2704
|
+
exported = bindings.elements.find((item) => sameBinding(item.name))?.propertyName?.text ?? (bindings.elements.some((item) => sameBinding(item.name)) ? local : exported);
|
|
2705
|
+
if (bindings && ts.isNamespaceImport(bindings) && sameBinding(bindings.name))
|
|
2706
|
+
exported = member ?? "*";
|
|
2707
|
+
if (!exported)
|
|
2708
|
+
continue;
|
|
2709
|
+
if (member && !(bindings && ts.isNamespaceImport(bindings) && sameBinding(bindings.name)))
|
|
2710
|
+
return;
|
|
2711
|
+
const runtime = ts.factory.createPropertyAccessExpression(ts.factory.createCallExpression(ts.factory.createIdentifier("getApp"), undefined, []), "__transoneRequest");
|
|
2712
|
+
return exported === "*" ? runtime : ts.factory.createElementAccessExpression(runtime, ts.factory.createStringLiteral(exported));
|
|
2109
2713
|
}
|
|
2714
|
+
return;
|
|
2715
|
+
}
|
|
2716
|
+
link(declaration) {
|
|
2717
|
+
const { ts } = this.context;
|
|
2718
|
+
const source = declaration.getSourceFile();
|
|
2719
|
+
if (source.isDeclarationFile)
|
|
2720
|
+
return;
|
|
2721
|
+
const topVariable = ts.isVariableDeclaration(declaration) && ts.isVariableDeclarationList(declaration.parent) && ts.isVariableStatement(declaration.parent.parent) && ts.isSourceFile(declaration.parent.parent.parent);
|
|
2722
|
+
const topFunction = ts.isFunctionDeclaration(declaration) && ts.isSourceFile(declaration.parent);
|
|
2723
|
+
const topClass = ts.isClassDeclaration(declaration) && ts.isSourceFile(declaration.parent);
|
|
2724
|
+
if (!topVariable && !topFunction && !topClass)
|
|
2725
|
+
return;
|
|
2726
|
+
if (topClass) {
|
|
2727
|
+
const ref = this.context.index?.findClass(source.fileName, declaration.name?.text ?? "default");
|
|
2728
|
+
if (ref && this.context.index.isComponent(ref))
|
|
2729
|
+
return;
|
|
2730
|
+
}
|
|
2731
|
+
const existing = this.names.get(declaration);
|
|
2732
|
+
if (existing)
|
|
2733
|
+
return existing;
|
|
2734
|
+
const name = `__mp_module_${this.names.size}`;
|
|
2735
|
+
this.names.set(declaration, name);
|
|
2736
|
+
const entries = this.entries.get(source) ?? new Map;
|
|
2737
|
+
this.entries.set(source, entries);
|
|
2738
|
+
const transformed = this.rewrite(declaration, source);
|
|
2739
|
+
let statement = transformed;
|
|
2740
|
+
if (ts.isVariableDeclaration(transformed))
|
|
2741
|
+
statement = ts.factory.createVariableStatement(undefined, ts.factory.createVariableDeclarationList([transformed], ts.isVariableDeclarationList(declaration.parent) ? declaration.parent.flags : ts.NodeFlags.Const));
|
|
2742
|
+
entries.set(declaration, statement);
|
|
2743
|
+
return name;
|
|
2110
2744
|
}
|
|
2111
|
-
return consts;
|
|
2112
2745
|
}
|
|
2113
2746
|
|
|
2114
2747
|
// src/mp/methods.ts
|
|
@@ -2131,13 +2764,26 @@ var COMPONENT_LIFECYCLE = {
|
|
|
2131
2764
|
onUnmounted: "detached"
|
|
2132
2765
|
};
|
|
2133
2766
|
function compileMethods(context, classSource, usedNames, kind, customEvents) {
|
|
2134
|
-
const
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2767
|
+
const methods = new Map(ownedMethods(context, classSource).map((item) => [
|
|
2768
|
+
item.declaration.name.getText(item.owner.source),
|
|
2769
|
+
item
|
|
2770
|
+
]));
|
|
2771
|
+
const linker = context.index ? new MethodModuleLinker(context) : undefined;
|
|
2772
|
+
const parentAliases = new Map;
|
|
2773
|
+
const resolveSuper = (owner, name) => {
|
|
2774
|
+
const parent = parentSource(context, owner);
|
|
2775
|
+
const owned = parent && ownedMethod(context, parent, name);
|
|
2776
|
+
if (!owned)
|
|
2777
|
+
throw mpError(owner.filePath, `\u4E0D\u652F\u6301 super.${name}(): \u672A\u627E\u5230\u7236\u4E1A\u52A1\u65B9\u6CD5`);
|
|
2778
|
+
const identity = `${owned.owner.filePath}:${owned.declaration.pos}`;
|
|
2779
|
+
const existing = parentAliases.get(identity);
|
|
2780
|
+
if (existing)
|
|
2781
|
+
return existing;
|
|
2782
|
+
const alias = `__mp_super_${parentAliases.size}_${name}`;
|
|
2783
|
+
parentAliases.set(identity, alias);
|
|
2784
|
+
methods.set(alias, owned);
|
|
2785
|
+
return alias;
|
|
2786
|
+
};
|
|
2141
2787
|
const lifecycleMap = kind === "page" ? PAGE_LIFECYCLE : COMPONENT_LIFECYCLE;
|
|
2142
2788
|
const seed = new Set(usedNames);
|
|
2143
2789
|
for (const hook of Object.keys(lifecycleMap)) {
|
|
@@ -2159,8 +2805,8 @@ function compileMethods(context, classSource, usedNames, kind, customEvents) {
|
|
|
2159
2805
|
continue;
|
|
2160
2806
|
}
|
|
2161
2807
|
visited.add(name);
|
|
2162
|
-
const
|
|
2163
|
-
if (!
|
|
2808
|
+
const owned = methods.get(name);
|
|
2809
|
+
if (!owned) {
|
|
2164
2810
|
throw mpError(classSource.filePath, `\u672A\u627E\u5230\u4E8B\u4EF6\u5904\u7406\u65B9\u6CD5 "${name}"`);
|
|
2165
2811
|
}
|
|
2166
2812
|
const lifecycleKey = lifecycleMap[name];
|
|
@@ -2169,16 +2815,20 @@ function compileMethods(context, classSource, usedNames, kind, customEvents) {
|
|
|
2169
2815
|
throw mpError(classSource.filePath, `\u65B9\u6CD5\u540D "${key}" \u4E0E\u5C0F\u7A0B\u5E8F\u751F\u547D\u5468\u671F\u94A9\u5B50\u51B2\u7A81`);
|
|
2170
2816
|
}
|
|
2171
2817
|
emittedKeys.add(key);
|
|
2172
|
-
const fn = compileMethod(context,
|
|
2818
|
+
const fn = compileMethod(context, owned.owner, owned.declaration, kind, customEvents, queue, resolveSuper, linker);
|
|
2173
2819
|
if (lifecycleKey) {
|
|
2174
2820
|
lifecycleEntries.push({ key, fn });
|
|
2175
2821
|
} else {
|
|
2176
2822
|
entries.push({ key, fn });
|
|
2177
2823
|
}
|
|
2178
2824
|
}
|
|
2179
|
-
return {
|
|
2825
|
+
return {
|
|
2826
|
+
methods: entries,
|
|
2827
|
+
lifecycle: lifecycleEntries,
|
|
2828
|
+
inlineModules: linker?.modules()
|
|
2829
|
+
};
|
|
2180
2830
|
}
|
|
2181
|
-
function compileMethod(context, classSource, declaration, kind, customEvents, referencedMethods) {
|
|
2831
|
+
function compileMethod(context, classSource, declaration, kind, customEvents, referencedMethods, resolveSuper, linker) {
|
|
2182
2832
|
const { ts } = context;
|
|
2183
2833
|
if (!declaration.body) {
|
|
2184
2834
|
throw mpError(classSource.filePath, `\u65B9\u6CD5 ${declaration.name.getText()} \u7F3A\u5C11\u65B9\u6CD5\u4F53`);
|
|
@@ -2195,16 +2845,20 @@ function compileMethod(context, classSource, declaration, kind, customEvents, re
|
|
|
2195
2845
|
customEvents,
|
|
2196
2846
|
consts,
|
|
2197
2847
|
locals,
|
|
2198
|
-
referencedMethods
|
|
2848
|
+
referencedMethods,
|
|
2849
|
+
resolveSuper
|
|
2199
2850
|
});
|
|
2200
2851
|
};
|
|
2201
2852
|
const result = ts.transform(functionExpression, [transformerFactory]);
|
|
2202
|
-
const transformed = result.transformed[0];
|
|
2853
|
+
const transformed = linker ? linker.rewrite(result.transformed[0], classSource.source) : result.transformed[0];
|
|
2203
2854
|
result.dispose();
|
|
2204
2855
|
const printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed });
|
|
2205
2856
|
const printed = printer.printNode(ts.EmitHint.Expression, transformed, classSource.source);
|
|
2206
2857
|
const transpiled = ts.transpileModule(printed, {
|
|
2207
|
-
compilerOptions: {
|
|
2858
|
+
compilerOptions: {
|
|
2859
|
+
target: ts.ScriptTarget.ESNext,
|
|
2860
|
+
module: ts.ModuleKind.None
|
|
2861
|
+
},
|
|
2208
2862
|
reportDiagnostics: false
|
|
2209
2863
|
});
|
|
2210
2864
|
return transpiled.outputText.trim();
|
|
@@ -2221,6 +2875,14 @@ function visit(context, classSource, node, state) {
|
|
|
2221
2875
|
if (ts.isVariableDeclaration(node) && ts.isIdentifier(node.name)) {
|
|
2222
2876
|
state.locals.add(node.name.text);
|
|
2223
2877
|
}
|
|
2878
|
+
if (ts.isCallExpression(node) && ts.isPropertyAccessExpression(node.expression) && node.expression.expression.kind === ts.SyntaxKind.SuperKeyword) {
|
|
2879
|
+
const alias = state.resolveSuper(classSource, node.expression.name.text);
|
|
2880
|
+
state.referencedMethods.push(alias);
|
|
2881
|
+
const call = ts.factory.createCallExpression(ts.factory.createPropertyAccessExpression(ts.factory.createThis(), alias), undefined, node.arguments);
|
|
2882
|
+
return ts.visitEachChild(call, (child) => visit(context, classSource, child, state), state.transformContext);
|
|
2883
|
+
}
|
|
2884
|
+
if (node.kind === ts.SyntaxKind.SuperKeyword)
|
|
2885
|
+
throw mpError(classSource.filePath, "\u4E0D\u652F\u6301\u7684 super \u8868\u8FBE\u5F0F\uFF1A\u4EC5\u652F\u6301\u7236\u4E1A\u52A1\u65B9\u6CD5\u8C03\u7528");
|
|
2224
2886
|
if (ts.isBinaryExpression(node) && isAssignmentOperator(ts, node.operatorToken.kind)) {
|
|
2225
2887
|
if (isWholeStateAssignment(ts, node.left)) {
|
|
2226
2888
|
throw mpError(classSource.filePath, "\u4E0D\u652F\u6301\u66FF\u6362\u6574\u4E2A this.state\uFF0C\u8BF7\u6539\u7528 this.setState({ ... })");
|
|
@@ -2268,7 +2930,12 @@ function visit(context, classSource, node, state) {
|
|
|
2268
2930
|
return ts.factory.createPropertyAccessExpression(ts.factory.createThis(), "properties");
|
|
2269
2931
|
}
|
|
2270
2932
|
}
|
|
2271
|
-
if (ts.
|
|
2933
|
+
if (ts.isShorthandPropertyAssignment(node) && !state.locals.has(node.name.text) && state.consts.has(node.name.text)) {
|
|
2934
|
+
const value = foldExpression(ts, state.consts.get(node.name.text), state.consts);
|
|
2935
|
+
if (value !== undefined && !(context.index && value !== null && typeof value === "object"))
|
|
2936
|
+
return ts.factory.createPropertyAssignment(node.name.text, valueToNode(ts, value));
|
|
2937
|
+
}
|
|
2938
|
+
if (ts.isIdentifier(node) && isValueReference(ts, node) && !state.locals.has(node.text) && state.consts.has(node.text)) {
|
|
2272
2939
|
const initializer = state.consts.get(node.text);
|
|
2273
2940
|
if (ts.isCallExpression(initializer) && ts.isIdentifier(initializer.expression)) {
|
|
2274
2941
|
const factoryName = initializer.expression.text;
|
|
@@ -2278,12 +2945,24 @@ function visit(context, classSource, node, state) {
|
|
|
2278
2945
|
}
|
|
2279
2946
|
const folded = foldExpression(ts, state.consts.get(node.text), state.consts);
|
|
2280
2947
|
if (folded === undefined) {
|
|
2948
|
+
if (context.index)
|
|
2949
|
+
return node;
|
|
2281
2950
|
throw mpError(classSource.filePath, `\u65B9\u6CD5\u4E2D\u5F15\u7528\u4E86\u65E0\u6CD5\u9759\u6001\u6C42\u503C\u7684\u6A21\u5757\u5E38\u91CF "${node.text}"`);
|
|
2282
2951
|
}
|
|
2952
|
+
if (context.index && folded !== null && typeof folded === "object")
|
|
2953
|
+
return node;
|
|
2283
2954
|
return valueToNode(ts, folded);
|
|
2284
2955
|
}
|
|
2285
2956
|
return ts.visitEachChild(node, (child) => visit(context, classSource, child, state), state.transformContext);
|
|
2286
2957
|
}
|
|
2958
|
+
function isValueReference(ts, node) {
|
|
2959
|
+
const parent = node.parent;
|
|
2960
|
+
if (!parent)
|
|
2961
|
+
return true;
|
|
2962
|
+
if ((ts.isPropertyAccessExpression(parent) || ts.isPropertyAssignment(parent) || ts.isVariableDeclaration(parent) || ts.isParameter(parent) || ts.isMethodDeclaration(parent) || ts.isFunctionDeclaration(parent) || ts.isBindingElement(parent)) && parent.name === node)
|
|
2963
|
+
return false;
|
|
2964
|
+
return !ts.isShorthandPropertyAssignment(parent);
|
|
2965
|
+
}
|
|
2287
2966
|
var BRIDGE_METHODS = new Set(["emit", "setState", "setData", "triggerEvent"]);
|
|
2288
2967
|
function buildStateAssignment(ts, node, filePath) {
|
|
2289
2968
|
const path = statePath(ts, node.left);
|
|
@@ -2360,9 +3039,6 @@ function compoundOperatorText(ts, kind) {
|
|
|
2360
3039
|
function isThisMemberCall(ts, node, name) {
|
|
2361
3040
|
return ts.isPropertyAccessExpression(node.expression) && isThisExpression(ts, node.expression.expression) && node.expression.name.text === name;
|
|
2362
3041
|
}
|
|
2363
|
-
function isStatic(ts, declaration) {
|
|
2364
|
-
return (declaration.modifiers ?? []).some((modifier) => modifier.kind === ts.SyntaxKind.StaticKeyword);
|
|
2365
|
-
}
|
|
2366
3042
|
function isAsync(ts, declaration) {
|
|
2367
3043
|
return (declaration.modifiers ?? []).some((modifier) => modifier.kind === ts.SyntaxKind.AsyncKeyword);
|
|
2368
3044
|
}
|
|
@@ -2385,145 +3061,7 @@ function valueToNode(ts, value) {
|
|
|
2385
3061
|
return ts.factory.createObjectLiteralExpression(Object.entries(value).map(([key, item]) => ts.factory.createPropertyAssignment(ts.factory.createStringLiteral(key), valueToNode(ts, item))));
|
|
2386
3062
|
}
|
|
2387
3063
|
function collectModuleConsts4(context, classSource) {
|
|
2388
|
-
|
|
2389
|
-
for (const statement of classSource.source.statements) {
|
|
2390
|
-
if (!context.ts.isVariableStatement(statement)) {
|
|
2391
|
-
continue;
|
|
2392
|
-
}
|
|
2393
|
-
const isConst = statement.declarationList.flags & context.ts.NodeFlags.Const;
|
|
2394
|
-
if (!isConst) {
|
|
2395
|
-
continue;
|
|
2396
|
-
}
|
|
2397
|
-
for (const declaration of statement.declarationList.declarations) {
|
|
2398
|
-
if (context.ts.isIdentifier(declaration.name) && declaration.initializer) {
|
|
2399
|
-
consts.set(declaration.name.text, declaration.initializer);
|
|
2400
|
-
}
|
|
2401
|
-
}
|
|
2402
|
-
}
|
|
2403
|
-
return consts;
|
|
2404
|
-
}
|
|
2405
|
-
|
|
2406
|
-
// src/mp/inline.ts
|
|
2407
|
-
import { dirname as dirname2, join as join2 } from "path";
|
|
2408
|
-
function collectInlineModules(context, classSource) {
|
|
2409
|
-
const { ts } = context;
|
|
2410
|
-
const output = [];
|
|
2411
|
-
const seen = new Set;
|
|
2412
|
-
const stack = new Set;
|
|
2413
|
-
const walk = (source) => {
|
|
2414
|
-
const filePath = source.fileName;
|
|
2415
|
-
if (seen.has(filePath)) {
|
|
2416
|
-
return;
|
|
2417
|
-
}
|
|
2418
|
-
for (const statement of source.statements) {
|
|
2419
|
-
if (!ts.isImportDeclaration(statement)) {
|
|
2420
|
-
continue;
|
|
2421
|
-
}
|
|
2422
|
-
const specifier = statement.moduleSpecifier;
|
|
2423
|
-
if (!ts.isStringLiteral(specifier)) {
|
|
2424
|
-
continue;
|
|
2425
|
-
}
|
|
2426
|
-
const target = resolveRelativeModule(context, filePath, specifier.text);
|
|
2427
|
-
if (!target) {
|
|
2428
|
-
continue;
|
|
2429
|
-
}
|
|
2430
|
-
if (stack.has(target)) {
|
|
2431
|
-
warn(context, `\u6A21\u5757\u5FAA\u73AF\u5F15\u7528\u5DF2\u8DF3\u8FC7: ${target}`);
|
|
2432
|
-
continue;
|
|
2433
|
-
}
|
|
2434
|
-
stack.add(target);
|
|
2435
|
-
walk(readSource(context, target));
|
|
2436
|
-
stack.delete(target);
|
|
2437
|
-
}
|
|
2438
|
-
seen.add(filePath);
|
|
2439
|
-
output.push(compileInlineModule(context, source));
|
|
2440
|
-
};
|
|
2441
|
-
walk(classSource.source);
|
|
2442
|
-
return output;
|
|
2443
|
-
}
|
|
2444
|
-
function resolveRelativeModule(context, fromFile, specifier) {
|
|
2445
|
-
if (!specifier.startsWith("./") && !specifier.startsWith("../")) {
|
|
2446
|
-
return null;
|
|
2447
|
-
}
|
|
2448
|
-
const base = specifier.endsWith(".ts") ? specifier : `${specifier}.ts`;
|
|
2449
|
-
const resolved = join2(dirname2(fromFile), base);
|
|
2450
|
-
if (isComponentFile(context, resolved)) {
|
|
2451
|
-
return null;
|
|
2452
|
-
}
|
|
2453
|
-
return resolved;
|
|
2454
|
-
}
|
|
2455
|
-
function isComponentFile(context, filePath) {
|
|
2456
|
-
const { ts } = context;
|
|
2457
|
-
const source = readSource(context, filePath);
|
|
2458
|
-
for (const statement of source.statements) {
|
|
2459
|
-
if (!ts.isClassDeclaration(statement)) {
|
|
2460
|
-
continue;
|
|
2461
|
-
}
|
|
2462
|
-
const name = statement.name?.text;
|
|
2463
|
-
if (!name) {
|
|
2464
|
-
continue;
|
|
2465
|
-
}
|
|
2466
|
-
const isExported2 = statement.modifiers?.some((m) => m.kind === ts.SyntaxKind.ExportKeyword);
|
|
2467
|
-
if (!isExported2) {
|
|
2468
|
-
continue;
|
|
2469
|
-
}
|
|
2470
|
-
const heritage = statement.heritageClauses?.some((clause) => clause.types.some((type) => {
|
|
2471
|
-
const expr = type.expression;
|
|
2472
|
-
if (!ts.isIdentifier(expr)) {
|
|
2473
|
-
return false;
|
|
2474
|
-
}
|
|
2475
|
-
return expr.text === "Component" || expr.text.endsWith("Component");
|
|
2476
|
-
}));
|
|
2477
|
-
if (heritage) {
|
|
2478
|
-
return true;
|
|
2479
|
-
}
|
|
2480
|
-
}
|
|
2481
|
-
return false;
|
|
2482
|
-
}
|
|
2483
|
-
function compileInlineModule(context, source) {
|
|
2484
|
-
const { ts } = context;
|
|
2485
|
-
const kept = [];
|
|
2486
|
-
const requestImports = [];
|
|
2487
|
-
for (const statement of source.statements) {
|
|
2488
|
-
if (ts.isImportDeclaration(statement) && ts.isStringLiteral(statement.moduleSpecifier) && statement.moduleSpecifier.text === "transone/request" && !statement.importClause?.isTypeOnly) {
|
|
2489
|
-
const clause = statement.importClause;
|
|
2490
|
-
if (clause?.name)
|
|
2491
|
-
requestImports.push(`const ${clause.name.text} = getApp().__transoneRequest.default;`);
|
|
2492
|
-
const bindings = clause?.namedBindings;
|
|
2493
|
-
if (bindings && ts.isNamespaceImport(bindings)) {
|
|
2494
|
-
requestImports.push(`const ${bindings.name.text} = getApp().__transoneRequest;`);
|
|
2495
|
-
} else if (bindings && ts.isNamedImports(bindings)) {
|
|
2496
|
-
for (const item of bindings.elements) {
|
|
2497
|
-
if (!item.isTypeOnly)
|
|
2498
|
-
requestImports.push(`const ${item.name.text} = getApp().__transoneRequest[${JSON.stringify(item.propertyName?.text ?? item.name.text)}];`);
|
|
2499
|
-
}
|
|
2500
|
-
}
|
|
2501
|
-
}
|
|
2502
|
-
if (ts.isImportDeclaration(statement) || ts.isExportDeclaration(statement) || ts.isExportAssignment(statement) || ts.isInterfaceDeclaration(statement) || ts.isTypeAliasDeclaration(statement)) {
|
|
2503
|
-
continue;
|
|
2504
|
-
}
|
|
2505
|
-
if (ts.isClassDeclaration(statement) && statement.heritageClauses?.some((clause) => clause.types.some((type) => ts.isIdentifier(type.expression) && (type.expression.text === "Component" || type.expression.text.endsWith("Component")))))
|
|
2506
|
-
continue;
|
|
2507
|
-
if (ts.isVariableStatement(statement)) {
|
|
2508
|
-
const declarations = statement.declarationList.declarations.filter((declaration) => !(declaration.initializer && ts.isCallExpression(declaration.initializer) && ts.isIdentifier(declaration.initializer.expression) && declaration.initializer.expression.text === "createApp"));
|
|
2509
|
-
if (declarations.length === 0)
|
|
2510
|
-
continue;
|
|
2511
|
-
kept.push(ts.factory.updateVariableStatement(statement, statement.modifiers, ts.factory.updateVariableDeclarationList(statement.declarationList, declarations)));
|
|
2512
|
-
continue;
|
|
2513
|
-
}
|
|
2514
|
-
kept.push(statement);
|
|
2515
|
-
}
|
|
2516
|
-
const printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed });
|
|
2517
|
-
const printed = printer.printList(ts.ListFormat.MultiLine, ts.factory.createNodeArray(kept), source);
|
|
2518
|
-
const transpiled = ts.transpileModule(printed, {
|
|
2519
|
-
compilerOptions: {
|
|
2520
|
-
target: ts.ScriptTarget.ESNext,
|
|
2521
|
-
module: ts.ModuleKind.ES2015
|
|
2522
|
-
},
|
|
2523
|
-
reportDiagnostics: false
|
|
2524
|
-
});
|
|
2525
|
-
return [...requestImports, transpiled.outputText.replace(/^export\s+/gm, "").trim()].join(`
|
|
2526
|
-
`);
|
|
3064
|
+
return moduleConstants(context, classSource);
|
|
2527
3065
|
}
|
|
2528
3066
|
|
|
2529
3067
|
// src/mp/compile.ts
|
|
@@ -2548,7 +3086,7 @@ function compileUnit(context, classSource, options) {
|
|
|
2548
3086
|
usedNames.add(emitter.method);
|
|
2549
3087
|
}
|
|
2550
3088
|
const customEvents = new Set;
|
|
2551
|
-
const
|
|
3089
|
+
const legacyModules = context.index ? undefined : collectInlineModules(context, classSource);
|
|
2552
3090
|
const compiledMethods = compileMethods(context, classSource, usedNames, kind, customEvents);
|
|
2553
3091
|
const methods = [...compiledMethods.methods];
|
|
2554
3092
|
for (const emitter of builder.emitters) {
|
|
@@ -2574,7 +3112,7 @@ function compileUnit(context, classSource, options) {
|
|
|
2574
3112
|
lifecycle: compiledMethods.lifecycle,
|
|
2575
3113
|
customEvents: [...customEvents],
|
|
2576
3114
|
usingComponents,
|
|
2577
|
-
inlineModules
|
|
3115
|
+
inlineModules: compiledMethods.inlineModules ?? legacyModules ?? []
|
|
2578
3116
|
};
|
|
2579
3117
|
if (kind === "component") {
|
|
2580
3118
|
context.components.set(name, unit);
|
|
@@ -2693,6 +3231,12 @@ async function buildMiniProgram(config, dialect) {
|
|
|
2693
3231
|
const ts = await loadTypescript();
|
|
2694
3232
|
const context = {
|
|
2695
3233
|
ts,
|
|
3234
|
+
index: createComponentIndex({
|
|
3235
|
+
root: config.root,
|
|
3236
|
+
entrypoints: Object.values(mp.pages),
|
|
3237
|
+
platform: config.platform,
|
|
3238
|
+
...config.components
|
|
3239
|
+
}),
|
|
2696
3240
|
root: config.root,
|
|
2697
3241
|
files: new Map,
|
|
2698
3242
|
components: new Map,
|
|
@@ -2716,13 +3260,22 @@ async function buildMiniProgram(config, dialect) {
|
|
|
2716
3260
|
for (const warning of context.warnings) {
|
|
2717
3261
|
console.warn(`[transone mp] ${warning}`);
|
|
2718
3262
|
}
|
|
2719
|
-
|
|
2720
|
-
|
|
2721
|
-
|
|
3263
|
+
return withBuildOutput({
|
|
3264
|
+
root: config.root,
|
|
3265
|
+
outDir: mp.outDir,
|
|
3266
|
+
protectedPaths: buildInputPaths(config, Object.values(mp.pages), [
|
|
3267
|
+
mp.publicDir,
|
|
3268
|
+
...context.index.sources.map((source) => source.fileName),
|
|
3269
|
+
...context.files.keys()
|
|
3270
|
+
])
|
|
3271
|
+
}, (outDir) => writeMiniProgram(config, dialect, outDir, pages, context));
|
|
3272
|
+
}
|
|
3273
|
+
async function writeMiniProgram(config, dialect, outDir, pages, context) {
|
|
3274
|
+
const mp = config.mp;
|
|
2722
3275
|
const assetsBuilt = [];
|
|
2723
3276
|
const write = async (path, content) => {
|
|
2724
|
-
const target =
|
|
2725
|
-
await mkdir(
|
|
3277
|
+
const target = buildOutputPath(outDir, path);
|
|
3278
|
+
await mkdir(dirname4(target), { recursive: true });
|
|
2726
3279
|
await writeFile(target, content, "utf8");
|
|
2727
3280
|
assetsBuilt.push(target);
|
|
2728
3281
|
};
|
|
@@ -2790,11 +3343,11 @@ async function buildMiniProgram(config, dialect) {
|
|
|
2790
3343
|
await write(`components/${tag}/${tag}.json`, `${JSON.stringify(dialect.componentJson(unit.usingComponents), null, 2)}
|
|
2791
3344
|
`);
|
|
2792
3345
|
}
|
|
2793
|
-
if (
|
|
3346
|
+
if (existsSync3(mp.publicDir)) {
|
|
2794
3347
|
for (const file of await listFiles(mp.publicDir)) {
|
|
2795
|
-
const target =
|
|
2796
|
-
if (!
|
|
2797
|
-
await cp(
|
|
3348
|
+
const target = buildOutputPath(outDir, file);
|
|
3349
|
+
if (!existsSync3(target)) {
|
|
3350
|
+
await cp(join4(mp.publicDir, file), target, {
|
|
2798
3351
|
recursive: true,
|
|
2799
3352
|
force: true,
|
|
2800
3353
|
errorOnExist: false
|
|
@@ -2804,7 +3357,7 @@ async function buildMiniProgram(config, dialect) {
|
|
|
2804
3357
|
}
|
|
2805
3358
|
return {
|
|
2806
3359
|
root: config.root,
|
|
2807
|
-
outDir:
|
|
3360
|
+
outDir: resolve3(outDir),
|
|
2808
3361
|
assetsBuilt
|
|
2809
3362
|
};
|
|
2810
3363
|
}
|
|
@@ -2829,7 +3382,7 @@ async function listFiles(root, dir = root) {
|
|
|
2829
3382
|
const out = [];
|
|
2830
3383
|
const entries = await readdir(dir, { withFileTypes: true });
|
|
2831
3384
|
for (const entry of entries) {
|
|
2832
|
-
const abs =
|
|
3385
|
+
const abs = join4(dir, entry.name);
|
|
2833
3386
|
if (entry.isDirectory()) {
|
|
2834
3387
|
out.push(...await listFiles(root, abs));
|
|
2835
3388
|
} else {
|
|
@@ -2842,5 +3395,5 @@ export {
|
|
|
2842
3395
|
buildMiniProgram
|
|
2843
3396
|
};
|
|
2844
3397
|
|
|
2845
|
-
//# debugId=
|
|
2846
|
-
//# sourceMappingURL=build-mp-
|
|
3398
|
+
//# debugId=2351C11ACC1AB08664756E2164756E21
|
|
3399
|
+
//# sourceMappingURL=build-mp-y5pwahsy.js.map
|