@mbler/mcx-core 0.0.3-dev.20260229 → 0.0.3
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/dist/index.d.ts +185 -108
- package/dist/index.js +728 -1714
- package/dist/index.js.map +1 -1
- package/dist/types/compile-mcx/compiler/index.d.ts +2 -2
- package/dist/types/compile-mcx/compiler/main.d.ts +2 -1
- package/dist/types/compile-mcx/index.d.ts +1 -0
- package/dist/types/compile-mcx/types.d.ts +4 -2
- package/dist/types/index.d.ts +4 -13
- package/dist/types/mcx-component/index.d.ts +2 -0
- package/dist/types/{compile-component → mcx-component}/lib.d.ts +0 -3
- package/dist/types/transforms/config.d.ts +1 -0
- package/dist/types/transforms/file_id.d.ts +1 -0
- package/dist/types/transforms/index.d.ts +3 -3
- package/dist/types/transforms/main.d.ts +2 -0
- package/dist/types/transforms/utils.d.ts +20 -5
- package/dist/types/transforms/x-comp/index.d.ts +3 -0
- package/dist/types/transforms/x-comp/x-app.d.ts +2 -0
- package/dist/types/transforms/x-comp/x-event.d.ts +2 -0
- package/dist/types/transforms/x-comp/x-ui.d.ts +2 -0
- package/dist/types/tsc/index.d.ts +1 -0
- package/dist/types/tsc/volar/index.d.ts +1 -0
- package/dist/types/tsc/volar/plugins/index.d.ts +1 -0
- package/dist/types/tsc/volar/plugins/mcx-file.d.ts +37 -0
- package/dist/types/types.d.ts +41 -14
- package/package.json +20 -16
- package/dist/types/compile-component/index.d.ts +0 -4
- package/dist/types/compile-mcx/compiler/bundler.d.ts +0 -2
- package/dist/types/compile-mcx/compiler/str.d.ts +0 -6
- /package/dist/types/{compile-component → mcx-component}/types.d.ts +0 -0
- /package/dist/types/{compile-component → mcx-component}/utils.d.ts +0 -0
package/dist/index.js
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
-
|
|
5
3
|
var fs = require('node:fs/promises');
|
|
6
4
|
var path = require('node:path');
|
|
5
|
+
var rollup = require('rollup');
|
|
6
|
+
var commjs = require('@rollup/plugin-commonjs');
|
|
7
|
+
var json = require('@rollup/plugin-json');
|
|
8
|
+
var module_resolve = require('@rollup/plugin-node-resolve');
|
|
7
9
|
var t = require('@babel/types');
|
|
8
10
|
var Parser = require('@babel/parser');
|
|
11
|
+
var ts = require('typescript');
|
|
9
12
|
var generator = require('@babel/generator');
|
|
13
|
+
var MagicString = require('magic-string');
|
|
10
14
|
|
|
11
15
|
function _interopNamespaceDefault(e) {
|
|
12
16
|
var n = Object.create(null);
|
|
@@ -29,8 +33,11 @@ var fs__namespace = /*#__PURE__*/_interopNamespaceDefault(fs);
|
|
|
29
33
|
var path__namespace = /*#__PURE__*/_interopNamespaceDefault(path);
|
|
30
34
|
var t__namespace = /*#__PURE__*/_interopNamespaceDefault(t);
|
|
31
35
|
var Parser__namespace = /*#__PURE__*/_interopNamespaceDefault(Parser);
|
|
32
|
-
var generator__namespace = /*#__PURE__*/_interopNamespaceDefault(generator);
|
|
33
36
|
|
|
37
|
+
/** 创建位置对象的辅助函数 */
|
|
38
|
+
function createPos(line, column) {
|
|
39
|
+
return { line, column };
|
|
40
|
+
}
|
|
34
41
|
let Lexer$1 = class Lexer {
|
|
35
42
|
text;
|
|
36
43
|
booleanProxyCache;
|
|
@@ -114,12 +121,13 @@ let Lexer$1 = class Lexer {
|
|
|
114
121
|
}
|
|
115
122
|
/**
|
|
116
123
|
* 拆分输入文本为 Token 流:Tag、TagEnd、Content
|
|
117
|
-
*
|
|
124
|
+
* 忽略 HTML 注释 <!-- ... --> 并记录每个 token 的起始位置与行号
|
|
118
125
|
*/
|
|
119
126
|
*tagSplitIterator() {
|
|
120
127
|
const text = this.text;
|
|
121
128
|
let i = 0;
|
|
122
129
|
let line = 1;
|
|
130
|
+
let column = 0;
|
|
123
131
|
const len = text.length;
|
|
124
132
|
while (i < len) {
|
|
125
133
|
const ch = text[i];
|
|
@@ -128,17 +136,23 @@ let Lexer$1 = class Lexer {
|
|
|
128
136
|
if (text.startsWith('!--', i + 1)) {
|
|
129
137
|
const endIdx = text.indexOf('-->', i + 4);
|
|
130
138
|
const commentEnd = endIdx === -1 ? len - 1 : endIdx + 2;
|
|
131
|
-
//
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
if (c === '\n')
|
|
139
|
+
// 更新行号和列号
|
|
140
|
+
for (let j = i; j <= commentEnd; j++) {
|
|
141
|
+
if (text[j] === '\n') {
|
|
135
142
|
line++;
|
|
143
|
+
column = 0;
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
column++;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
136
149
|
i = commentEnd + 1;
|
|
137
150
|
continue; // 跳过注释
|
|
138
151
|
}
|
|
139
152
|
// 普通标签读取到 '>'
|
|
140
153
|
const tokenStart = i;
|
|
141
154
|
const tokenStartLine = line;
|
|
155
|
+
const tokenStartColumn = column;
|
|
142
156
|
let j = i + 1;
|
|
143
157
|
let sawGt = false;
|
|
144
158
|
for (; j < len; j++) {
|
|
@@ -147,41 +161,51 @@ let Lexer$1 = class Lexer {
|
|
|
147
161
|
sawGt = true;
|
|
148
162
|
break;
|
|
149
163
|
}
|
|
150
|
-
if (c === '\n')
|
|
164
|
+
if (c === '\n') {
|
|
151
165
|
line++;
|
|
166
|
+
column = 0;
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
column++;
|
|
170
|
+
}
|
|
152
171
|
}
|
|
153
|
-
const tokenEnd = j;
|
|
154
172
|
const buffer = text.slice(tokenStart, sawGt ? j + 1 : len);
|
|
155
173
|
const type = buffer.startsWith('</') ? 'TagEnd' : 'Tag';
|
|
156
174
|
const tok = {
|
|
157
175
|
data: buffer,
|
|
158
176
|
type,
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
startLine: tokenStartLine
|
|
177
|
+
start: createPos(tokenStartLine, tokenStartColumn),
|
|
178
|
+
end: createPos(line, column)
|
|
162
179
|
};
|
|
163
180
|
yield tok;
|
|
164
181
|
i = sawGt ? j + 1 : len;
|
|
182
|
+
if (sawGt)
|
|
183
|
+
column++;
|
|
165
184
|
}
|
|
166
185
|
else {
|
|
167
186
|
// 内容直到下一个 '<'
|
|
168
187
|
const contentStart = i;
|
|
169
188
|
const contentStartLine = line;
|
|
189
|
+
const contentStartColumn = column;
|
|
170
190
|
let j = i;
|
|
171
191
|
for (; j < len; j++) {
|
|
172
192
|
const c = text[j];
|
|
173
193
|
if (c === '<')
|
|
174
194
|
break;
|
|
175
|
-
if (c === '\n')
|
|
195
|
+
if (c === '\n') {
|
|
176
196
|
line++;
|
|
197
|
+
column = 0;
|
|
198
|
+
}
|
|
199
|
+
else {
|
|
200
|
+
column++;
|
|
201
|
+
}
|
|
177
202
|
}
|
|
178
203
|
const data = text.slice(contentStart, j);
|
|
179
204
|
const n = {
|
|
180
205
|
data,
|
|
181
206
|
type: 'Content',
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
startLine: contentStartLine
|
|
207
|
+
start: createPos(contentStartLine, contentStartColumn),
|
|
208
|
+
end: createPos(line, j > contentStart ? column - 1 : column)
|
|
185
209
|
};
|
|
186
210
|
yield n;
|
|
187
211
|
i = j;
|
|
@@ -190,7 +214,7 @@ let Lexer$1 = class Lexer {
|
|
|
190
214
|
}
|
|
191
215
|
/**
|
|
192
216
|
* 生成 Token 迭代器,用于遍历所有结构化 Token
|
|
193
|
-
* 改为基于 stack 的解析以支持嵌套,并为 ParsedTagNode 添加 loc: { start
|
|
217
|
+
* 改为基于 stack 的解析以支持嵌套,并为 ParsedTagNode 添加 loc: { start, end }
|
|
194
218
|
* Content 改为递归节点数组 (ParsedTagContentNode | ParsedTagNode)[]
|
|
195
219
|
*/
|
|
196
220
|
*tokenIterator() {
|
|
@@ -222,10 +246,10 @@ let Lexer$1 = class Lexer {
|
|
|
222
246
|
// content 现在是一个数组,包含文本节点或子标签
|
|
223
247
|
content: [],
|
|
224
248
|
end: null,
|
|
225
|
-
|
|
249
|
+
type: 'TagNode',
|
|
226
250
|
loc: {
|
|
227
|
-
start: {
|
|
228
|
-
end: {
|
|
251
|
+
start: { ...token.start },
|
|
252
|
+
end: { ...token.end }
|
|
229
253
|
}
|
|
230
254
|
};
|
|
231
255
|
if (isSelfClosing) {
|
|
@@ -251,7 +275,7 @@ let Lexer$1 = class Lexer {
|
|
|
251
275
|
if (candidate && candidate.name === name) {
|
|
252
276
|
// 设置结束
|
|
253
277
|
candidate.end = token;
|
|
254
|
-
candidate.loc.end = {
|
|
278
|
+
candidate.loc.end = { ...token.end };
|
|
255
279
|
// 从 stack 中移除并附加到父节点或作为顶层节点产出
|
|
256
280
|
stack.splice(s, 1);
|
|
257
281
|
if (stack.length > 0) {
|
|
@@ -379,6 +403,8 @@ class MCXUtils {
|
|
|
379
403
|
typeof obj === 'object' &&
|
|
380
404
|
'data' in obj &&
|
|
381
405
|
'type' in obj &&
|
|
406
|
+
'start' in obj &&
|
|
407
|
+
'end' in obj &&
|
|
382
408
|
((obj.type) === 'Tag' || (obj.type) === 'TagEnd' || (obj.type) === 'Content'));
|
|
383
409
|
}
|
|
384
410
|
static isTagToken(obj) {
|
|
@@ -397,7 +423,9 @@ class MCXUtils {
|
|
|
397
423
|
return (!!obj &&
|
|
398
424
|
typeof obj === 'object' &&
|
|
399
425
|
'data' in obj &&
|
|
400
|
-
'type' in obj
|
|
426
|
+
'type' in obj &&
|
|
427
|
+
'start' in obj &&
|
|
428
|
+
'end' in obj);
|
|
401
429
|
}
|
|
402
430
|
static isTokenType(value) {
|
|
403
431
|
return (value === 'Tag' ||
|
|
@@ -708,30 +736,31 @@ class CompileError extends Error {
|
|
|
708
736
|
constructor(message, loc) {
|
|
709
737
|
super(message);
|
|
710
738
|
this.name = "CompileError";
|
|
711
|
-
this.loc = loc || { line: -1,
|
|
739
|
+
this.loc = loc || { line: -1, column: -1 };
|
|
712
740
|
}
|
|
713
741
|
}
|
|
714
742
|
function extractLoc(node) {
|
|
715
743
|
if (!node)
|
|
716
|
-
return { line: -1,
|
|
717
|
-
// Node with loc.start (Babel or MCX): prefer column
|
|
744
|
+
return { line: -1, column: -1 };
|
|
745
|
+
// Node with loc.start (Babel or MCX): prefer column
|
|
718
746
|
if (node.loc && node.loc.start) {
|
|
719
747
|
const line = typeof node.loc.start.line === "number" ? node.loc.start.line : -1;
|
|
720
|
-
const
|
|
748
|
+
const column = typeof node.loc.start.column === "number"
|
|
721
749
|
? node.loc.start.column
|
|
722
|
-
:
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
750
|
+
: -1;
|
|
751
|
+
return { line, column };
|
|
752
|
+
}
|
|
753
|
+
else if (node.loc && node.loc.column !== undefined) {
|
|
754
|
+
return {
|
|
755
|
+
line: node.loc.line ?? -1,
|
|
756
|
+
column: node.loc.column
|
|
757
|
+
};
|
|
758
|
+
}
|
|
759
|
+
// MCX Token with unified position: start: { line, column }
|
|
760
|
+
if (node.start && typeof node.start.line === "number") {
|
|
761
|
+
return { line: node.start.line, column: node.start.column ?? -1 };
|
|
762
|
+
}
|
|
763
|
+
return { line: -1, column: -1 };
|
|
735
764
|
}
|
|
736
765
|
function makeError(msg, node) {
|
|
737
766
|
return new CompileError(msg, extractLoc(node));
|
|
@@ -1120,10 +1149,11 @@ class CompileMCX {
|
|
|
1120
1149
|
Event: {
|
|
1121
1150
|
on: "after",
|
|
1122
1151
|
subscribe: {},
|
|
1123
|
-
loc: { line: -1,
|
|
1152
|
+
loc: { line: -1, column: -1 },
|
|
1124
1153
|
isLoad: false,
|
|
1125
1154
|
},
|
|
1126
1155
|
Component: {},
|
|
1156
|
+
UI: null,
|
|
1127
1157
|
};
|
|
1128
1158
|
getCompileData() {
|
|
1129
1159
|
return this.CompileData;
|
|
@@ -1161,15 +1191,25 @@ class CompileMCX {
|
|
|
1161
1191
|
let component = null;
|
|
1162
1192
|
const temp = {
|
|
1163
1193
|
script: "",
|
|
1164
|
-
Event: null
|
|
1194
|
+
Event: null,
|
|
1195
|
+
ui: null};
|
|
1165
1196
|
for (const node of this.mcxCode || []) {
|
|
1166
1197
|
if (!MCXUtils.isTagNode(node))
|
|
1167
1198
|
continue;
|
|
1168
1199
|
if (node.name == "script") {
|
|
1169
1200
|
if (temp.script)
|
|
1170
1201
|
throw makeError("[compile error]: duplicate script node", node);
|
|
1171
|
-
|
|
1172
|
-
|
|
1202
|
+
const scriptNode = node.content.length == 0 ? "" : this.commonTagNodeContent(node);
|
|
1203
|
+
let code = scriptNode;
|
|
1204
|
+
if (node.arr.lang == "ts") {
|
|
1205
|
+
code = ts.transpileModule(scriptNode, {
|
|
1206
|
+
compilerOptions: {
|
|
1207
|
+
target: ts.ScriptTarget.ES2024,
|
|
1208
|
+
module: ts.ModuleKind.ESNext,
|
|
1209
|
+
},
|
|
1210
|
+
}).outputText;
|
|
1211
|
+
}
|
|
1212
|
+
temp.script = code;
|
|
1173
1213
|
}
|
|
1174
1214
|
else if (node.name == "Event") {
|
|
1175
1215
|
if (temp.Event)
|
|
@@ -1185,8 +1225,15 @@ class CompileMCX {
|
|
|
1185
1225
|
// if Event already discovered, report error
|
|
1186
1226
|
if (temp.Event)
|
|
1187
1227
|
throw makeError("[compile error]: Component node cannot appear after Event", node);
|
|
1228
|
+
if (temp.ui)
|
|
1229
|
+
throw makeError("[compile error]: Component node can't use with UI node");
|
|
1188
1230
|
component = node;
|
|
1189
1231
|
}
|
|
1232
|
+
else if (node.name == "Ui") {
|
|
1233
|
+
if (component || temp.Event || temp.ui)
|
|
1234
|
+
throw makeError("[compile error]: UI node can't use with component or event or other ui node", node);
|
|
1235
|
+
temp.ui = node;
|
|
1236
|
+
}
|
|
1190
1237
|
}
|
|
1191
1238
|
if (!temp.script)
|
|
1192
1239
|
throw makeError("[compile error]: mcx must has a script");
|
|
@@ -1218,6 +1265,9 @@ class CompileMCX {
|
|
|
1218
1265
|
this.handlerChildComponent(subNode);
|
|
1219
1266
|
}
|
|
1220
1267
|
}
|
|
1268
|
+
if (temp.ui) {
|
|
1269
|
+
this.tempLoc.UI = temp.ui;
|
|
1270
|
+
}
|
|
1221
1271
|
}
|
|
1222
1272
|
// 传入组件的节点,处理子组件(如 items entities)
|
|
1223
1273
|
handlerChildComponent(node) {
|
|
@@ -1247,7 +1297,7 @@ class CompileMCX {
|
|
|
1247
1297
|
this.tempLoc.Component[`${name}/${id}`] = {
|
|
1248
1298
|
type: subName,
|
|
1249
1299
|
useExpore: useExpore,
|
|
1250
|
-
loc: extractLoc(subNode)
|
|
1300
|
+
loc: extractLoc(subNode),
|
|
1251
1301
|
};
|
|
1252
1302
|
}
|
|
1253
1303
|
}
|
|
@@ -1261,7 +1311,34 @@ class CompileMCX {
|
|
|
1261
1311
|
}
|
|
1262
1312
|
}
|
|
1263
1313
|
function compileJSFn(code) {
|
|
1264
|
-
|
|
1314
|
+
let parsedCode;
|
|
1315
|
+
try {
|
|
1316
|
+
parsedCode = Parser.parse(code, {
|
|
1317
|
+
sourceType: "module",
|
|
1318
|
+
allowImportExportEverywhere: true,
|
|
1319
|
+
errorRecovery: true,
|
|
1320
|
+
allowAwaitOutsideFunction: true,
|
|
1321
|
+
allowReturnOutsideFunction: true,
|
|
1322
|
+
allowSuperOutsideMethod: true,
|
|
1323
|
+
});
|
|
1324
|
+
}
|
|
1325
|
+
catch (err) {
|
|
1326
|
+
if (err instanceof SyntaxError) {
|
|
1327
|
+
const babelErr = err;
|
|
1328
|
+
const loc = babelErr.loc ?? { column: -1, line: -1 };
|
|
1329
|
+
throw makeError(`[babel parse error]: ${err.message}`, { loc: { start: loc } });
|
|
1330
|
+
}
|
|
1331
|
+
throw makeError(`[parse error]: ${String(err)}`);
|
|
1332
|
+
}
|
|
1333
|
+
// 检查解析过程中的错误(当启用 errorRecovery 时)
|
|
1334
|
+
const parseErrors = parsedCode.errors;
|
|
1335
|
+
if (parseErrors && Array.isArray(parseErrors) && parseErrors.length > 0) {
|
|
1336
|
+
const firstError = parseErrors[0];
|
|
1337
|
+
if (firstError && firstError.loc) {
|
|
1338
|
+
throw makeError(`[babel parse error]: ${firstError.message || 'Unknown parse error'}`, { loc: firstError.loc });
|
|
1339
|
+
}
|
|
1340
|
+
}
|
|
1341
|
+
const comiler = new CompileJS(parsedCode.program);
|
|
1265
1342
|
comiler.run();
|
|
1266
1343
|
return comiler.getCompileData();
|
|
1267
1344
|
}
|
|
@@ -1270,7 +1347,7 @@ function compileMCXFn(mcxCode) {
|
|
|
1270
1347
|
return compiler.getCompileData();
|
|
1271
1348
|
}
|
|
1272
1349
|
|
|
1273
|
-
var
|
|
1350
|
+
var index$2 = /*#__PURE__*/Object.freeze({
|
|
1274
1351
|
__proto__: null,
|
|
1275
1352
|
CompileError: CompileError,
|
|
1276
1353
|
CompileJS: CompileJS,
|
|
@@ -1281,1699 +1358,468 @@ var Compiler = /*#__PURE__*/Object.freeze({
|
|
|
1281
1358
|
var config = {
|
|
1282
1359
|
// script tag compile function name
|
|
1283
1360
|
scriptCompileFn: "__main",
|
|
1284
|
-
|
|
1285
|
-
|
|
1361
|
+
eventExtendsName: "McxExtendsBy",
|
|
1362
|
+
// paramName
|
|
1363
|
+
paramCtx: "__mcx__ctx"
|
|
1286
1364
|
};
|
|
1287
1365
|
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1366
|
+
let fileIdCounter = 0;
|
|
1367
|
+
function generateFileId() {
|
|
1368
|
+
return `__file_import_${fileIdCounter++}__`;
|
|
1369
|
+
}
|
|
1370
|
+
|
|
1371
|
+
function extrectVarDefIdList(express) {
|
|
1372
|
+
const result = [];
|
|
1373
|
+
if (t__namespace.isIdentifier(express))
|
|
1374
|
+
result.push(express.name);
|
|
1375
|
+
if (t__namespace.isObjectPattern(express))
|
|
1376
|
+
express.properties.forEach((prop) => {
|
|
1377
|
+
// const {xxx:xxx,xxx=Litter} = xxx
|
|
1378
|
+
if (t__namespace.isObjectProperty(prop))
|
|
1379
|
+
return result.push(...extrectVarDefIdList(prop.value));
|
|
1380
|
+
// const {...restElement} = xx (restElement in this, ,must identifier)
|
|
1381
|
+
if (t__namespace.isRestElement(prop) && prop.argument.type == "Identifier")
|
|
1382
|
+
result.push(prop.argument.name);
|
|
1383
|
+
});
|
|
1384
|
+
if (t__namespace.isArrayPattern(express)) {
|
|
1385
|
+
for (const element of express.elements) {
|
|
1386
|
+
if (!element)
|
|
1387
|
+
continue;
|
|
1388
|
+
result.push(...extrectVarDefIdList(element));
|
|
1302
1389
|
}
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1390
|
+
}
|
|
1391
|
+
if (t__namespace.isAssignmentPattern(express)) {
|
|
1392
|
+
result.push(...extrectVarDefIdList(express.left));
|
|
1393
|
+
}
|
|
1394
|
+
return result;
|
|
1395
|
+
}
|
|
1396
|
+
function extractIdList(expression) {
|
|
1397
|
+
if (t__namespace.isFunctionDeclaration(expression)) {
|
|
1398
|
+
return [expression.id?.name || ""];
|
|
1399
|
+
}
|
|
1400
|
+
if (t__namespace.isVariableDeclaration(expression)) {
|
|
1401
|
+
const result = [];
|
|
1402
|
+
for (const varDef of expression.declarations) {
|
|
1403
|
+
result.push(...extrectVarDefIdList(varDef.id));
|
|
1306
1404
|
}
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1405
|
+
return result;
|
|
1406
|
+
}
|
|
1407
|
+
if (t__namespace.isClassDeclaration(expression)) {
|
|
1408
|
+
// 'export class {}'is not vaild(error: class name is required).
|
|
1409
|
+
return [expression.id?.name || ""];
|
|
1410
|
+
}
|
|
1411
|
+
return [];
|
|
1412
|
+
}
|
|
1413
|
+
function ToExpression(s) {
|
|
1414
|
+
if (t__namespace.isFunctionDeclaration(s))
|
|
1415
|
+
return t__namespace.functionExpression(s.id, s.params, s.body, s.generator, s.async);
|
|
1416
|
+
if (t__namespace.isClassDeclaration(s))
|
|
1417
|
+
return t__namespace.classExpression(s.id, s.superClass, s.body, s.decorators);
|
|
1418
|
+
if (t__namespace.isTSDeclareFunction(s))
|
|
1419
|
+
return t__namespace.objectExpression([]);
|
|
1420
|
+
return s;
|
|
1421
|
+
}
|
|
1422
|
+
function generateMain(code) {
|
|
1423
|
+
const expBody = [];
|
|
1424
|
+
const impBody = code.BuildCache.import.map((item) => {
|
|
1425
|
+
return Utils.CacheToImportNode(item);
|
|
1426
|
+
});
|
|
1427
|
+
const codeBody = code.node.body;
|
|
1428
|
+
for (const exp of code.BuildCache.export) {
|
|
1429
|
+
if (t__namespace.isExportNamedDeclaration(exp)) {
|
|
1430
|
+
// export {xxx} from "./xxx" or export xxx from "./xxx"
|
|
1431
|
+
if (exp.source &&
|
|
1432
|
+
exp.specifiers &&
|
|
1433
|
+
exp.specifiers.length >= 1 &&
|
|
1434
|
+
exp.source.value.length >= 1) {
|
|
1435
|
+
impBody.push(t__namespace.importDeclaration(exp.specifiers.map((item) => {
|
|
1436
|
+
if (t__namespace.isExportDefaultSpecifier(item)) {
|
|
1437
|
+
expBody.push(t__namespace.objectProperty(item.exported, item.exported));
|
|
1438
|
+
return t__namespace.importDefaultSpecifier(item.exported);
|
|
1314
1439
|
}
|
|
1315
|
-
|
|
1316
|
-
|
|
1440
|
+
if (t__namespace.isExportSpecifier(item)) {
|
|
1441
|
+
expBody.push(t__namespace.objectProperty(item.exported, item.exported));
|
|
1442
|
+
return t__namespace.importSpecifier(item.local, item.exported);
|
|
1317
1443
|
}
|
|
1444
|
+
if (t__namespace.isExportNamespaceSpecifier(item)) {
|
|
1445
|
+
expBody.push(t__namespace.spreadElement(item.exported));
|
|
1446
|
+
return t__namespace.importNamespaceSpecifier(item.exported);
|
|
1447
|
+
}
|
|
1448
|
+
// 不加的话,ts就报错
|
|
1449
|
+
throw new Error("[build import]: 这也不是那也不是, 你是个登啊(ts也是galgame)");
|
|
1450
|
+
}), exp.source));
|
|
1451
|
+
}
|
|
1452
|
+
if (exp.declaration) {
|
|
1453
|
+
const idList = extractIdList(exp.declaration);
|
|
1454
|
+
// be like: const {} = {}; (worthless)
|
|
1455
|
+
if (idList.length < 1)
|
|
1318
1456
|
continue;
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1457
|
+
codeBody.push(exp.declaration);
|
|
1458
|
+
expBody.push(...idList.map((id) => {
|
|
1459
|
+
return t__namespace.objectProperty(t__namespace.identifier(id), t__namespace.identifier(id));
|
|
1460
|
+
}));
|
|
1461
|
+
}
|
|
1462
|
+
// export { xxx }
|
|
1463
|
+
if (exp.specifiers && !exp.source) {
|
|
1464
|
+
expBody.push(...exp.specifiers.map((item) => {
|
|
1465
|
+
if (!t__namespace.isExportSpecifier(item))
|
|
1466
|
+
throw new Error(`[build import]: invaild specifiers`);
|
|
1467
|
+
return t__namespace.objectProperty(item.exported, item.local);
|
|
1468
|
+
}));
|
|
1469
|
+
}
|
|
1470
|
+
// export * from "xxx"
|
|
1322
1471
|
}
|
|
1323
|
-
else if (
|
|
1324
|
-
|
|
1472
|
+
else if (t__namespace.isExportAllDeclaration(exp)) {
|
|
1473
|
+
// xxx.js => xxx_js(id)
|
|
1474
|
+
const id = generateFileId();
|
|
1475
|
+
impBody.push(t__namespace.importDeclaration([t__namespace.importNamespaceSpecifier(t__namespace.identifier(id))], exp.source));
|
|
1476
|
+
expBody.push(t__namespace.objectProperty(t__namespace.identifier(id), t__namespace.identifier(id)));
|
|
1477
|
+
// export default {} or export default function a(){}
|
|
1325
1478
|
}
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
if (node.type == "VariableDeclaration") {
|
|
1330
|
-
for (const declaration of node.declarations) {
|
|
1331
|
-
findkeyByVarId(declaration.id, result);
|
|
1332
|
-
}
|
|
1479
|
+
else if (t__namespace.isExportDefaultDeclaration(exp)) {
|
|
1480
|
+
// to expression
|
|
1481
|
+
expBody.push(t__namespace.objectProperty(t__namespace.identifier("default"), ToExpression(exp.declaration)));
|
|
1333
1482
|
}
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
const
|
|
1352
|
-
const
|
|
1353
|
-
const
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
if (
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
exportsProps.push(t__namespace.objectProperty(t__namespace.identifier(name), t__namespace.identifier(name)));
|
|
1363
|
-
});
|
|
1364
|
-
continue;
|
|
1365
|
-
}
|
|
1366
|
-
else if (exportNode.specifiers.length >= 1 && exportNode.source) {
|
|
1367
|
-
// export ... from 'mod' — import namespace into a temp id and spread it in return
|
|
1368
|
-
const id = generateTempId();
|
|
1369
|
-
importDeclarations.push(t__namespace.importDeclaration([t__namespace.importNamespaceSpecifier(t__namespace.identifier(id))], exportNode.source));
|
|
1370
|
-
exportsProps.push(t__namespace.spreadElement(t__namespace.identifier(id)));
|
|
1371
|
-
}
|
|
1372
|
-
}
|
|
1373
|
-
else if (exportNode.type == "ExportDefaultDeclaration") {
|
|
1374
|
-
if (t__namespace.isExpression(exportNode.declaration)) {
|
|
1375
|
-
exportsProps.push(t__namespace.objectProperty(t__namespace.identifier("default"), exportNode.declaration));
|
|
1376
|
-
}
|
|
1377
|
-
else {
|
|
1378
|
-
const decl = exportNode.declaration;
|
|
1379
|
-
if (decl.id && decl.id.name) {
|
|
1380
|
-
iifeBody.body.push(decl);
|
|
1381
|
-
exportsProps.push(t__namespace.objectProperty(t__namespace.identifier("default"), t__namespace.identifier(decl.id.name)));
|
|
1382
|
-
}
|
|
1383
|
-
else {
|
|
1384
|
-
exportsProps.push(t__namespace.objectProperty(t__namespace.identifier("default"), DeclarationToExpression(decl)));
|
|
1385
|
-
}
|
|
1386
|
-
}
|
|
1387
|
-
}
|
|
1388
|
-
else {
|
|
1389
|
-
const source = exportNode.source;
|
|
1390
|
-
const id = generateTempId();
|
|
1391
|
-
importDeclarations.push(t__namespace.importDeclaration([t__namespace.importNamespaceSpecifier(t__namespace.identifier(id))], source));
|
|
1392
|
-
exportsProps.push(t__namespace.spreadElement(t__namespace.identifier(id)));
|
|
1483
|
+
}
|
|
1484
|
+
return [
|
|
1485
|
+
[...codeBody, t__namespace.returnStatement(t__namespace.objectExpression(expBody))],
|
|
1486
|
+
impBody,
|
|
1487
|
+
];
|
|
1488
|
+
}
|
|
1489
|
+
async function generateEventConfig(eventTag, ctx, impBody) {
|
|
1490
|
+
const prop = ctx.compiledCode.strLoc.Event.subscribe;
|
|
1491
|
+
const argm = t__namespace.objectExpression([
|
|
1492
|
+
t__namespace.objectProperty(t__namespace.identifier("on"), t__namespace.stringLiteral(ctx.compiledCode.strLoc.Event.on))
|
|
1493
|
+
]);
|
|
1494
|
+
if (eventTag.arr.tick) {
|
|
1495
|
+
const num = parseFloat(eventTag.arr.tick);
|
|
1496
|
+
if (!Number.isNaN(num))
|
|
1497
|
+
argm.properties.push(t__namespace.objectProperty(t__namespace.identifier("tick"), t__namespace.numericLiteral(num)));
|
|
1498
|
+
}
|
|
1499
|
+
// extract event and hanler
|
|
1500
|
+
const data = [];
|
|
1501
|
+
const extend = [];
|
|
1502
|
+
for (const [name, handlerName] of Object.entries(prop)) {
|
|
1503
|
+
if (name == config.eventExtendsName) {
|
|
1504
|
+
const extendsFile = handlerName.split(",");
|
|
1505
|
+
for (const extFile of extendsFile) {
|
|
1506
|
+
if (!(await McxUtlis.FileExsit(path.join(path.dirname(ctx.currentId), extFile))))
|
|
1507
|
+
throw new Error("[transform event]: can't resolve");
|
|
1508
|
+
const id = generateFileId();
|
|
1509
|
+
impBody.push(t__namespace.importDeclaration([t__namespace.importDefaultSpecifier(t__namespace.identifier(id))], t__namespace.stringLiteral(extFile)));
|
|
1510
|
+
extend.push(t__namespace.identifier(id));
|
|
1393
1511
|
}
|
|
1394
1512
|
}
|
|
1513
|
+
data.push(t__namespace.objectProperty(t__namespace.identifier(name), t__namespace.stringLiteral(handlerName)));
|
|
1395
1514
|
}
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1515
|
+
argm.properties.push(t__namespace.objectProperty(t__namespace.identifier("data"), t__namespace.objectExpression(data)), t__namespace.objectProperty(t__namespace.identifier("extends"), t__namespace.arrayExpression(extend)));
|
|
1516
|
+
return argm;
|
|
1517
|
+
}
|
|
1518
|
+
/**
|
|
1519
|
+
* record enable
|
|
1520
|
+
* @returns {(): void} - only call one
|
|
1521
|
+
*/
|
|
1522
|
+
function _enable() {
|
|
1523
|
+
let success = false;
|
|
1524
|
+
const fn = function () {
|
|
1525
|
+
if (success)
|
|
1526
|
+
throw new Error("[enable]: can't enable again");
|
|
1527
|
+
success = true;
|
|
1528
|
+
fn.prototype.enable = success;
|
|
1529
|
+
};
|
|
1530
|
+
fn.prototype.enable = success;
|
|
1531
|
+
return fn;
|
|
1401
1532
|
}
|
|
1402
|
-
function
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1533
|
+
function _enableWithData() {
|
|
1534
|
+
let d = null;
|
|
1535
|
+
const fn = function (data) {
|
|
1536
|
+
if (d)
|
|
1537
|
+
throw new Error("[enable]: can't enable again");
|
|
1538
|
+
d = data;
|
|
1539
|
+
fn.prototype.enable = d;
|
|
1540
|
+
};
|
|
1541
|
+
fn.prototype.enable = d;
|
|
1542
|
+
return fn;
|
|
1408
1543
|
}
|
|
1409
1544
|
|
|
1410
|
-
function
|
|
1411
|
-
const
|
|
1412
|
-
|
|
1413
|
-
|
|
1545
|
+
async function Comp$2(ctx) {
|
|
1546
|
+
const internalCtx = ctx.ctx;
|
|
1547
|
+
ctx.impBody.push(t__namespace.importDeclaration([t__namespace.importSpecifier(t__namespace.identifier("__mcx_ui"), t__namespace.identifier("ui"))], t__namespace.stringLiteral("@mbler/mcx")), t__namespace.importDeclaration([
|
|
1548
|
+
t__namespace.importNamespaceSpecifier(t__namespace.identifier("__minecraft__ui"))
|
|
1549
|
+
], t__namespace.stringLiteral("@minecraft/server-ui")));
|
|
1550
|
+
const uiTagNode = ctx.ctx.compiledCode.strLoc.UI;
|
|
1551
|
+
if (!uiTagNode || uiTagNode?.name !== "Ui")
|
|
1552
|
+
throw new Error("[UI Component]: why didn't parent compeled verify?");
|
|
1553
|
+
let MCXUIType = null;
|
|
1554
|
+
const UITree = [];
|
|
1555
|
+
for (const uiClientTag of uiTagNode.content) {
|
|
1556
|
+
if (uiClientTag.type == "TagNode") {
|
|
1557
|
+
// if has client TagNode
|
|
1558
|
+
if (uiClientTag.content.some(i => i.type == "TagNode")) {
|
|
1559
|
+
internalCtx.rollupContext.error("[UI]: can't support ui client element", uiClientTag.loc ? {
|
|
1560
|
+
column: uiClientTag.loc.start.column,
|
|
1561
|
+
line: uiClientTag.loc.start.line
|
|
1562
|
+
} : void 0);
|
|
1563
|
+
}
|
|
1564
|
+
// add to tree
|
|
1565
|
+
UITree.push({
|
|
1566
|
+
arr: uiClientTag.arr,
|
|
1567
|
+
content: uiClientTag.content.map(i => i.type == "TagContent" && i.data || "").join(""),
|
|
1568
|
+
type: uiClientTag.name,
|
|
1569
|
+
loc: uiClientTag.loc
|
|
1570
|
+
});
|
|
1571
|
+
}
|
|
1572
|
+
// continue TagContentNode
|
|
1573
|
+
}
|
|
1574
|
+
const parsedObj = [];
|
|
1575
|
+
function pushToTree(name, params, content) {
|
|
1576
|
+
parsedObj.push(t__namespace.objectExpression([
|
|
1577
|
+
t__namespace.objectProperty(t__namespace.identifier("type"), t__namespace.stringLiteral(name)),
|
|
1578
|
+
t__namespace.objectProperty(t__namespace.identifier("params"), t__namespace.objectExpression(Object.entries(params).map(i => {
|
|
1579
|
+
return t__namespace.objectProperty(t__namespace.identifier(i[0]), typeof i[1] == "boolean" ? t__namespace.booleanLiteral(i[1]) : t__namespace.stringLiteral(i[1]));
|
|
1580
|
+
}))),
|
|
1581
|
+
t__namespace.objectProperty(t__namespace.identifier("content"), (content.startsWith("{{ ") && content.endsWith(" }}")) ? t__namespace.objectExpression([
|
|
1582
|
+
t__namespace.objectProperty(t__namespace.identifier("useProp"), t__namespace.stringLiteral(content.slice(3, content.length - 3).trim()))
|
|
1583
|
+
]) : t__namespace.stringLiteral(content))
|
|
1584
|
+
]));
|
|
1585
|
+
}
|
|
1586
|
+
// generate type and parsed tree
|
|
1587
|
+
for (const tp of UITree) {
|
|
1588
|
+
const name = tp.type;
|
|
1589
|
+
// only ModalFormData Element
|
|
1590
|
+
if (["input", "dropdown", "submit", "toggle", "slider"].includes(name)) {
|
|
1591
|
+
// ModalFromData
|
|
1592
|
+
if (MCXUIType && MCXUIType !== "ModalFormData") {
|
|
1593
|
+
internalCtx.rollupContext.error("[UI]: a mcx can't have a ModalFormData Node and other form tag", tp.loc ? {
|
|
1594
|
+
line: tp.loc.start.line,
|
|
1595
|
+
column: tp.loc.start.column
|
|
1596
|
+
} : void 0);
|
|
1597
|
+
}
|
|
1598
|
+
MCXUIType = "ModalFormData";
|
|
1599
|
+
pushToTree(name, tp.arr, tp.content);
|
|
1600
|
+
}
|
|
1601
|
+
// only MessageFormData Element
|
|
1602
|
+
else if (["button-m"].includes(name)) {
|
|
1603
|
+
if (MCXUIType && MCXUIType !== "MessageFormData") {
|
|
1604
|
+
internalCtx.rollupContext.error("[UI]: ", tp.loc ? {
|
|
1605
|
+
line: tp.loc.start.line,
|
|
1606
|
+
column: tp.loc.start.column
|
|
1607
|
+
} : void 0);
|
|
1608
|
+
}
|
|
1609
|
+
MCXUIType = "MessageFormData";
|
|
1610
|
+
pushToTree(name, tp.arr, tp.content);
|
|
1611
|
+
}
|
|
1612
|
+
// public
|
|
1613
|
+
else if (["body", "divider", "title", "label"].includes(name)) {
|
|
1614
|
+
pushToTree(name, tp.arr, tp.content);
|
|
1615
|
+
}
|
|
1616
|
+
else if (name == "button") {
|
|
1617
|
+
if (MCXUIType !== "ActionFromData" && MCXUIType)
|
|
1618
|
+
internalCtx.rollupContext.error("[UI]: don't support use button for messageFormData", tp.loc ? {
|
|
1619
|
+
line: tp.loc.start.line,
|
|
1620
|
+
column: tp.loc.start.column
|
|
1621
|
+
} : void 0);
|
|
1622
|
+
pushToTree(name, tp.arr, tp.content);
|
|
1623
|
+
MCXUIType = "ActionFromData";
|
|
1624
|
+
}
|
|
1625
|
+
else {
|
|
1626
|
+
internalCtx.rollupContext.error("[UI]: don't support tag: " + name, tp.loc ? {
|
|
1627
|
+
line: tp.loc.start.line,
|
|
1628
|
+
column: tp.loc.start.column
|
|
1629
|
+
} : void 0);
|
|
1630
|
+
}
|
|
1414
1631
|
}
|
|
1415
|
-
|
|
1632
|
+
if (!MCXUIType)
|
|
1633
|
+
MCXUIType = "ActionFromData";
|
|
1634
|
+
const finallyData = t__namespace.objectExpression([
|
|
1635
|
+
t__namespace.objectProperty(t__namespace.identifier("layout"), t__namespace.arrayExpression(parsedObj)),
|
|
1636
|
+
t__namespace.objectProperty(t__namespace.identifier("use"), t__namespace.memberExpression(t__namespace.identifier("__minecraft__ui"), t__namespace.identifier(MCXUIType))),
|
|
1637
|
+
t__namespace.objectProperty(t__namespace.identifier("_UI"), t__namespace.identifier("__minecraft__ui"))
|
|
1638
|
+
]);
|
|
1639
|
+
ctx.app([
|
|
1640
|
+
t__namespace.objectProperty(t__namespace.identifier("ui"), t__namespace.newExpression(t__namespace.identifier("__mcx__ui"), [finallyData, t__namespace.identifier(config.scriptCompileFn)]))
|
|
1641
|
+
]);
|
|
1416
1642
|
}
|
|
1417
|
-
|
|
1418
|
-
async function
|
|
1419
|
-
const
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
line: 1
|
|
1424
|
-
});
|
|
1425
|
-
}
|
|
1426
|
-
cache$1.set(opt, true);
|
|
1427
|
-
const projectDir = path.dirname(opt.ProjectDir);
|
|
1428
|
-
for (const jsonKey in component) {
|
|
1429
|
-
handlerPath(jsonKey, projectDir);
|
|
1430
|
-
component[jsonKey];
|
|
1431
|
-
}
|
|
1643
|
+
|
|
1644
|
+
async function Comp$1(ctx) {
|
|
1645
|
+
const appData = [
|
|
1646
|
+
t__namespace.objectProperty(t__namespace.identifier("event"), await generateEventConfig(ctx.ctx.compiledCode.raw.find((node) => node.name === "Event"), ctx.ctx, ctx.impBody)),
|
|
1647
|
+
];
|
|
1648
|
+
ctx.app(appData);
|
|
1432
1649
|
}
|
|
1433
1650
|
|
|
1434
|
-
async function
|
|
1435
|
-
const
|
|
1436
|
-
const
|
|
1437
|
-
|
|
1438
|
-
|
|
1651
|
+
async function Comp(ctx) {
|
|
1652
|
+
const eventImportIdList = [];
|
|
1653
|
+
for (const impNode of ctx.ctx.compiledCode.JSIR.BuildCache.import) {
|
|
1654
|
+
const source = impNode.source;
|
|
1655
|
+
const parsed = path.parse(source);
|
|
1656
|
+
if (!parsed.root && !parsed.dir.startsWith(".")) {
|
|
1439
1657
|
continue;
|
|
1440
1658
|
}
|
|
1441
|
-
//
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1659
|
+
// path
|
|
1660
|
+
const fPath = path.join(ctx.ctx.currentId, "../", source);
|
|
1661
|
+
try {
|
|
1662
|
+
// read file
|
|
1663
|
+
const code = await fs.readFile(fPath, "utf-8");
|
|
1664
|
+
const compiledCode = compileMCXFn(code);
|
|
1665
|
+
// write cache
|
|
1666
|
+
ctx.ctx.cache.set(fPath, compiledCode);
|
|
1667
|
+
if (compiledCode.strLoc.Event.isLoad) {
|
|
1668
|
+
for (const impItem of impNode.imported) {
|
|
1669
|
+
let type;
|
|
1670
|
+
if (impItem.isAll)
|
|
1671
|
+
type = "all";
|
|
1672
|
+
else if (impItem.import == "default")
|
|
1673
|
+
type = "default";
|
|
1674
|
+
else {
|
|
1675
|
+
throw new Error("not vaild importDeclartion: Event mcx only resolve default and all import, can't use other import");
|
|
1676
|
+
}
|
|
1677
|
+
eventImportIdList.push({
|
|
1678
|
+
type,
|
|
1679
|
+
as: impItem.as
|
|
1680
|
+
});
|
|
1681
|
+
}
|
|
1456
1682
|
}
|
|
1457
1683
|
}
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
const extendArr = [];
|
|
1462
|
-
if (!imp)
|
|
1463
|
-
return;
|
|
1464
|
-
for (const pkg of imp.split(",")) {
|
|
1465
|
-
const pkgTrim = pkg.trim();
|
|
1466
|
-
const pkgDir = path.join(path.dirname(id), pkgTrim);
|
|
1467
|
-
let st;
|
|
1468
|
-
try {
|
|
1469
|
-
st = await fs.stat(pkgDir);
|
|
1470
|
-
if (!st.isFile())
|
|
1471
|
-
throw new Error("Not File");
|
|
1472
|
-
}
|
|
1473
|
-
catch (err) {
|
|
1474
|
-
context.error(`[event node]: extends ${pkg} error: ${err.message} code: ${err.code} file: ${id}`);
|
|
1475
|
-
}
|
|
1476
|
-
const impId = generateTempId();
|
|
1477
|
-
body.unshift(t__namespace.importDeclaration([t__namespace.importDefaultSpecifier(t__namespace.identifier(impId))], t__namespace.stringLiteral(pkgTrim)));
|
|
1478
|
-
extendArr.push(t__namespace.identifier(impId));
|
|
1684
|
+
catch (err) {
|
|
1685
|
+
// if error: file not found, file can't write, mcx syntax error
|
|
1686
|
+
ctx.ctx.rollupContext.warn(`[extract import]: can't resolve file ${fPath} and import by ${ctx.ctx.currentId}\n- err: ${(err instanceof Error) ? err.stack : err}`);
|
|
1479
1687
|
}
|
|
1480
|
-
armg.properties.push(t__namespace.objectProperty(t__namespace.identifier("extends"), t__namespace.arrayExpression(extendArr)));
|
|
1481
1688
|
}
|
|
1482
|
-
//
|
|
1483
|
-
|
|
1484
|
-
t__namespace.
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
throw new Error("[compile component]: a mcx must event or component, can't both");
|
|
1505
|
-
// leave placeholder for component compilation
|
|
1506
|
-
await compileComponent(compileData, opt);
|
|
1507
|
-
// export a MCXFile-like default for components
|
|
1508
|
-
const defObj = t__namespace.objectExpression([
|
|
1509
|
-
t__namespace.objectProperty(t__namespace.identifier("type"), t__namespace.stringLiteral("component")),
|
|
1510
|
-
t__namespace.objectProperty(t__namespace.identifier("setup"), t__namespace.identifier(config.scriptCompileFn)),
|
|
1511
|
-
]);
|
|
1512
|
-
statement.push(t__namespace.exportDefaultDeclaration(defObj));
|
|
1513
|
-
return generator__namespace.generate(t__namespace.program(statement)).code;
|
|
1514
|
-
}
|
|
1515
|
-
// app (default) MCX
|
|
1516
|
-
if (!mcxtype) {
|
|
1517
|
-
mcxtype = "app";
|
|
1518
|
-
for (const imp of compileData.JSIR.BuildCache.import || []) {
|
|
1519
|
-
if (path.parse(imp.source).dir == "")
|
|
1520
|
-
continue;
|
|
1521
|
-
const source = path.join(path.dirname(id), imp.source);
|
|
1522
|
-
if (!source.endsWith(".mcx"))
|
|
1523
|
-
continue;
|
|
1524
|
-
// generate code;
|
|
1525
|
-
let moduleData;
|
|
1526
|
-
if (cache.has(source)) {
|
|
1527
|
-
moduleData = cache.get(source);
|
|
1528
|
-
}
|
|
1529
|
-
else {
|
|
1530
|
-
let code;
|
|
1531
|
-
try {
|
|
1532
|
-
code = await fs.readFile(source, "utf-8");
|
|
1689
|
+
// only have event import
|
|
1690
|
+
if (eventImportIdList.length >= 1) {
|
|
1691
|
+
const eventMemberNode = t__namespace.memberExpression(t__namespace.identifier(config.paramCtx), t__namespace.identifier("event"));
|
|
1692
|
+
ctx.mainFn.unshift(
|
|
1693
|
+
// add declaration
|
|
1694
|
+
t__namespace.variableDeclaration("var", eventImportIdList.map((item, index) => {
|
|
1695
|
+
if (item.type == "all") {
|
|
1696
|
+
return t__namespace.variableDeclarator(t__namespace.identifier(item.as), t__namespace.objectExpression([
|
|
1697
|
+
t__namespace.objectProperty(t__namespace.identifier("default"), t__namespace.memberExpression(eventMemberNode, t__namespace.numericLiteral(index), true)),
|
|
1698
|
+
]));
|
|
1699
|
+
}
|
|
1700
|
+
else if (item.type == "default") {
|
|
1701
|
+
return t__namespace.variableDeclarator(t__namespace.identifier(item.as), t__namespace.memberExpression(eventMemberNode, t__namespace.numericLiteral(index), true));
|
|
1702
|
+
}
|
|
1703
|
+
// ts galgame
|
|
1704
|
+
throw new Error("[javascript error]: why it not in [default, all]");
|
|
1705
|
+
})));
|
|
1706
|
+
// app: add event export to runtime framework
|
|
1707
|
+
const appData = [
|
|
1708
|
+
t__namespace.objectProperty(t__namespace.identifier("event"), t__namespace.arrayExpression(eventImportIdList.map(vl => {
|
|
1709
|
+
if (vl.type == "all") {
|
|
1710
|
+
return t__namespace.memberExpression(t__namespace.identifier(vl.as), t__namespace.identifier("default"));
|
|
1533
1711
|
}
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
continue;
|
|
1712
|
+
else if (vl.type == "default") {
|
|
1713
|
+
return t__namespace.identifier(vl.as);
|
|
1537
1714
|
}
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
for (const item of imp.imported) {
|
|
1544
|
-
const base = t__namespace.identifier(item.as);
|
|
1545
|
-
if (item.isAll)
|
|
1546
|
-
eventImportIds.push(t__namespace.memberExpression(base, t__namespace.identifier("default")));
|
|
1547
|
-
else if (item.import == "default")
|
|
1548
|
-
eventImportIds.push(base, t__namespace.identifier("event"));
|
|
1549
|
-
}
|
|
1550
|
-
}
|
|
1551
|
-
}
|
|
1552
|
-
// Default export properties. `setup` references the compiled script wrapper
|
|
1553
|
-
// function (callable as `setup(ctx)`) which returns the exported bindings
|
|
1554
|
-
// object (e.g. `{ default: Handler }`). Event handler references in the
|
|
1555
|
-
// compiled event config are string names that the runtime will resolve by
|
|
1556
|
-
// calling `setup()` and looking up the named export.
|
|
1557
|
-
const props = [
|
|
1558
|
-
t__namespace.objectProperty(t__namespace.identifier("type"), t__namespace.stringLiteral(mcxtype)),
|
|
1559
|
-
t__namespace.objectProperty(t__namespace.identifier("setup"), t__namespace.identifier(config.scriptCompileFn)),
|
|
1560
|
-
];
|
|
1561
|
-
// if this app imports an event mcx, attach it under `event` property
|
|
1562
|
-
if (mcxtype === "app" && eventImportIds.length > 0) {
|
|
1563
|
-
// prefer first discovered event import id
|
|
1564
|
-
if (eventImportIds.length > 1) {
|
|
1565
|
-
context.warn(`multiple event MCX imports detected in ${id}. Only the first will be attached to the app export.`);
|
|
1566
|
-
}
|
|
1567
|
-
props.push(t__namespace.objectProperty(t__namespace.identifier("app"), t__namespace.objectExpression([
|
|
1568
|
-
t__namespace.objectProperty(t__namespace.identifier("event"), eventImportIds[0]),
|
|
1569
|
-
])));
|
|
1570
|
-
for (const statIndex in statement) {
|
|
1571
|
-
const stat = statement[statIndex];
|
|
1572
|
-
if (!stat)
|
|
1573
|
-
continue;
|
|
1574
|
-
console.log(stat);
|
|
1575
|
-
if (stat.type == "FunctionDeclaration" && stat.id && stat.id.name == config.scriptCompileFn) {
|
|
1576
|
-
console.log("into");
|
|
1577
|
-
stat.params[0] =
|
|
1578
|
-
eventImportIds[0] && eventImportIds[0].type == "Identifier"
|
|
1579
|
-
? eventImportIds[0]
|
|
1580
|
-
: eventImportIds[0]?.object;
|
|
1581
|
-
}
|
|
1582
|
-
}
|
|
1583
|
-
}
|
|
1584
|
-
// if this is an event mcx we still need to provide named export 'event'
|
|
1585
|
-
if (mcxtype === "event") {
|
|
1586
|
-
// ensure default export still includes type and setup
|
|
1587
|
-
props.push(t__namespace.objectProperty(t__namespace.identifier("event"), t__namespace.identifier(config.eventVarName)));
|
|
1588
|
-
const defObj = t__namespace.objectExpression(props);
|
|
1589
|
-
statement.push(t__namespace.exportDefaultDeclaration(defObj));
|
|
1590
|
-
return generator__namespace.generate(t__namespace.program(statement)).code;
|
|
1591
|
-
}
|
|
1592
|
-
// normal app default export
|
|
1593
|
-
const defObj = t__namespace.objectExpression(props);
|
|
1594
|
-
statement.push(t__namespace.exportDefaultDeclaration(defObj));
|
|
1595
|
-
return generator__namespace.generate(t__namespace.program(statement)).code;
|
|
1596
|
-
}
|
|
1597
|
-
|
|
1598
|
-
// src/vlq.ts
|
|
1599
|
-
var comma = ",".charCodeAt(0);
|
|
1600
|
-
var semicolon = ";".charCodeAt(0);
|
|
1601
|
-
var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
1602
|
-
var intToChar = new Uint8Array(64);
|
|
1603
|
-
var charToInt = new Uint8Array(128);
|
|
1604
|
-
for (let i = 0; i < chars.length; i++) {
|
|
1605
|
-
const c = chars.charCodeAt(i);
|
|
1606
|
-
intToChar[i] = c;
|
|
1607
|
-
charToInt[c] = i;
|
|
1608
|
-
}
|
|
1609
|
-
function encodeInteger(builder, num, relative) {
|
|
1610
|
-
let delta = num - relative;
|
|
1611
|
-
delta = delta < 0 ? -delta << 1 | 1 : delta << 1;
|
|
1612
|
-
do {
|
|
1613
|
-
let clamped = delta & 31;
|
|
1614
|
-
delta >>>= 5;
|
|
1615
|
-
if (delta > 0) clamped |= 32;
|
|
1616
|
-
builder.write(intToChar[clamped]);
|
|
1617
|
-
} while (delta > 0);
|
|
1618
|
-
return num;
|
|
1619
|
-
}
|
|
1620
|
-
|
|
1621
|
-
// src/strings.ts
|
|
1622
|
-
var bufLength = 1024 * 16;
|
|
1623
|
-
var td = typeof TextDecoder !== "undefined" ? /* @__PURE__ */ new TextDecoder() : typeof Buffer !== "undefined" ? {
|
|
1624
|
-
decode(buf) {
|
|
1625
|
-
const out = Buffer.from(buf.buffer, buf.byteOffset, buf.byteLength);
|
|
1626
|
-
return out.toString();
|
|
1627
|
-
}
|
|
1628
|
-
} : {
|
|
1629
|
-
decode(buf) {
|
|
1630
|
-
let out = "";
|
|
1631
|
-
for (let i = 0; i < buf.length; i++) {
|
|
1632
|
-
out += String.fromCharCode(buf[i]);
|
|
1633
|
-
}
|
|
1634
|
-
return out;
|
|
1635
|
-
}
|
|
1636
|
-
};
|
|
1637
|
-
var StringWriter = class {
|
|
1638
|
-
constructor() {
|
|
1639
|
-
this.pos = 0;
|
|
1640
|
-
this.out = "";
|
|
1641
|
-
this.buffer = new Uint8Array(bufLength);
|
|
1642
|
-
}
|
|
1643
|
-
write(v) {
|
|
1644
|
-
const { buffer } = this;
|
|
1645
|
-
buffer[this.pos++] = v;
|
|
1646
|
-
if (this.pos === bufLength) {
|
|
1647
|
-
this.out += td.decode(buffer);
|
|
1648
|
-
this.pos = 0;
|
|
1649
|
-
}
|
|
1650
|
-
}
|
|
1651
|
-
flush() {
|
|
1652
|
-
const { buffer, out, pos } = this;
|
|
1653
|
-
return pos > 0 ? out + td.decode(buffer.subarray(0, pos)) : out;
|
|
1654
|
-
}
|
|
1655
|
-
};
|
|
1656
|
-
function encode(decoded) {
|
|
1657
|
-
const writer = new StringWriter();
|
|
1658
|
-
let sourcesIndex = 0;
|
|
1659
|
-
let sourceLine = 0;
|
|
1660
|
-
let sourceColumn = 0;
|
|
1661
|
-
let namesIndex = 0;
|
|
1662
|
-
for (let i = 0; i < decoded.length; i++) {
|
|
1663
|
-
const line = decoded[i];
|
|
1664
|
-
if (i > 0) writer.write(semicolon);
|
|
1665
|
-
if (line.length === 0) continue;
|
|
1666
|
-
let genColumn = 0;
|
|
1667
|
-
for (let j = 0; j < line.length; j++) {
|
|
1668
|
-
const segment = line[j];
|
|
1669
|
-
if (j > 0) writer.write(comma);
|
|
1670
|
-
genColumn = encodeInteger(writer, segment[0], genColumn);
|
|
1671
|
-
if (segment.length === 1) continue;
|
|
1672
|
-
sourcesIndex = encodeInteger(writer, segment[1], sourcesIndex);
|
|
1673
|
-
sourceLine = encodeInteger(writer, segment[2], sourceLine);
|
|
1674
|
-
sourceColumn = encodeInteger(writer, segment[3], sourceColumn);
|
|
1675
|
-
if (segment.length === 4) continue;
|
|
1676
|
-
namesIndex = encodeInteger(writer, segment[4], namesIndex);
|
|
1677
|
-
}
|
|
1678
|
-
}
|
|
1679
|
-
return writer.flush();
|
|
1680
|
-
}
|
|
1681
|
-
|
|
1682
|
-
class BitSet {
|
|
1683
|
-
constructor(arg) {
|
|
1684
|
-
this.bits = arg instanceof BitSet ? arg.bits.slice() : [];
|
|
1685
|
-
}
|
|
1686
|
-
|
|
1687
|
-
add(n) {
|
|
1688
|
-
this.bits[n >> 5] |= 1 << (n & 31);
|
|
1689
|
-
}
|
|
1690
|
-
|
|
1691
|
-
has(n) {
|
|
1692
|
-
return !!(this.bits[n >> 5] & (1 << (n & 31)));
|
|
1693
|
-
}
|
|
1694
|
-
}
|
|
1695
|
-
|
|
1696
|
-
class Chunk {
|
|
1697
|
-
constructor(start, end, content) {
|
|
1698
|
-
this.start = start;
|
|
1699
|
-
this.end = end;
|
|
1700
|
-
this.original = content;
|
|
1701
|
-
|
|
1702
|
-
this.intro = '';
|
|
1703
|
-
this.outro = '';
|
|
1704
|
-
|
|
1705
|
-
this.content = content;
|
|
1706
|
-
this.storeName = false;
|
|
1707
|
-
this.edited = false;
|
|
1708
|
-
|
|
1709
|
-
{
|
|
1710
|
-
this.previous = null;
|
|
1711
|
-
this.next = null;
|
|
1712
|
-
}
|
|
1713
|
-
}
|
|
1714
|
-
|
|
1715
|
-
appendLeft(content) {
|
|
1716
|
-
this.outro += content;
|
|
1717
|
-
}
|
|
1718
|
-
|
|
1719
|
-
appendRight(content) {
|
|
1720
|
-
this.intro = this.intro + content;
|
|
1721
|
-
}
|
|
1722
|
-
|
|
1723
|
-
clone() {
|
|
1724
|
-
const chunk = new Chunk(this.start, this.end, this.original);
|
|
1725
|
-
|
|
1726
|
-
chunk.intro = this.intro;
|
|
1727
|
-
chunk.outro = this.outro;
|
|
1728
|
-
chunk.content = this.content;
|
|
1729
|
-
chunk.storeName = this.storeName;
|
|
1730
|
-
chunk.edited = this.edited;
|
|
1731
|
-
|
|
1732
|
-
return chunk;
|
|
1733
|
-
}
|
|
1734
|
-
|
|
1735
|
-
contains(index) {
|
|
1736
|
-
return this.start < index && index < this.end;
|
|
1737
|
-
}
|
|
1738
|
-
|
|
1739
|
-
eachNext(fn) {
|
|
1740
|
-
let chunk = this;
|
|
1741
|
-
while (chunk) {
|
|
1742
|
-
fn(chunk);
|
|
1743
|
-
chunk = chunk.next;
|
|
1744
|
-
}
|
|
1745
|
-
}
|
|
1746
|
-
|
|
1747
|
-
eachPrevious(fn) {
|
|
1748
|
-
let chunk = this;
|
|
1749
|
-
while (chunk) {
|
|
1750
|
-
fn(chunk);
|
|
1751
|
-
chunk = chunk.previous;
|
|
1752
|
-
}
|
|
1753
|
-
}
|
|
1754
|
-
|
|
1755
|
-
edit(content, storeName, contentOnly) {
|
|
1756
|
-
this.content = content;
|
|
1757
|
-
if (!contentOnly) {
|
|
1758
|
-
this.intro = '';
|
|
1759
|
-
this.outro = '';
|
|
1760
|
-
}
|
|
1761
|
-
this.storeName = storeName;
|
|
1762
|
-
|
|
1763
|
-
this.edited = true;
|
|
1764
|
-
|
|
1765
|
-
return this;
|
|
1766
|
-
}
|
|
1767
|
-
|
|
1768
|
-
prependLeft(content) {
|
|
1769
|
-
this.outro = content + this.outro;
|
|
1770
|
-
}
|
|
1771
|
-
|
|
1772
|
-
prependRight(content) {
|
|
1773
|
-
this.intro = content + this.intro;
|
|
1774
|
-
}
|
|
1775
|
-
|
|
1776
|
-
reset() {
|
|
1777
|
-
this.intro = '';
|
|
1778
|
-
this.outro = '';
|
|
1779
|
-
if (this.edited) {
|
|
1780
|
-
this.content = this.original;
|
|
1781
|
-
this.storeName = false;
|
|
1782
|
-
this.edited = false;
|
|
1783
|
-
}
|
|
1784
|
-
}
|
|
1785
|
-
|
|
1786
|
-
split(index) {
|
|
1787
|
-
const sliceIndex = index - this.start;
|
|
1788
|
-
|
|
1789
|
-
const originalBefore = this.original.slice(0, sliceIndex);
|
|
1790
|
-
const originalAfter = this.original.slice(sliceIndex);
|
|
1791
|
-
|
|
1792
|
-
this.original = originalBefore;
|
|
1793
|
-
|
|
1794
|
-
const newChunk = new Chunk(index, this.end, originalAfter);
|
|
1795
|
-
newChunk.outro = this.outro;
|
|
1796
|
-
this.outro = '';
|
|
1797
|
-
|
|
1798
|
-
this.end = index;
|
|
1799
|
-
|
|
1800
|
-
if (this.edited) {
|
|
1801
|
-
// after split we should save the edit content record into the correct chunk
|
|
1802
|
-
// to make sure sourcemap correct
|
|
1803
|
-
// For example:
|
|
1804
|
-
// ' test'.trim()
|
|
1805
|
-
// split -> ' ' + 'test'
|
|
1806
|
-
// ✔️ edit -> '' + 'test'
|
|
1807
|
-
// ✖️ edit -> 'test' + ''
|
|
1808
|
-
// TODO is this block necessary?...
|
|
1809
|
-
newChunk.edit('', false);
|
|
1810
|
-
this.content = '';
|
|
1811
|
-
} else {
|
|
1812
|
-
this.content = originalBefore;
|
|
1813
|
-
}
|
|
1814
|
-
|
|
1815
|
-
newChunk.next = this.next;
|
|
1816
|
-
if (newChunk.next) newChunk.next.previous = newChunk;
|
|
1817
|
-
newChunk.previous = this;
|
|
1818
|
-
this.next = newChunk;
|
|
1819
|
-
|
|
1820
|
-
return newChunk;
|
|
1821
|
-
}
|
|
1822
|
-
|
|
1823
|
-
toString() {
|
|
1824
|
-
return this.intro + this.content + this.outro;
|
|
1825
|
-
}
|
|
1826
|
-
|
|
1827
|
-
trimEnd(rx) {
|
|
1828
|
-
this.outro = this.outro.replace(rx, '');
|
|
1829
|
-
if (this.outro.length) return true;
|
|
1830
|
-
|
|
1831
|
-
const trimmed = this.content.replace(rx, '');
|
|
1832
|
-
|
|
1833
|
-
if (trimmed.length) {
|
|
1834
|
-
if (trimmed !== this.content) {
|
|
1835
|
-
this.split(this.start + trimmed.length).edit('', undefined, true);
|
|
1836
|
-
if (this.edited) {
|
|
1837
|
-
// save the change, if it has been edited
|
|
1838
|
-
this.edit(trimmed, this.storeName, true);
|
|
1839
|
-
}
|
|
1840
|
-
}
|
|
1841
|
-
return true;
|
|
1842
|
-
} else {
|
|
1843
|
-
this.edit('', undefined, true);
|
|
1844
|
-
|
|
1845
|
-
this.intro = this.intro.replace(rx, '');
|
|
1846
|
-
if (this.intro.length) return true;
|
|
1847
|
-
}
|
|
1848
|
-
}
|
|
1849
|
-
|
|
1850
|
-
trimStart(rx) {
|
|
1851
|
-
this.intro = this.intro.replace(rx, '');
|
|
1852
|
-
if (this.intro.length) return true;
|
|
1853
|
-
|
|
1854
|
-
const trimmed = this.content.replace(rx, '');
|
|
1855
|
-
|
|
1856
|
-
if (trimmed.length) {
|
|
1857
|
-
if (trimmed !== this.content) {
|
|
1858
|
-
const newChunk = this.split(this.end - trimmed.length);
|
|
1859
|
-
if (this.edited) {
|
|
1860
|
-
// save the change, if it has been edited
|
|
1861
|
-
newChunk.edit(trimmed, this.storeName, true);
|
|
1862
|
-
}
|
|
1863
|
-
this.edit('', undefined, true);
|
|
1864
|
-
}
|
|
1865
|
-
return true;
|
|
1866
|
-
} else {
|
|
1867
|
-
this.edit('', undefined, true);
|
|
1868
|
-
|
|
1869
|
-
this.outro = this.outro.replace(rx, '');
|
|
1870
|
-
if (this.outro.length) return true;
|
|
1871
|
-
}
|
|
1872
|
-
}
|
|
1873
|
-
}
|
|
1874
|
-
|
|
1875
|
-
function getBtoa() {
|
|
1876
|
-
if (typeof globalThis !== 'undefined' && typeof globalThis.btoa === 'function') {
|
|
1877
|
-
return (str) => globalThis.btoa(unescape(encodeURIComponent(str)));
|
|
1878
|
-
} else if (typeof Buffer === 'function') {
|
|
1879
|
-
return (str) => Buffer.from(str, 'utf-8').toString('base64');
|
|
1880
|
-
} else {
|
|
1881
|
-
return () => {
|
|
1882
|
-
throw new Error('Unsupported environment: `window.btoa` or `Buffer` should be supported.');
|
|
1883
|
-
};
|
|
1884
|
-
}
|
|
1885
|
-
}
|
|
1886
|
-
|
|
1887
|
-
const btoa = /*#__PURE__*/ getBtoa();
|
|
1888
|
-
|
|
1889
|
-
class SourceMap {
|
|
1890
|
-
constructor(properties) {
|
|
1891
|
-
this.version = 3;
|
|
1892
|
-
this.file = properties.file;
|
|
1893
|
-
this.sources = properties.sources;
|
|
1894
|
-
this.sourcesContent = properties.sourcesContent;
|
|
1895
|
-
this.names = properties.names;
|
|
1896
|
-
this.mappings = encode(properties.mappings);
|
|
1897
|
-
if (typeof properties.x_google_ignoreList !== 'undefined') {
|
|
1898
|
-
this.x_google_ignoreList = properties.x_google_ignoreList;
|
|
1899
|
-
}
|
|
1900
|
-
if (typeof properties.debugId !== 'undefined') {
|
|
1901
|
-
this.debugId = properties.debugId;
|
|
1902
|
-
}
|
|
1903
|
-
}
|
|
1904
|
-
|
|
1905
|
-
toString() {
|
|
1906
|
-
return JSON.stringify(this);
|
|
1907
|
-
}
|
|
1908
|
-
|
|
1909
|
-
toUrl() {
|
|
1910
|
-
return 'data:application/json;charset=utf-8;base64,' + btoa(this.toString());
|
|
1911
|
-
}
|
|
1912
|
-
}
|
|
1913
|
-
|
|
1914
|
-
function guessIndent(code) {
|
|
1915
|
-
const lines = code.split('\n');
|
|
1916
|
-
|
|
1917
|
-
const tabbed = lines.filter((line) => /^\t+/.test(line));
|
|
1918
|
-
const spaced = lines.filter((line) => /^ {2,}/.test(line));
|
|
1919
|
-
|
|
1920
|
-
if (tabbed.length === 0 && spaced.length === 0) {
|
|
1921
|
-
return null;
|
|
1922
|
-
}
|
|
1923
|
-
|
|
1924
|
-
// More lines tabbed than spaced? Assume tabs, and
|
|
1925
|
-
// default to tabs in the case of a tie (or nothing
|
|
1926
|
-
// to go on)
|
|
1927
|
-
if (tabbed.length >= spaced.length) {
|
|
1928
|
-
return '\t';
|
|
1929
|
-
}
|
|
1930
|
-
|
|
1931
|
-
// Otherwise, we need to guess the multiple
|
|
1932
|
-
const min = spaced.reduce((previous, current) => {
|
|
1933
|
-
const numSpaces = /^ +/.exec(current)[0].length;
|
|
1934
|
-
return Math.min(numSpaces, previous);
|
|
1935
|
-
}, Infinity);
|
|
1936
|
-
|
|
1937
|
-
return new Array(min + 1).join(' ');
|
|
1938
|
-
}
|
|
1939
|
-
|
|
1940
|
-
function getRelativePath(from, to) {
|
|
1941
|
-
const fromParts = from.split(/[/\\]/);
|
|
1942
|
-
const toParts = to.split(/[/\\]/);
|
|
1943
|
-
|
|
1944
|
-
fromParts.pop(); // get dirname
|
|
1945
|
-
|
|
1946
|
-
while (fromParts[0] === toParts[0]) {
|
|
1947
|
-
fromParts.shift();
|
|
1948
|
-
toParts.shift();
|
|
1949
|
-
}
|
|
1950
|
-
|
|
1951
|
-
if (fromParts.length) {
|
|
1952
|
-
let i = fromParts.length;
|
|
1953
|
-
while (i--) fromParts[i] = '..';
|
|
1954
|
-
}
|
|
1955
|
-
|
|
1956
|
-
return fromParts.concat(toParts).join('/');
|
|
1957
|
-
}
|
|
1958
|
-
|
|
1959
|
-
const toString = Object.prototype.toString;
|
|
1960
|
-
|
|
1961
|
-
function isObject(thing) {
|
|
1962
|
-
return toString.call(thing) === '[object Object]';
|
|
1715
|
+
throw new Error("[add prop]: can't format eventImportList");
|
|
1716
|
+
})))
|
|
1717
|
+
];
|
|
1718
|
+
ctx.app(appData);
|
|
1719
|
+
}
|
|
1963
1720
|
}
|
|
1964
1721
|
|
|
1965
|
-
function
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
lineOffsets.push(pos);
|
|
1971
|
-
pos += originalLines[i].length + 1;
|
|
1972
|
-
}
|
|
1973
|
-
|
|
1974
|
-
return function locate(index) {
|
|
1975
|
-
let i = 0;
|
|
1976
|
-
let j = lineOffsets.length;
|
|
1977
|
-
while (i < j) {
|
|
1978
|
-
const m = (i + j) >> 1;
|
|
1979
|
-
if (index < lineOffsets[m]) {
|
|
1980
|
-
j = m;
|
|
1981
|
-
} else {
|
|
1982
|
-
i = m + 1;
|
|
1983
|
-
}
|
|
1984
|
-
}
|
|
1985
|
-
const line = i - 1;
|
|
1986
|
-
const column = index - lineOffsets[line];
|
|
1987
|
-
return { line, column };
|
|
1988
|
-
};
|
|
1722
|
+
async function compileComponent(compiledCode, project) {
|
|
1723
|
+
const component = compiledCode.strLoc.Component;
|
|
1724
|
+
for (const i of Object.entries(component)) {
|
|
1725
|
+
// TODO: compele compile component
|
|
1726
|
+
}
|
|
1989
1727
|
}
|
|
1990
1728
|
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
this.hires = hires;
|
|
1996
|
-
this.generatedCodeLine = 0;
|
|
1997
|
-
this.generatedCodeColumn = 0;
|
|
1998
|
-
this.raw = [];
|
|
1999
|
-
this.rawSegments = this.raw[this.generatedCodeLine] = [];
|
|
2000
|
-
this.pending = null;
|
|
2001
|
-
}
|
|
2002
|
-
|
|
2003
|
-
addEdit(sourceIndex, content, loc, nameIndex) {
|
|
2004
|
-
if (content.length) {
|
|
2005
|
-
const contentLengthMinusOne = content.length - 1;
|
|
2006
|
-
let contentLineEnd = content.indexOf('\n', 0);
|
|
2007
|
-
let previousContentLineEnd = -1;
|
|
2008
|
-
// Loop through each line in the content and add a segment, but stop if the last line is empty,
|
|
2009
|
-
// else code afterwards would fill one line too many
|
|
2010
|
-
while (contentLineEnd >= 0 && contentLengthMinusOne > contentLineEnd) {
|
|
2011
|
-
const segment = [this.generatedCodeColumn, sourceIndex, loc.line, loc.column];
|
|
2012
|
-
if (nameIndex >= 0) {
|
|
2013
|
-
segment.push(nameIndex);
|
|
2014
|
-
}
|
|
2015
|
-
this.rawSegments.push(segment);
|
|
2016
|
-
|
|
2017
|
-
this.generatedCodeLine += 1;
|
|
2018
|
-
this.raw[this.generatedCodeLine] = this.rawSegments = [];
|
|
2019
|
-
this.generatedCodeColumn = 0;
|
|
2020
|
-
|
|
2021
|
-
previousContentLineEnd = contentLineEnd;
|
|
2022
|
-
contentLineEnd = content.indexOf('\n', contentLineEnd + 1);
|
|
2023
|
-
}
|
|
2024
|
-
|
|
2025
|
-
const segment = [this.generatedCodeColumn, sourceIndex, loc.line, loc.column];
|
|
2026
|
-
if (nameIndex >= 0) {
|
|
2027
|
-
segment.push(nameIndex);
|
|
2028
|
-
}
|
|
2029
|
-
this.rawSegments.push(segment);
|
|
2030
|
-
|
|
2031
|
-
this.advance(content.slice(previousContentLineEnd + 1));
|
|
2032
|
-
} else if (this.pending) {
|
|
2033
|
-
this.rawSegments.push(this.pending);
|
|
2034
|
-
this.advance(content);
|
|
2035
|
-
}
|
|
2036
|
-
|
|
2037
|
-
this.pending = null;
|
|
2038
|
-
}
|
|
2039
|
-
|
|
2040
|
-
addUneditedChunk(sourceIndex, chunk, original, loc, sourcemapLocations) {
|
|
2041
|
-
let originalCharIndex = chunk.start;
|
|
2042
|
-
let first = true;
|
|
2043
|
-
// when iterating each char, check if it's in a word boundary
|
|
2044
|
-
let charInHiresBoundary = false;
|
|
2045
|
-
|
|
2046
|
-
while (originalCharIndex < chunk.end) {
|
|
2047
|
-
if (original[originalCharIndex] === '\n') {
|
|
2048
|
-
loc.line += 1;
|
|
2049
|
-
loc.column = 0;
|
|
2050
|
-
this.generatedCodeLine += 1;
|
|
2051
|
-
this.raw[this.generatedCodeLine] = this.rawSegments = [];
|
|
2052
|
-
this.generatedCodeColumn = 0;
|
|
2053
|
-
first = true;
|
|
2054
|
-
charInHiresBoundary = false;
|
|
2055
|
-
} else {
|
|
2056
|
-
if (this.hires || first || sourcemapLocations.has(originalCharIndex)) {
|
|
2057
|
-
const segment = [this.generatedCodeColumn, sourceIndex, loc.line, loc.column];
|
|
2058
|
-
|
|
2059
|
-
if (this.hires === 'boundary') {
|
|
2060
|
-
// in hires "boundary", group segments per word boundary than per char
|
|
2061
|
-
if (wordRegex.test(original[originalCharIndex])) {
|
|
2062
|
-
// for first char in the boundary found, start the boundary by pushing a segment
|
|
2063
|
-
if (!charInHiresBoundary) {
|
|
2064
|
-
this.rawSegments.push(segment);
|
|
2065
|
-
charInHiresBoundary = true;
|
|
2066
|
-
}
|
|
2067
|
-
} else {
|
|
2068
|
-
// for non-word char, end the boundary by pushing a segment
|
|
2069
|
-
this.rawSegments.push(segment);
|
|
2070
|
-
charInHiresBoundary = false;
|
|
2071
|
-
}
|
|
2072
|
-
} else {
|
|
2073
|
-
this.rawSegments.push(segment);
|
|
2074
|
-
}
|
|
2075
|
-
}
|
|
2076
|
-
|
|
2077
|
-
loc.column += 1;
|
|
2078
|
-
this.generatedCodeColumn += 1;
|
|
2079
|
-
first = false;
|
|
2080
|
-
}
|
|
2081
|
-
|
|
2082
|
-
originalCharIndex += 1;
|
|
2083
|
-
}
|
|
2084
|
-
|
|
2085
|
-
this.pending = null;
|
|
2086
|
-
}
|
|
2087
|
-
|
|
2088
|
-
advance(str) {
|
|
2089
|
-
if (!str) return;
|
|
2090
|
-
|
|
2091
|
-
const lines = str.split('\n');
|
|
2092
|
-
|
|
2093
|
-
if (lines.length > 1) {
|
|
2094
|
-
for (let i = 0; i < lines.length - 1; i++) {
|
|
2095
|
-
this.generatedCodeLine++;
|
|
2096
|
-
this.raw[this.generatedCodeLine] = this.rawSegments = [];
|
|
2097
|
-
}
|
|
2098
|
-
this.generatedCodeColumn = 0;
|
|
2099
|
-
}
|
|
1729
|
+
var index$1 = /*#__PURE__*/Object.freeze({
|
|
1730
|
+
__proto__: null,
|
|
1731
|
+
compileComponent: compileComponent
|
|
1732
|
+
});
|
|
2100
1733
|
|
|
2101
|
-
|
|
2102
|
-
|
|
1734
|
+
async function _transform(ctx) {
|
|
1735
|
+
const _temp_main = generateMain(ctx.compiledCode.JSIR);
|
|
1736
|
+
const mainFn = ctx.mainFn.body = _temp_main[0];
|
|
1737
|
+
const prop = [];
|
|
1738
|
+
const app = _enableWithData();
|
|
1739
|
+
const params = ctx.mainFn.param = [
|
|
1740
|
+
t__namespace.identifier(config.paramCtx)
|
|
1741
|
+
];
|
|
1742
|
+
const parseCtx = {
|
|
1743
|
+
impBody: _temp_main[1],
|
|
1744
|
+
mainFn,
|
|
1745
|
+
prop,
|
|
1746
|
+
ctx: ctx,
|
|
1747
|
+
app
|
|
1748
|
+
};
|
|
1749
|
+
let type = "app";
|
|
1750
|
+
// enable setup fn: use to generate setup
|
|
1751
|
+
const enableSetup = _enable();
|
|
1752
|
+
if (ctx.compiledCode.strLoc.Event.isLoad) {
|
|
1753
|
+
// handler event type mcx
|
|
1754
|
+
type = "event";
|
|
1755
|
+
// enable export setup
|
|
1756
|
+
enableSetup();
|
|
1757
|
+
await Comp$1(parseCtx);
|
|
1758
|
+
}
|
|
1759
|
+
if (ctx.compiledCode.strLoc.UI) {
|
|
1760
|
+
/**
|
|
1761
|
+
* Completed UI handler
|
|
1762
|
+
* @todo - handler
|
|
1763
|
+
*/
|
|
1764
|
+
type = "ui"; // ui mcx
|
|
1765
|
+
enableSetup();
|
|
1766
|
+
await Comp$2(parseCtx);
|
|
1767
|
+
}
|
|
1768
|
+
if (Object.getOwnPropertyNames(ctx.compiledCode.strLoc.Component).length >= 1) {
|
|
1769
|
+
type = "component";
|
|
1770
|
+
await compileComponent(ctx.compiledCode, ctx.opt.ProjectDir);
|
|
1771
|
+
return `export default {type:'component',setup:null,app:{}}`;
|
|
1772
|
+
}
|
|
1773
|
+
if (type == "app") {
|
|
1774
|
+
// enable setup export
|
|
1775
|
+
enableSetup();
|
|
1776
|
+
// find event mcx import
|
|
1777
|
+
await Comp(parseCtx);
|
|
1778
|
+
}
|
|
1779
|
+
// add default export: type
|
|
1780
|
+
prop.push(t__namespace.objectProperty(t__namespace.identifier("type"), t__namespace.stringLiteral(type)));
|
|
1781
|
+
if (enableSetup.prototype.enable) {
|
|
1782
|
+
prop.push(t__namespace.objectProperty(t__namespace.identifier("setup"), t__namespace.identifier(config.scriptCompileFn)));
|
|
1783
|
+
}
|
|
1784
|
+
if (app.prototype.enable) {
|
|
1785
|
+
prop.push(t__namespace.objectProperty(t__namespace.identifier("app"), t__namespace.objectExpression(app.prototype.enable)));
|
|
1786
|
+
}
|
|
1787
|
+
// generate code
|
|
1788
|
+
const code = generator.generate(
|
|
1789
|
+
// create program
|
|
1790
|
+
(t__namespace.program([
|
|
1791
|
+
...parseCtx.impBody,
|
|
1792
|
+
t__namespace.functionDeclaration(t__namespace.identifier(config.scriptCompileFn), params, t__namespace.blockStatement(mainFn), false, false),
|
|
1793
|
+
t__namespace.exportDefaultDeclaration(t__namespace.objectExpression(prop)),
|
|
1794
|
+
]))).code;
|
|
1795
|
+
return code;
|
|
2103
1796
|
}
|
|
2104
1797
|
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
filename: { writable: true, value: options.filename },
|
|
2127
|
-
indentExclusionRanges: { writable: true, value: options.indentExclusionRanges },
|
|
2128
|
-
sourcemapLocations: { writable: true, value: new BitSet() },
|
|
2129
|
-
storedNames: { writable: true, value: {} },
|
|
2130
|
-
indentStr: { writable: true, value: undefined },
|
|
2131
|
-
ignoreList: { writable: true, value: options.ignoreList },
|
|
2132
|
-
offset: { writable: true, value: options.offset || 0 },
|
|
2133
|
-
});
|
|
2134
|
-
|
|
2135
|
-
this.byStart[0] = chunk;
|
|
2136
|
-
this.byEnd[string.length] = chunk;
|
|
2137
|
-
}
|
|
2138
|
-
|
|
2139
|
-
addSourcemapLocation(char) {
|
|
2140
|
-
this.sourcemapLocations.add(char);
|
|
2141
|
-
}
|
|
2142
|
-
|
|
2143
|
-
append(content) {
|
|
2144
|
-
if (typeof content !== 'string') throw new TypeError('outro content must be a string');
|
|
2145
|
-
|
|
2146
|
-
this.outro += content;
|
|
2147
|
-
return this;
|
|
2148
|
-
}
|
|
2149
|
-
|
|
2150
|
-
appendLeft(index, content) {
|
|
2151
|
-
index = index + this.offset;
|
|
2152
|
-
|
|
2153
|
-
if (typeof content !== 'string') throw new TypeError('inserted content must be a string');
|
|
2154
|
-
|
|
2155
|
-
this._split(index);
|
|
2156
|
-
|
|
2157
|
-
const chunk = this.byEnd[index];
|
|
2158
|
-
|
|
2159
|
-
if (chunk) {
|
|
2160
|
-
chunk.appendLeft(content);
|
|
2161
|
-
} else {
|
|
2162
|
-
this.intro += content;
|
|
2163
|
-
}
|
|
2164
|
-
return this;
|
|
2165
|
-
}
|
|
2166
|
-
|
|
2167
|
-
appendRight(index, content) {
|
|
2168
|
-
index = index + this.offset;
|
|
2169
|
-
|
|
2170
|
-
if (typeof content !== 'string') throw new TypeError('inserted content must be a string');
|
|
2171
|
-
|
|
2172
|
-
this._split(index);
|
|
2173
|
-
|
|
2174
|
-
const chunk = this.byStart[index];
|
|
2175
|
-
|
|
2176
|
-
if (chunk) {
|
|
2177
|
-
chunk.appendRight(content);
|
|
2178
|
-
} else {
|
|
2179
|
-
this.outro += content;
|
|
2180
|
-
}
|
|
2181
|
-
return this;
|
|
2182
|
-
}
|
|
2183
|
-
|
|
2184
|
-
clone() {
|
|
2185
|
-
const cloned = new MagicString(this.original, { filename: this.filename, offset: this.offset });
|
|
2186
|
-
|
|
2187
|
-
let originalChunk = this.firstChunk;
|
|
2188
|
-
let clonedChunk = (cloned.firstChunk = cloned.lastSearchedChunk = originalChunk.clone());
|
|
2189
|
-
|
|
2190
|
-
while (originalChunk) {
|
|
2191
|
-
cloned.byStart[clonedChunk.start] = clonedChunk;
|
|
2192
|
-
cloned.byEnd[clonedChunk.end] = clonedChunk;
|
|
2193
|
-
|
|
2194
|
-
const nextOriginalChunk = originalChunk.next;
|
|
2195
|
-
const nextClonedChunk = nextOriginalChunk && nextOriginalChunk.clone();
|
|
2196
|
-
|
|
2197
|
-
if (nextClonedChunk) {
|
|
2198
|
-
clonedChunk.next = nextClonedChunk;
|
|
2199
|
-
nextClonedChunk.previous = clonedChunk;
|
|
2200
|
-
|
|
2201
|
-
clonedChunk = nextClonedChunk;
|
|
2202
|
-
}
|
|
2203
|
-
|
|
2204
|
-
originalChunk = nextOriginalChunk;
|
|
2205
|
-
}
|
|
2206
|
-
|
|
2207
|
-
cloned.lastChunk = clonedChunk;
|
|
2208
|
-
|
|
2209
|
-
if (this.indentExclusionRanges) {
|
|
2210
|
-
cloned.indentExclusionRanges = this.indentExclusionRanges.slice();
|
|
2211
|
-
}
|
|
2212
|
-
|
|
2213
|
-
cloned.sourcemapLocations = new BitSet(this.sourcemapLocations);
|
|
2214
|
-
|
|
2215
|
-
cloned.intro = this.intro;
|
|
2216
|
-
cloned.outro = this.outro;
|
|
2217
|
-
|
|
2218
|
-
return cloned;
|
|
2219
|
-
}
|
|
2220
|
-
|
|
2221
|
-
generateDecodedMap(options) {
|
|
2222
|
-
options = options || {};
|
|
2223
|
-
|
|
2224
|
-
const sourceIndex = 0;
|
|
2225
|
-
const names = Object.keys(this.storedNames);
|
|
2226
|
-
const mappings = new Mappings(options.hires);
|
|
2227
|
-
|
|
2228
|
-
const locate = getLocator(this.original);
|
|
2229
|
-
|
|
2230
|
-
if (this.intro) {
|
|
2231
|
-
mappings.advance(this.intro);
|
|
2232
|
-
}
|
|
2233
|
-
|
|
2234
|
-
this.firstChunk.eachNext((chunk) => {
|
|
2235
|
-
const loc = locate(chunk.start);
|
|
2236
|
-
|
|
2237
|
-
if (chunk.intro.length) mappings.advance(chunk.intro);
|
|
2238
|
-
|
|
2239
|
-
if (chunk.edited) {
|
|
2240
|
-
mappings.addEdit(
|
|
2241
|
-
sourceIndex,
|
|
2242
|
-
chunk.content,
|
|
2243
|
-
loc,
|
|
2244
|
-
chunk.storeName ? names.indexOf(chunk.original) : -1,
|
|
2245
|
-
);
|
|
2246
|
-
} else {
|
|
2247
|
-
mappings.addUneditedChunk(sourceIndex, chunk, this.original, loc, this.sourcemapLocations);
|
|
2248
|
-
}
|
|
2249
|
-
|
|
2250
|
-
if (chunk.outro.length) mappings.advance(chunk.outro);
|
|
2251
|
-
});
|
|
2252
|
-
|
|
2253
|
-
if (this.outro) {
|
|
2254
|
-
mappings.advance(this.outro);
|
|
2255
|
-
}
|
|
2256
|
-
|
|
2257
|
-
return {
|
|
2258
|
-
file: options.file ? options.file.split(/[/\\]/).pop() : undefined,
|
|
2259
|
-
sources: [
|
|
2260
|
-
options.source ? getRelativePath(options.file || '', options.source) : options.file || '',
|
|
2261
|
-
],
|
|
2262
|
-
sourcesContent: options.includeContent ? [this.original] : undefined,
|
|
2263
|
-
names,
|
|
2264
|
-
mappings: mappings.raw,
|
|
2265
|
-
x_google_ignoreList: this.ignoreList ? [sourceIndex] : undefined,
|
|
2266
|
-
};
|
|
2267
|
-
}
|
|
2268
|
-
|
|
2269
|
-
generateMap(options) {
|
|
2270
|
-
return new SourceMap(this.generateDecodedMap(options));
|
|
2271
|
-
}
|
|
2272
|
-
|
|
2273
|
-
_ensureindentStr() {
|
|
2274
|
-
if (this.indentStr === undefined) {
|
|
2275
|
-
this.indentStr = guessIndent(this.original);
|
|
2276
|
-
}
|
|
2277
|
-
}
|
|
2278
|
-
|
|
2279
|
-
_getRawIndentString() {
|
|
2280
|
-
this._ensureindentStr();
|
|
2281
|
-
return this.indentStr;
|
|
2282
|
-
}
|
|
2283
|
-
|
|
2284
|
-
getIndentString() {
|
|
2285
|
-
this._ensureindentStr();
|
|
2286
|
-
return this.indentStr === null ? '\t' : this.indentStr;
|
|
2287
|
-
}
|
|
2288
|
-
|
|
2289
|
-
indent(indentStr, options) {
|
|
2290
|
-
const pattern = /^[^\r\n]/gm;
|
|
2291
|
-
|
|
2292
|
-
if (isObject(indentStr)) {
|
|
2293
|
-
options = indentStr;
|
|
2294
|
-
indentStr = undefined;
|
|
2295
|
-
}
|
|
2296
|
-
|
|
2297
|
-
if (indentStr === undefined) {
|
|
2298
|
-
this._ensureindentStr();
|
|
2299
|
-
indentStr = this.indentStr || '\t';
|
|
2300
|
-
}
|
|
2301
|
-
|
|
2302
|
-
if (indentStr === '') return this; // noop
|
|
2303
|
-
|
|
2304
|
-
options = options || {};
|
|
2305
|
-
|
|
2306
|
-
// Process exclusion ranges
|
|
2307
|
-
const isExcluded = {};
|
|
2308
|
-
|
|
2309
|
-
if (options.exclude) {
|
|
2310
|
-
const exclusions =
|
|
2311
|
-
typeof options.exclude[0] === 'number' ? [options.exclude] : options.exclude;
|
|
2312
|
-
exclusions.forEach((exclusion) => {
|
|
2313
|
-
for (let i = exclusion[0]; i < exclusion[1]; i += 1) {
|
|
2314
|
-
isExcluded[i] = true;
|
|
2315
|
-
}
|
|
2316
|
-
});
|
|
2317
|
-
}
|
|
2318
|
-
|
|
2319
|
-
let shouldIndentNextCharacter = options.indentStart !== false;
|
|
2320
|
-
const replacer = (match) => {
|
|
2321
|
-
if (shouldIndentNextCharacter) return `${indentStr}${match}`;
|
|
2322
|
-
shouldIndentNextCharacter = true;
|
|
2323
|
-
return match;
|
|
2324
|
-
};
|
|
2325
|
-
|
|
2326
|
-
this.intro = this.intro.replace(pattern, replacer);
|
|
2327
|
-
|
|
2328
|
-
let charIndex = 0;
|
|
2329
|
-
let chunk = this.firstChunk;
|
|
2330
|
-
|
|
2331
|
-
while (chunk) {
|
|
2332
|
-
const end = chunk.end;
|
|
2333
|
-
|
|
2334
|
-
if (chunk.edited) {
|
|
2335
|
-
if (!isExcluded[charIndex]) {
|
|
2336
|
-
chunk.content = chunk.content.replace(pattern, replacer);
|
|
2337
|
-
|
|
2338
|
-
if (chunk.content.length) {
|
|
2339
|
-
shouldIndentNextCharacter = chunk.content[chunk.content.length - 1] === '\n';
|
|
2340
|
-
}
|
|
2341
|
-
}
|
|
2342
|
-
} else {
|
|
2343
|
-
charIndex = chunk.start;
|
|
2344
|
-
|
|
2345
|
-
while (charIndex < end) {
|
|
2346
|
-
if (!isExcluded[charIndex]) {
|
|
2347
|
-
const char = this.original[charIndex];
|
|
2348
|
-
|
|
2349
|
-
if (char === '\n') {
|
|
2350
|
-
shouldIndentNextCharacter = true;
|
|
2351
|
-
} else if (char !== '\r' && shouldIndentNextCharacter) {
|
|
2352
|
-
shouldIndentNextCharacter = false;
|
|
2353
|
-
|
|
2354
|
-
if (charIndex === chunk.start) {
|
|
2355
|
-
chunk.prependRight(indentStr);
|
|
2356
|
-
} else {
|
|
2357
|
-
this._splitChunk(chunk, charIndex);
|
|
2358
|
-
chunk = chunk.next;
|
|
2359
|
-
chunk.prependRight(indentStr);
|
|
2360
|
-
}
|
|
2361
|
-
}
|
|
2362
|
-
}
|
|
2363
|
-
|
|
2364
|
-
charIndex += 1;
|
|
2365
|
-
}
|
|
2366
|
-
}
|
|
2367
|
-
|
|
2368
|
-
charIndex = chunk.end;
|
|
2369
|
-
chunk = chunk.next;
|
|
2370
|
-
}
|
|
2371
|
-
|
|
2372
|
-
this.outro = this.outro.replace(pattern, replacer);
|
|
2373
|
-
|
|
2374
|
-
return this;
|
|
2375
|
-
}
|
|
2376
|
-
|
|
2377
|
-
insert() {
|
|
2378
|
-
throw new Error(
|
|
2379
|
-
'magicString.insert(...) is deprecated. Use prependRight(...) or appendLeft(...)',
|
|
2380
|
-
);
|
|
2381
|
-
}
|
|
2382
|
-
|
|
2383
|
-
insertLeft(index, content) {
|
|
2384
|
-
if (!warned.insertLeft) {
|
|
2385
|
-
console.warn(
|
|
2386
|
-
'magicString.insertLeft(...) is deprecated. Use magicString.appendLeft(...) instead',
|
|
2387
|
-
);
|
|
2388
|
-
warned.insertLeft = true;
|
|
2389
|
-
}
|
|
2390
|
-
|
|
2391
|
-
return this.appendLeft(index, content);
|
|
2392
|
-
}
|
|
2393
|
-
|
|
2394
|
-
insertRight(index, content) {
|
|
2395
|
-
if (!warned.insertRight) {
|
|
2396
|
-
console.warn(
|
|
2397
|
-
'magicString.insertRight(...) is deprecated. Use magicString.prependRight(...) instead',
|
|
2398
|
-
);
|
|
2399
|
-
warned.insertRight = true;
|
|
2400
|
-
}
|
|
2401
|
-
|
|
2402
|
-
return this.prependRight(index, content);
|
|
2403
|
-
}
|
|
2404
|
-
|
|
2405
|
-
move(start, end, index) {
|
|
2406
|
-
start = start + this.offset;
|
|
2407
|
-
end = end + this.offset;
|
|
2408
|
-
index = index + this.offset;
|
|
2409
|
-
|
|
2410
|
-
if (index >= start && index <= end) throw new Error('Cannot move a selection inside itself');
|
|
2411
|
-
|
|
2412
|
-
this._split(start);
|
|
2413
|
-
this._split(end);
|
|
2414
|
-
this._split(index);
|
|
2415
|
-
|
|
2416
|
-
const first = this.byStart[start];
|
|
2417
|
-
const last = this.byEnd[end];
|
|
2418
|
-
|
|
2419
|
-
const oldLeft = first.previous;
|
|
2420
|
-
const oldRight = last.next;
|
|
2421
|
-
|
|
2422
|
-
const newRight = this.byStart[index];
|
|
2423
|
-
if (!newRight && last === this.lastChunk) return this;
|
|
2424
|
-
const newLeft = newRight ? newRight.previous : this.lastChunk;
|
|
2425
|
-
|
|
2426
|
-
if (oldLeft) oldLeft.next = oldRight;
|
|
2427
|
-
if (oldRight) oldRight.previous = oldLeft;
|
|
2428
|
-
|
|
2429
|
-
if (newLeft) newLeft.next = first;
|
|
2430
|
-
if (newRight) newRight.previous = last;
|
|
2431
|
-
|
|
2432
|
-
if (!first.previous) this.firstChunk = last.next;
|
|
2433
|
-
if (!last.next) {
|
|
2434
|
-
this.lastChunk = first.previous;
|
|
2435
|
-
this.lastChunk.next = null;
|
|
2436
|
-
}
|
|
2437
|
-
|
|
2438
|
-
first.previous = newLeft;
|
|
2439
|
-
last.next = newRight || null;
|
|
2440
|
-
|
|
2441
|
-
if (!newLeft) this.firstChunk = first;
|
|
2442
|
-
if (!newRight) this.lastChunk = last;
|
|
2443
|
-
return this;
|
|
2444
|
-
}
|
|
2445
|
-
|
|
2446
|
-
overwrite(start, end, content, options) {
|
|
2447
|
-
options = options || {};
|
|
2448
|
-
return this.update(start, end, content, { ...options, overwrite: !options.contentOnly });
|
|
2449
|
-
}
|
|
2450
|
-
|
|
2451
|
-
update(start, end, content, options) {
|
|
2452
|
-
start = start + this.offset;
|
|
2453
|
-
end = end + this.offset;
|
|
2454
|
-
|
|
2455
|
-
if (typeof content !== 'string') throw new TypeError('replacement content must be a string');
|
|
2456
|
-
|
|
2457
|
-
if (this.original.length !== 0) {
|
|
2458
|
-
while (start < 0) start += this.original.length;
|
|
2459
|
-
while (end < 0) end += this.original.length;
|
|
2460
|
-
}
|
|
2461
|
-
|
|
2462
|
-
if (end > this.original.length) throw new Error('end is out of bounds');
|
|
2463
|
-
if (start === end)
|
|
2464
|
-
throw new Error(
|
|
2465
|
-
'Cannot overwrite a zero-length range – use appendLeft or prependRight instead',
|
|
2466
|
-
);
|
|
2467
|
-
|
|
2468
|
-
this._split(start);
|
|
2469
|
-
this._split(end);
|
|
2470
|
-
|
|
2471
|
-
if (options === true) {
|
|
2472
|
-
if (!warned.storeName) {
|
|
2473
|
-
console.warn(
|
|
2474
|
-
'The final argument to magicString.overwrite(...) should be an options object. See https://github.com/rich-harris/magic-string',
|
|
2475
|
-
);
|
|
2476
|
-
warned.storeName = true;
|
|
2477
|
-
}
|
|
2478
|
-
|
|
2479
|
-
options = { storeName: true };
|
|
2480
|
-
}
|
|
2481
|
-
const storeName = options !== undefined ? options.storeName : false;
|
|
2482
|
-
const overwrite = options !== undefined ? options.overwrite : false;
|
|
2483
|
-
|
|
2484
|
-
if (storeName) {
|
|
2485
|
-
const original = this.original.slice(start, end);
|
|
2486
|
-
Object.defineProperty(this.storedNames, original, {
|
|
2487
|
-
writable: true,
|
|
2488
|
-
value: true,
|
|
2489
|
-
enumerable: true,
|
|
2490
|
-
});
|
|
2491
|
-
}
|
|
2492
|
-
|
|
2493
|
-
const first = this.byStart[start];
|
|
2494
|
-
const last = this.byEnd[end];
|
|
2495
|
-
|
|
2496
|
-
if (first) {
|
|
2497
|
-
let chunk = first;
|
|
2498
|
-
while (chunk !== last) {
|
|
2499
|
-
if (chunk.next !== this.byStart[chunk.end]) {
|
|
2500
|
-
throw new Error('Cannot overwrite across a split point');
|
|
2501
|
-
}
|
|
2502
|
-
chunk = chunk.next;
|
|
2503
|
-
chunk.edit('', false);
|
|
2504
|
-
}
|
|
2505
|
-
|
|
2506
|
-
first.edit(content, storeName, !overwrite);
|
|
2507
|
-
} else {
|
|
2508
|
-
// must be inserting at the end
|
|
2509
|
-
const newChunk = new Chunk(start, end, '').edit(content, storeName);
|
|
2510
|
-
|
|
2511
|
-
// TODO last chunk in the array may not be the last chunk, if it's moved...
|
|
2512
|
-
last.next = newChunk;
|
|
2513
|
-
newChunk.previous = last;
|
|
2514
|
-
}
|
|
2515
|
-
return this;
|
|
2516
|
-
}
|
|
2517
|
-
|
|
2518
|
-
prepend(content) {
|
|
2519
|
-
if (typeof content !== 'string') throw new TypeError('outro content must be a string');
|
|
2520
|
-
|
|
2521
|
-
this.intro = content + this.intro;
|
|
2522
|
-
return this;
|
|
2523
|
-
}
|
|
2524
|
-
|
|
2525
|
-
prependLeft(index, content) {
|
|
2526
|
-
index = index + this.offset;
|
|
2527
|
-
|
|
2528
|
-
if (typeof content !== 'string') throw new TypeError('inserted content must be a string');
|
|
2529
|
-
|
|
2530
|
-
this._split(index);
|
|
2531
|
-
|
|
2532
|
-
const chunk = this.byEnd[index];
|
|
2533
|
-
|
|
2534
|
-
if (chunk) {
|
|
2535
|
-
chunk.prependLeft(content);
|
|
2536
|
-
} else {
|
|
2537
|
-
this.intro = content + this.intro;
|
|
2538
|
-
}
|
|
2539
|
-
return this;
|
|
2540
|
-
}
|
|
2541
|
-
|
|
2542
|
-
prependRight(index, content) {
|
|
2543
|
-
index = index + this.offset;
|
|
2544
|
-
|
|
2545
|
-
if (typeof content !== 'string') throw new TypeError('inserted content must be a string');
|
|
2546
|
-
|
|
2547
|
-
this._split(index);
|
|
2548
|
-
|
|
2549
|
-
const chunk = this.byStart[index];
|
|
2550
|
-
|
|
2551
|
-
if (chunk) {
|
|
2552
|
-
chunk.prependRight(content);
|
|
2553
|
-
} else {
|
|
2554
|
-
this.outro = content + this.outro;
|
|
2555
|
-
}
|
|
2556
|
-
return this;
|
|
2557
|
-
}
|
|
2558
|
-
|
|
2559
|
-
remove(start, end) {
|
|
2560
|
-
start = start + this.offset;
|
|
2561
|
-
end = end + this.offset;
|
|
2562
|
-
|
|
2563
|
-
if (this.original.length !== 0) {
|
|
2564
|
-
while (start < 0) start += this.original.length;
|
|
2565
|
-
while (end < 0) end += this.original.length;
|
|
2566
|
-
}
|
|
2567
|
-
|
|
2568
|
-
if (start === end) return this;
|
|
2569
|
-
|
|
2570
|
-
if (start < 0 || end > this.original.length) throw new Error('Character is out of bounds');
|
|
2571
|
-
if (start > end) throw new Error('end must be greater than start');
|
|
2572
|
-
|
|
2573
|
-
this._split(start);
|
|
2574
|
-
this._split(end);
|
|
2575
|
-
|
|
2576
|
-
let chunk = this.byStart[start];
|
|
2577
|
-
|
|
2578
|
-
while (chunk) {
|
|
2579
|
-
chunk.intro = '';
|
|
2580
|
-
chunk.outro = '';
|
|
2581
|
-
chunk.edit('');
|
|
2582
|
-
|
|
2583
|
-
chunk = end > chunk.end ? this.byStart[chunk.end] : null;
|
|
2584
|
-
}
|
|
2585
|
-
return this;
|
|
2586
|
-
}
|
|
2587
|
-
|
|
2588
|
-
reset(start, end) {
|
|
2589
|
-
start = start + this.offset;
|
|
2590
|
-
end = end + this.offset;
|
|
2591
|
-
|
|
2592
|
-
if (this.original.length !== 0) {
|
|
2593
|
-
while (start < 0) start += this.original.length;
|
|
2594
|
-
while (end < 0) end += this.original.length;
|
|
2595
|
-
}
|
|
2596
|
-
|
|
2597
|
-
if (start === end) return this;
|
|
2598
|
-
|
|
2599
|
-
if (start < 0 || end > this.original.length) throw new Error('Character is out of bounds');
|
|
2600
|
-
if (start > end) throw new Error('end must be greater than start');
|
|
2601
|
-
|
|
2602
|
-
this._split(start);
|
|
2603
|
-
this._split(end);
|
|
2604
|
-
|
|
2605
|
-
let chunk = this.byStart[start];
|
|
2606
|
-
|
|
2607
|
-
while (chunk) {
|
|
2608
|
-
chunk.reset();
|
|
2609
|
-
|
|
2610
|
-
chunk = end > chunk.end ? this.byStart[chunk.end] : null;
|
|
2611
|
-
}
|
|
2612
|
-
return this;
|
|
2613
|
-
}
|
|
2614
|
-
|
|
2615
|
-
lastChar() {
|
|
2616
|
-
if (this.outro.length) return this.outro[this.outro.length - 1];
|
|
2617
|
-
let chunk = this.lastChunk;
|
|
2618
|
-
do {
|
|
2619
|
-
if (chunk.outro.length) return chunk.outro[chunk.outro.length - 1];
|
|
2620
|
-
if (chunk.content.length) return chunk.content[chunk.content.length - 1];
|
|
2621
|
-
if (chunk.intro.length) return chunk.intro[chunk.intro.length - 1];
|
|
2622
|
-
} while ((chunk = chunk.previous));
|
|
2623
|
-
if (this.intro.length) return this.intro[this.intro.length - 1];
|
|
2624
|
-
return '';
|
|
2625
|
-
}
|
|
2626
|
-
|
|
2627
|
-
lastLine() {
|
|
2628
|
-
let lineIndex = this.outro.lastIndexOf(n);
|
|
2629
|
-
if (lineIndex !== -1) return this.outro.substr(lineIndex + 1);
|
|
2630
|
-
let lineStr = this.outro;
|
|
2631
|
-
let chunk = this.lastChunk;
|
|
2632
|
-
do {
|
|
2633
|
-
if (chunk.outro.length > 0) {
|
|
2634
|
-
lineIndex = chunk.outro.lastIndexOf(n);
|
|
2635
|
-
if (lineIndex !== -1) return chunk.outro.substr(lineIndex + 1) + lineStr;
|
|
2636
|
-
lineStr = chunk.outro + lineStr;
|
|
2637
|
-
}
|
|
2638
|
-
|
|
2639
|
-
if (chunk.content.length > 0) {
|
|
2640
|
-
lineIndex = chunk.content.lastIndexOf(n);
|
|
2641
|
-
if (lineIndex !== -1) return chunk.content.substr(lineIndex + 1) + lineStr;
|
|
2642
|
-
lineStr = chunk.content + lineStr;
|
|
2643
|
-
}
|
|
2644
|
-
|
|
2645
|
-
if (chunk.intro.length > 0) {
|
|
2646
|
-
lineIndex = chunk.intro.lastIndexOf(n);
|
|
2647
|
-
if (lineIndex !== -1) return chunk.intro.substr(lineIndex + 1) + lineStr;
|
|
2648
|
-
lineStr = chunk.intro + lineStr;
|
|
2649
|
-
}
|
|
2650
|
-
} while ((chunk = chunk.previous));
|
|
2651
|
-
lineIndex = this.intro.lastIndexOf(n);
|
|
2652
|
-
if (lineIndex !== -1) return this.intro.substr(lineIndex + 1) + lineStr;
|
|
2653
|
-
return this.intro + lineStr;
|
|
2654
|
-
}
|
|
2655
|
-
|
|
2656
|
-
slice(start = 0, end = this.original.length - this.offset) {
|
|
2657
|
-
start = start + this.offset;
|
|
2658
|
-
end = end + this.offset;
|
|
2659
|
-
|
|
2660
|
-
if (this.original.length !== 0) {
|
|
2661
|
-
while (start < 0) start += this.original.length;
|
|
2662
|
-
while (end < 0) end += this.original.length;
|
|
2663
|
-
}
|
|
2664
|
-
|
|
2665
|
-
let result = '';
|
|
2666
|
-
|
|
2667
|
-
// find start chunk
|
|
2668
|
-
let chunk = this.firstChunk;
|
|
2669
|
-
while (chunk && (chunk.start > start || chunk.end <= start)) {
|
|
2670
|
-
// found end chunk before start
|
|
2671
|
-
if (chunk.start < end && chunk.end >= end) {
|
|
2672
|
-
return result;
|
|
2673
|
-
}
|
|
2674
|
-
|
|
2675
|
-
chunk = chunk.next;
|
|
2676
|
-
}
|
|
2677
|
-
|
|
2678
|
-
if (chunk && chunk.edited && chunk.start !== start)
|
|
2679
|
-
throw new Error(`Cannot use replaced character ${start} as slice start anchor.`);
|
|
2680
|
-
|
|
2681
|
-
const startChunk = chunk;
|
|
2682
|
-
while (chunk) {
|
|
2683
|
-
if (chunk.intro && (startChunk !== chunk || chunk.start === start)) {
|
|
2684
|
-
result += chunk.intro;
|
|
2685
|
-
}
|
|
2686
|
-
|
|
2687
|
-
const containsEnd = chunk.start < end && chunk.end >= end;
|
|
2688
|
-
if (containsEnd && chunk.edited && chunk.end !== end)
|
|
2689
|
-
throw new Error(`Cannot use replaced character ${end} as slice end anchor.`);
|
|
2690
|
-
|
|
2691
|
-
const sliceStart = startChunk === chunk ? start - chunk.start : 0;
|
|
2692
|
-
const sliceEnd = containsEnd ? chunk.content.length + end - chunk.end : chunk.content.length;
|
|
2693
|
-
|
|
2694
|
-
result += chunk.content.slice(sliceStart, sliceEnd);
|
|
2695
|
-
|
|
2696
|
-
if (chunk.outro && (!containsEnd || chunk.end === end)) {
|
|
2697
|
-
result += chunk.outro;
|
|
2698
|
-
}
|
|
2699
|
-
|
|
2700
|
-
if (containsEnd) {
|
|
2701
|
-
break;
|
|
2702
|
-
}
|
|
2703
|
-
|
|
2704
|
-
chunk = chunk.next;
|
|
2705
|
-
}
|
|
2706
|
-
|
|
2707
|
-
return result;
|
|
2708
|
-
}
|
|
2709
|
-
|
|
2710
|
-
// TODO deprecate this? not really very useful
|
|
2711
|
-
snip(start, end) {
|
|
2712
|
-
const clone = this.clone();
|
|
2713
|
-
clone.remove(0, start);
|
|
2714
|
-
clone.remove(end, clone.original.length);
|
|
2715
|
-
|
|
2716
|
-
return clone;
|
|
2717
|
-
}
|
|
2718
|
-
|
|
2719
|
-
_split(index) {
|
|
2720
|
-
if (this.byStart[index] || this.byEnd[index]) return;
|
|
2721
|
-
|
|
2722
|
-
let chunk = this.lastSearchedChunk;
|
|
2723
|
-
let previousChunk = chunk;
|
|
2724
|
-
const searchForward = index > chunk.end;
|
|
2725
|
-
|
|
2726
|
-
while (chunk) {
|
|
2727
|
-
if (chunk.contains(index)) return this._splitChunk(chunk, index);
|
|
2728
|
-
|
|
2729
|
-
chunk = searchForward ? this.byStart[chunk.end] : this.byEnd[chunk.start];
|
|
2730
|
-
|
|
2731
|
-
// Prevent infinite loop (e.g. via empty chunks, where start === end)
|
|
2732
|
-
if (chunk === previousChunk) return;
|
|
2733
|
-
|
|
2734
|
-
previousChunk = chunk;
|
|
2735
|
-
}
|
|
2736
|
-
}
|
|
2737
|
-
|
|
2738
|
-
_splitChunk(chunk, index) {
|
|
2739
|
-
if (chunk.edited && chunk.content.length) {
|
|
2740
|
-
// zero-length edited chunks are a special case (overlapping replacements)
|
|
2741
|
-
const loc = getLocator(this.original)(index);
|
|
2742
|
-
throw new Error(
|
|
2743
|
-
`Cannot split a chunk that has already been edited (${loc.line}:${loc.column} – "${chunk.original}")`,
|
|
2744
|
-
);
|
|
2745
|
-
}
|
|
2746
|
-
|
|
2747
|
-
const newChunk = chunk.split(index);
|
|
2748
|
-
|
|
2749
|
-
this.byEnd[index] = chunk;
|
|
2750
|
-
this.byStart[index] = newChunk;
|
|
2751
|
-
this.byEnd[newChunk.end] = newChunk;
|
|
2752
|
-
|
|
2753
|
-
if (chunk === this.lastChunk) this.lastChunk = newChunk;
|
|
2754
|
-
|
|
2755
|
-
this.lastSearchedChunk = chunk;
|
|
2756
|
-
return true;
|
|
2757
|
-
}
|
|
2758
|
-
|
|
2759
|
-
toString() {
|
|
2760
|
-
let str = this.intro;
|
|
2761
|
-
|
|
2762
|
-
let chunk = this.firstChunk;
|
|
2763
|
-
while (chunk) {
|
|
2764
|
-
str += chunk.toString();
|
|
2765
|
-
chunk = chunk.next;
|
|
2766
|
-
}
|
|
2767
|
-
|
|
2768
|
-
return str + this.outro;
|
|
2769
|
-
}
|
|
2770
|
-
|
|
2771
|
-
isEmpty() {
|
|
2772
|
-
let chunk = this.firstChunk;
|
|
2773
|
-
do {
|
|
2774
|
-
if (
|
|
2775
|
-
(chunk.intro.length && chunk.intro.trim()) ||
|
|
2776
|
-
(chunk.content.length && chunk.content.trim()) ||
|
|
2777
|
-
(chunk.outro.length && chunk.outro.trim())
|
|
2778
|
-
)
|
|
2779
|
-
return false;
|
|
2780
|
-
} while ((chunk = chunk.next));
|
|
2781
|
-
return true;
|
|
2782
|
-
}
|
|
2783
|
-
|
|
2784
|
-
length() {
|
|
2785
|
-
let chunk = this.firstChunk;
|
|
2786
|
-
let length = 0;
|
|
2787
|
-
do {
|
|
2788
|
-
length += chunk.intro.length + chunk.content.length + chunk.outro.length;
|
|
2789
|
-
} while ((chunk = chunk.next));
|
|
2790
|
-
return length;
|
|
2791
|
-
}
|
|
2792
|
-
|
|
2793
|
-
trimLines() {
|
|
2794
|
-
return this.trim('[\\r\\n]');
|
|
2795
|
-
}
|
|
2796
|
-
|
|
2797
|
-
trim(charType) {
|
|
2798
|
-
return this.trimStart(charType).trimEnd(charType);
|
|
2799
|
-
}
|
|
2800
|
-
|
|
2801
|
-
trimEndAborted(charType) {
|
|
2802
|
-
const rx = new RegExp((charType || '\\s') + '+$');
|
|
2803
|
-
|
|
2804
|
-
this.outro = this.outro.replace(rx, '');
|
|
2805
|
-
if (this.outro.length) return true;
|
|
2806
|
-
|
|
2807
|
-
let chunk = this.lastChunk;
|
|
2808
|
-
|
|
2809
|
-
do {
|
|
2810
|
-
const end = chunk.end;
|
|
2811
|
-
const aborted = chunk.trimEnd(rx);
|
|
2812
|
-
|
|
2813
|
-
// if chunk was trimmed, we have a new lastChunk
|
|
2814
|
-
if (chunk.end !== end) {
|
|
2815
|
-
if (this.lastChunk === chunk) {
|
|
2816
|
-
this.lastChunk = chunk.next;
|
|
2817
|
-
}
|
|
2818
|
-
|
|
2819
|
-
this.byEnd[chunk.end] = chunk;
|
|
2820
|
-
this.byStart[chunk.next.start] = chunk.next;
|
|
2821
|
-
this.byEnd[chunk.next.end] = chunk.next;
|
|
2822
|
-
}
|
|
2823
|
-
|
|
2824
|
-
if (aborted) return true;
|
|
2825
|
-
chunk = chunk.previous;
|
|
2826
|
-
} while (chunk);
|
|
2827
|
-
|
|
2828
|
-
return false;
|
|
2829
|
-
}
|
|
2830
|
-
|
|
2831
|
-
trimEnd(charType) {
|
|
2832
|
-
this.trimEndAborted(charType);
|
|
2833
|
-
return this;
|
|
2834
|
-
}
|
|
2835
|
-
trimStartAborted(charType) {
|
|
2836
|
-
const rx = new RegExp('^' + (charType || '\\s') + '+');
|
|
2837
|
-
|
|
2838
|
-
this.intro = this.intro.replace(rx, '');
|
|
2839
|
-
if (this.intro.length) return true;
|
|
2840
|
-
|
|
2841
|
-
let chunk = this.firstChunk;
|
|
2842
|
-
|
|
2843
|
-
do {
|
|
2844
|
-
const end = chunk.end;
|
|
2845
|
-
const aborted = chunk.trimStart(rx);
|
|
2846
|
-
|
|
2847
|
-
if (chunk.end !== end) {
|
|
2848
|
-
// special case...
|
|
2849
|
-
if (chunk === this.lastChunk) this.lastChunk = chunk.next;
|
|
2850
|
-
|
|
2851
|
-
this.byEnd[chunk.end] = chunk;
|
|
2852
|
-
this.byStart[chunk.next.start] = chunk.next;
|
|
2853
|
-
this.byEnd[chunk.next.end] = chunk.next;
|
|
2854
|
-
}
|
|
2855
|
-
|
|
2856
|
-
if (aborted) return true;
|
|
2857
|
-
chunk = chunk.next;
|
|
2858
|
-
} while (chunk);
|
|
2859
|
-
|
|
2860
|
-
return false;
|
|
2861
|
-
}
|
|
2862
|
-
|
|
2863
|
-
trimStart(charType) {
|
|
2864
|
-
this.trimStartAborted(charType);
|
|
2865
|
-
return this;
|
|
2866
|
-
}
|
|
2867
|
-
|
|
2868
|
-
hasChanged() {
|
|
2869
|
-
return this.original !== this.toString();
|
|
2870
|
-
}
|
|
2871
|
-
|
|
2872
|
-
_replaceRegexp(searchValue, replacement) {
|
|
2873
|
-
function getReplacement(match, str) {
|
|
2874
|
-
if (typeof replacement === 'string') {
|
|
2875
|
-
return replacement.replace(/\$(\$|&|\d+)/g, (_, i) => {
|
|
2876
|
-
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace#specifying_a_string_as_a_parameter
|
|
2877
|
-
if (i === '$') return '$';
|
|
2878
|
-
if (i === '&') return match[0];
|
|
2879
|
-
const num = +i;
|
|
2880
|
-
if (num < match.length) return match[+i];
|
|
2881
|
-
return `$${i}`;
|
|
2882
|
-
});
|
|
2883
|
-
} else {
|
|
2884
|
-
return replacement(...match, match.index, str, match.groups);
|
|
2885
|
-
}
|
|
2886
|
-
}
|
|
2887
|
-
function matchAll(re, str) {
|
|
2888
|
-
let match;
|
|
2889
|
-
const matches = [];
|
|
2890
|
-
while ((match = re.exec(str))) {
|
|
2891
|
-
matches.push(match);
|
|
2892
|
-
}
|
|
2893
|
-
return matches;
|
|
2894
|
-
}
|
|
2895
|
-
if (searchValue.global) {
|
|
2896
|
-
const matches = matchAll(searchValue, this.original);
|
|
2897
|
-
matches.forEach((match) => {
|
|
2898
|
-
if (match.index != null) {
|
|
2899
|
-
const replacement = getReplacement(match, this.original);
|
|
2900
|
-
if (replacement !== match[0]) {
|
|
2901
|
-
this.overwrite(match.index, match.index + match[0].length, replacement);
|
|
2902
|
-
}
|
|
2903
|
-
}
|
|
2904
|
-
});
|
|
2905
|
-
} else {
|
|
2906
|
-
const match = this.original.match(searchValue);
|
|
2907
|
-
if (match && match.index != null) {
|
|
2908
|
-
const replacement = getReplacement(match, this.original);
|
|
2909
|
-
if (replacement !== match[0]) {
|
|
2910
|
-
this.overwrite(match.index, match.index + match[0].length, replacement);
|
|
2911
|
-
}
|
|
2912
|
-
}
|
|
2913
|
-
}
|
|
2914
|
-
return this;
|
|
2915
|
-
}
|
|
2916
|
-
|
|
2917
|
-
_replaceString(string, replacement) {
|
|
2918
|
-
const { original } = this;
|
|
2919
|
-
const index = original.indexOf(string);
|
|
2920
|
-
|
|
2921
|
-
if (index !== -1) {
|
|
2922
|
-
if (typeof replacement === 'function') {
|
|
2923
|
-
replacement = replacement(string, index, original);
|
|
2924
|
-
}
|
|
2925
|
-
if (string !== replacement) {
|
|
2926
|
-
this.overwrite(index, index + string.length, replacement);
|
|
2927
|
-
}
|
|
2928
|
-
}
|
|
2929
|
-
|
|
2930
|
-
return this;
|
|
2931
|
-
}
|
|
2932
|
-
|
|
2933
|
-
replace(searchValue, replacement) {
|
|
2934
|
-
if (typeof searchValue === 'string') {
|
|
2935
|
-
return this._replaceString(searchValue, replacement);
|
|
2936
|
-
}
|
|
2937
|
-
|
|
2938
|
-
return this._replaceRegexp(searchValue, replacement);
|
|
2939
|
-
}
|
|
2940
|
-
|
|
2941
|
-
_replaceAllString(string, replacement) {
|
|
2942
|
-
const { original } = this;
|
|
2943
|
-
const stringLength = string.length;
|
|
2944
|
-
for (
|
|
2945
|
-
let index = original.indexOf(string);
|
|
2946
|
-
index !== -1;
|
|
2947
|
-
index = original.indexOf(string, index + stringLength)
|
|
2948
|
-
) {
|
|
2949
|
-
const previous = original.slice(index, index + stringLength);
|
|
2950
|
-
let _replacement = replacement;
|
|
2951
|
-
if (typeof replacement === 'function') {
|
|
2952
|
-
_replacement = replacement(previous, index, original);
|
|
2953
|
-
}
|
|
2954
|
-
if (previous !== _replacement) this.overwrite(index, index + stringLength, _replacement);
|
|
2955
|
-
}
|
|
2956
|
-
|
|
2957
|
-
return this;
|
|
2958
|
-
}
|
|
2959
|
-
|
|
2960
|
-
replaceAll(searchValue, replacement) {
|
|
2961
|
-
if (typeof searchValue === 'string') {
|
|
2962
|
-
return this._replaceAllString(searchValue, replacement);
|
|
2963
|
-
}
|
|
2964
|
-
|
|
2965
|
-
if (!searchValue.global) {
|
|
2966
|
-
throw new TypeError(
|
|
2967
|
-
'MagicString.prototype.replaceAll called with a non-global RegExp argument',
|
|
2968
|
-
);
|
|
2969
|
-
}
|
|
2970
|
-
|
|
2971
|
-
return this._replaceRegexp(searchValue, replacement);
|
|
2972
|
-
}
|
|
1798
|
+
async function transform(code, cache, id, context, opt) {
|
|
1799
|
+
const scriptTag = code.raw.find(node => {
|
|
1800
|
+
return node.name == "script";
|
|
1801
|
+
});
|
|
1802
|
+
if (!scriptTag)
|
|
1803
|
+
throw new Error("[transform check]: not found mcx script tag");
|
|
1804
|
+
const transformContext = {
|
|
1805
|
+
rollupContext: context,
|
|
1806
|
+
impAST: [],
|
|
1807
|
+
currentAST: t.program([]),
|
|
1808
|
+
opt,
|
|
1809
|
+
currentId: id,
|
|
1810
|
+
compiledCode: code,
|
|
1811
|
+
cache,
|
|
1812
|
+
scriptTag: scriptTag,
|
|
1813
|
+
mainFn: {
|
|
1814
|
+
param: [],
|
|
1815
|
+
body: []
|
|
1816
|
+
}
|
|
1817
|
+
};
|
|
1818
|
+
return await _transform(transformContext);
|
|
2973
1819
|
}
|
|
2974
1820
|
|
|
2975
|
-
const cache = new Map();
|
|
2976
1821
|
function mcxPlugn(opt) {
|
|
1822
|
+
let cache = new Map();
|
|
2977
1823
|
return {
|
|
2978
1824
|
name: "mbler-mcx-core",
|
|
2979
1825
|
async resolveId(id, imp) {
|
|
@@ -3016,22 +1862,56 @@ function mcxPlugn(opt) {
|
|
|
3016
1862
|
if (err instanceof CompileError) {
|
|
3017
1863
|
const error = err;
|
|
3018
1864
|
this.error(error.message, {
|
|
3019
|
-
column: error.loc.
|
|
1865
|
+
column: error.loc.column,
|
|
3020
1866
|
line: error.loc.line,
|
|
3021
1867
|
});
|
|
3022
1868
|
}
|
|
3023
|
-
this.error(err
|
|
1869
|
+
this.error(String(err));
|
|
3024
1870
|
}
|
|
3025
1871
|
compileData.setFilePath(id);
|
|
1872
|
+
const compiledCode = await transform(compileData, cache, id, this, opt);
|
|
3026
1873
|
return {
|
|
3027
|
-
code:
|
|
1874
|
+
code: compiledCode,
|
|
3028
1875
|
map: magic.generateMap({ hires: true, source: id }),
|
|
3029
1876
|
};
|
|
3030
1877
|
}
|
|
3031
1878
|
return null;
|
|
3032
1879
|
},
|
|
1880
|
+
buildEnd() {
|
|
1881
|
+
cache.clear();
|
|
1882
|
+
},
|
|
1883
|
+
buildStart() {
|
|
1884
|
+
cache = new Map();
|
|
1885
|
+
}
|
|
3033
1886
|
};
|
|
3034
1887
|
}
|
|
1888
|
+
function AbsoluteJoin(base, dir) {
|
|
1889
|
+
return path.isAbsolute(dir) ? dir : path.join(base, dir);
|
|
1890
|
+
}
|
|
1891
|
+
async function CompileProject(opt) {
|
|
1892
|
+
const rollupResult = await rollup.rollup({
|
|
1893
|
+
input: opt.main,
|
|
1894
|
+
// only minecraft package
|
|
1895
|
+
external: ["@minecraft/server", "@minecraft/server-ui"],
|
|
1896
|
+
plugins: [
|
|
1897
|
+
mcxPlugn(opt),
|
|
1898
|
+
commjs(),
|
|
1899
|
+
json(),
|
|
1900
|
+
module_resolve({
|
|
1901
|
+
modulePaths: [opt.moduleDir],
|
|
1902
|
+
}),
|
|
1903
|
+
],
|
|
1904
|
+
});
|
|
1905
|
+
// only index.js
|
|
1906
|
+
await fs.rm(opt.output, {
|
|
1907
|
+
recursive: true,
|
|
1908
|
+
});
|
|
1909
|
+
await rollupResult.write({
|
|
1910
|
+
file: AbsoluteJoin(opt.output, "./index.js"),
|
|
1911
|
+
format: "esm",
|
|
1912
|
+
sourcemap: true,
|
|
1913
|
+
});
|
|
1914
|
+
}
|
|
3035
1915
|
|
|
3036
1916
|
/**
|
|
3037
1917
|
* @description - this is a function factory to generate mcxProject
|
|
@@ -3057,7 +1937,7 @@ class Compile {
|
|
|
3057
1937
|
await fs.mkdir(this.BuildOpt.moduleDir, {
|
|
3058
1938
|
recursive: true,
|
|
3059
1939
|
});
|
|
3060
|
-
await
|
|
1940
|
+
await CompileProject(this.BuildOpt);
|
|
3061
1941
|
}
|
|
3062
1942
|
}
|
|
3063
1943
|
|
|
@@ -3069,18 +1949,152 @@ var types = /*#__PURE__*/Object.freeze({
|
|
|
3069
1949
|
__proto__: null
|
|
3070
1950
|
});
|
|
3071
1951
|
|
|
3072
|
-
|
|
3073
|
-
|
|
3074
|
-
|
|
3075
|
-
|
|
3076
|
-
|
|
3077
|
-
|
|
1952
|
+
/**
|
|
1953
|
+
* MCX Volar TSC 插件
|
|
1954
|
+
* 为 MCX 文件提供 TypeScript 智能感知支持
|
|
1955
|
+
*/
|
|
1956
|
+
const mcxVolarTscPlugin = {
|
|
1957
|
+
getLanguageId(scriptId) {
|
|
1958
|
+
if (scriptId.path.endsWith('.mcx')) {
|
|
1959
|
+
return 'mcx';
|
|
1960
|
+
}
|
|
1961
|
+
return undefined;
|
|
1962
|
+
},
|
|
3078
1963
|
};
|
|
1964
|
+
/**
|
|
1965
|
+
* MCX 虚拟代码
|
|
1966
|
+
* 用于在 Volar 中表示 MCX 文件的内容
|
|
1967
|
+
*/
|
|
1968
|
+
class MCXVirtualCode {
|
|
1969
|
+
snapshot;
|
|
1970
|
+
id;
|
|
1971
|
+
languageId = 'mcx';
|
|
1972
|
+
mappings;
|
|
1973
|
+
embeddedCodes = [];
|
|
1974
|
+
constructor(snapshot, id = 'root') {
|
|
1975
|
+
this.snapshot = snapshot;
|
|
1976
|
+
this.id = id;
|
|
1977
|
+
const content = snapshot.getText(0, snapshot.getLength());
|
|
1978
|
+
// 基础映射:整个文件
|
|
1979
|
+
this.mappings = [{
|
|
1980
|
+
sourceOffsets: [0],
|
|
1981
|
+
generatedOffsets: [0],
|
|
1982
|
+
lengths: [snapshot.getLength()],
|
|
1983
|
+
data: {
|
|
1984
|
+
verification: true,
|
|
1985
|
+
completion: true,
|
|
1986
|
+
semantic: true,
|
|
1987
|
+
navigation: true,
|
|
1988
|
+
structure: true,
|
|
1989
|
+
format: true,
|
|
1990
|
+
}
|
|
1991
|
+
}];
|
|
1992
|
+
// 尝试提取 script 标签内容并创建嵌入式 JS/TS 代码
|
|
1993
|
+
try {
|
|
1994
|
+
const embeddedCode = this.extractScriptContent(content);
|
|
1995
|
+
if (embeddedCode) {
|
|
1996
|
+
this.embeddedCodes.push(embeddedCode);
|
|
1997
|
+
}
|
|
1998
|
+
}
|
|
1999
|
+
catch {
|
|
2000
|
+
// 解析失败时忽略嵌入式代码
|
|
2001
|
+
}
|
|
2002
|
+
}
|
|
2003
|
+
/**
|
|
2004
|
+
* 从 MCX 文件中提取 script 标签内容
|
|
2005
|
+
*/
|
|
2006
|
+
extractScriptContent(content) {
|
|
2007
|
+
try {
|
|
2008
|
+
const ast = new AST.tag(content);
|
|
2009
|
+
const nodes = ast.data;
|
|
2010
|
+
// 查找 script 标签
|
|
2011
|
+
for (const node of nodes) {
|
|
2012
|
+
if (node.name === 'script') {
|
|
2013
|
+
const scriptContent = this.extractContent(node);
|
|
2014
|
+
if (scriptContent) {
|
|
2015
|
+
const scriptStart = this.findScriptStart(content);
|
|
2016
|
+
const isTypeScript = node.arr?.lang === 'ts';
|
|
2017
|
+
return {
|
|
2018
|
+
id: 'script',
|
|
2019
|
+
languageId: isTypeScript ? 'typescript' : 'javascript',
|
|
2020
|
+
snapshot: {
|
|
2021
|
+
getText: (start, end) => scriptContent.slice(start, end),
|
|
2022
|
+
getLength: () => scriptContent.length,
|
|
2023
|
+
getChangeRange: () => undefined,
|
|
2024
|
+
},
|
|
2025
|
+
mappings: [{
|
|
2026
|
+
sourceOffsets: [scriptStart],
|
|
2027
|
+
generatedOffsets: [0],
|
|
2028
|
+
lengths: [scriptContent.length],
|
|
2029
|
+
data: {
|
|
2030
|
+
verification: true,
|
|
2031
|
+
completion: true,
|
|
2032
|
+
semantic: true,
|
|
2033
|
+
navigation: true,
|
|
2034
|
+
structure: true,
|
|
2035
|
+
format: true,
|
|
2036
|
+
}
|
|
2037
|
+
}],
|
|
2038
|
+
embeddedCodes: [],
|
|
2039
|
+
};
|
|
2040
|
+
}
|
|
2041
|
+
}
|
|
2042
|
+
}
|
|
2043
|
+
}
|
|
2044
|
+
catch {
|
|
2045
|
+
// 解析失败
|
|
2046
|
+
}
|
|
2047
|
+
return null;
|
|
2048
|
+
}
|
|
2049
|
+
/**
|
|
2050
|
+
* 提取标签内容
|
|
2051
|
+
*/
|
|
2052
|
+
extractContent(node) {
|
|
2053
|
+
if (!node.content)
|
|
2054
|
+
return '';
|
|
2055
|
+
return node.content
|
|
2056
|
+
.map(item => {
|
|
2057
|
+
if (item.type === 'TagContent') {
|
|
2058
|
+
return item.data;
|
|
2059
|
+
}
|
|
2060
|
+
return '';
|
|
2061
|
+
})
|
|
2062
|
+
.join('');
|
|
2063
|
+
}
|
|
2064
|
+
/**
|
|
2065
|
+
* 查找 script 标签在源文件中的起始位置
|
|
2066
|
+
*/
|
|
2067
|
+
findScriptStart(content) {
|
|
2068
|
+
const scriptMatch = content.match(/<script[^>]*>([\s\S]*?)<\/script>/);
|
|
2069
|
+
if (scriptMatch && scriptMatch.index !== undefined) {
|
|
2070
|
+
// 返回 script 内容的开始位置(跳过开始标签)
|
|
2071
|
+
const tagEnd = content.indexOf('>', scriptMatch.index);
|
|
2072
|
+
return tagEnd + 1;
|
|
2073
|
+
}
|
|
2074
|
+
return 0;
|
|
2075
|
+
}
|
|
2076
|
+
}
|
|
2077
|
+
/**
|
|
2078
|
+
* 创建 MCX 虚拟代码实例
|
|
2079
|
+
*/
|
|
2080
|
+
function createMCXVirtualCode(snapshot, id) {
|
|
2081
|
+
return new MCXVirtualCode(snapshot, id);
|
|
2082
|
+
}
|
|
2083
|
+
|
|
2084
|
+
var index = /*#__PURE__*/Object.freeze({
|
|
2085
|
+
__proto__: null,
|
|
2086
|
+
MCXVirtualCode: MCXVirtualCode,
|
|
2087
|
+
createMCXVirtualCode: createMCXVirtualCode,
|
|
2088
|
+
mcxVolarTscPlugin: mcxVolarTscPlugin
|
|
2089
|
+
});
|
|
3079
2090
|
|
|
3080
2091
|
exports.AST = AST;
|
|
3081
|
-
exports.Compiler =
|
|
2092
|
+
exports.Compiler = index$2;
|
|
3082
2093
|
exports.PUBTYPE = types;
|
|
3083
|
-
exports.
|
|
2094
|
+
exports.TSC = index;
|
|
2095
|
+
exports.compile = CompileMcxDir;
|
|
2096
|
+
exports.compile_component = index$1;
|
|
2097
|
+
exports.plugin = mcxPlugn;
|
|
3084
2098
|
exports.transform = transform;
|
|
3085
2099
|
exports.utils = McxUtlis;
|
|
3086
2100
|
//# sourceMappingURL=index.js.map
|