efront 4.0.35 → 4.0.38

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.
@@ -245,8 +245,8 @@ var killCircle = function () {
245
245
  // -->
246
246
  var hasOwnProperty = {}.hasOwnProperty;
247
247
  var loadModule = function (url, then, prebuilds = {}) {
248
- var name = url.replace(/[\*~][\s\S]*$/, '');
249
- if (/^(?:module|exports|define|require|window|global|undefined)$/.test(name)) return then();
248
+ var name = url.replace(/[\#\*~\?][\s\S]*$/, '');
249
+ if (/^(?:module|exports|define|import_meta|require|window|global|undefined)$/.test(name)) return then();
250
250
  if ((hasOwnProperty.call(prebuilds, url)) || hasOwnProperty.call(modules, url) || (!hasOwnProperty.call(forceRequest, name) && !/^on/.test(name) && window[name] !== null && window[name] !== void 0)
251
251
  ) return then();
252
252
  preLoad(url);
@@ -383,49 +383,56 @@ var getArgs = function (text, aftfix) {
383
383
  return [argNames || [], functionBody, args || [], required || '', strs || [], !!isAsync, !!isYield];
384
384
  };
385
385
  var get_relatives = function (name, required, prefix = "") {
386
- var required_base = name.replace(/[^\/\$]+$/, "");
387
- required_base = required_base.replace(/^\.?[\/\$]+/, "");
388
- var is_page = /^\//.test(name);
389
386
  return required.map(r => {
390
- var r1 = r;
391
- var base = required_base;
392
- if (/^\.*[\/]/.test(r1)) {
393
- r1 = r1.replace(/^\.\//, '');
394
- while (/\.\.[\/\$]/.test(r1)) {
395
- if (/^[\\\/\$\.]*$/.test(base)) {
396
- break;
397
- }
398
- base = base.replace(/[^\/\$]*[\/\$]$/, '');
399
- r1 = r1.slice(3);
400
- }
401
- base = base.replace(/^[\/\$]/, '');
402
- if (/^\//.test(r1)) {
403
- base = '';
404
- r1 = r1.slice(1);
405
- }
406
- if (is_page) {
407
- base = "/" + base;
408
- }
409
- if (!/^\.*\//.test(base)) {
410
- base = prefix + base;
411
- }
412
- if (prefix) {
413
- base = base.replace(/\$/g, "/");
414
- r1 = r1.replace(/\$/g, '/');
415
- } else {
416
- base = base.replace(/\//g, "$");
417
- r1 = r1.replace(/\//g, '$');
387
+ return resolve(r, name, prefix);
388
+ });
389
+ };
390
+ function resolve(r1, base, prefix = '') {
391
+ var is_page = /^\//.test(base);
392
+ base = base.replace(/[^\/\$]+$/, "").replace(/^\.?[\/\$]+/, "");
393
+ if (/^\.*[\/]/.test(r1)) {
394
+ r1 = r1.replace(/^\.\//, '');
395
+ while (/\.\.[\/\$]/.test(r1)) {
396
+ if (/^[\\\/\$\.]*$/.test(base)) {
397
+ break;
418
398
  }
419
- var r2 = base + r1;
420
- } else {
421
- var r2 = r1.replace(/\//g, '$');
399
+ base = base.replace(/[^\/\$]*[\/\$]$/, '');
400
+ r1 = r1.slice(3);
401
+ }
402
+ base = base.replace(/^[\/\$]/, '');
403
+ if (/^\//.test(r1)) {
404
+ base = '';
405
+ r1 = r1.slice(1);
422
406
  }
423
407
  if (is_page) {
424
- r2 = r2.replace(/\$([\s\S])/g, '/$1');
408
+ base = "/" + base;
425
409
  }
426
- return r2;
427
- });
428
- };
410
+ if (!/^\.*\//.test(base)) {
411
+ base = prefix + base;
412
+ }
413
+ if (prefix) {
414
+ base = base.replace(/\$/g, "/");
415
+ r1 = r1.replace(/\$/g, '/');
416
+ } else {
417
+ base = base.replace(/\//g, "$");
418
+ r1 = r1.replace(/\//g, '$');
419
+ }
420
+ var r2 = base + r1;
421
+ } else {
422
+ var r2 = r1.replace(/\//g, '$');
423
+ }
424
+ if (is_page) {
425
+ r2 = r2.replace(/\$([\s\S])/g, '/$1');
426
+ }
427
+ return r2;
428
+
429
+ }
430
+ function Meta(url) {
431
+ this.url = url;
432
+ }
433
+ Meta.prototype.resolve = function (url) {
434
+ return resolve(url, this.url);
435
+ }
429
436
  var createModule = function (exec, originNames, compiledNames, prebuilds = {}) {
430
437
  var module = {};
431
438
  var exports = module.exports = {};
@@ -433,7 +440,7 @@ var createModule = function (exec, originNames, compiledNames, prebuilds = {}) {
433
440
  var required = exec.required;
434
441
  if (required) required = required.map(a => loadedModules[keyprefix + a]);
435
442
  var argsList = originNames.map(function (aName) {
436
- var argName = aName.replace(/[\*~][\s\S]*$/, '');
443
+ var argName = aName.replace(/[\#\*~\?][\s\S]*$/, '');
437
444
  if (hasOwnProperty.call(prebuilds, argName)) {
438
445
  return prebuilds[argName];
439
446
  }
@@ -445,6 +452,9 @@ var createModule = function (exec, originNames, compiledNames, prebuilds = {}) {
445
452
  isModuleInit = true;
446
453
  return exports;
447
454
  }
455
+ if (argName === 'import_meta') {
456
+ return new Meta(exec.file);
457
+ }
448
458
  if (/^(?:window|global|undefined)$/.test(argName)) return window[argName];
449
459
  if (argName === "require") {
450
460
  let r = function (refer) {
@@ -510,7 +520,7 @@ var init = function (url, then, prebuilds) {
510
520
  if (then) then(modules[url]);
511
521
  return modules[url];
512
522
  }
513
- var name = url.replace(/[\*~][\s\S]*$/, '');
523
+ var name = url.replace(/[\#\*~\?][\s\S]*$/, '');
514
524
  if (!hasOwnProperty.call(forceRequest, name) && name in window && !/^on/.test(name)) {
515
525
  try {
516
526
  var value = window[name];
@@ -26,7 +26,10 @@ var split = function (s, n) {
26
26
  return r;
27
27
  };
28
28
  var fixme = function (neg, res, nl) {
29
- if (nl > 0) res = res.slice(0, res.length - nl) + "." + res.slice(res.length - nl).replace(/0+$/, '');
29
+ if (nl > 0) {
30
+ if (res.length < nl) res = repeat0(nl - res.length) + res;
31
+ res = res.slice(0, res.length - nl) + "." + res.slice(res.length - nl).replace(/0+$/, '');
32
+ }
30
33
  res = res.replace(/^0+(?!\.)/, '');
31
34
  if (/^\./.test(res)) res = '0' + res;
32
35
  if (neg) res = '-' + res;
@@ -55,15 +58,71 @@ var fixde = function (numstr, fractionDigits, compare) {
55
58
  if (neg) res = '-' + res;
56
59
  return res;
57
60
  };
61
+ var vmap = Object.create(null);
62
+ var vsrc = [];
63
+ var adds = function (s, c) {
64
+ for (var cx = 0, dx = s.length; cx < dx; cx++) {
65
+ vmap[s.charAt(cx)] = c + cx;
66
+ vsrc[c + cx] = s.charAt(cx);
67
+ }
68
+ }
69
+ adds("0123456789", 0);
70
+ adds("abcdefghijklmnopqrstuvwxyz", 10);
58
71
  class BigNumber {
59
- constructor(value) {
72
+ constructor(value, system_scale) {
60
73
  if (!this || this.constructor !== BigNumber) {
61
- return new BigNumber(value);
74
+ return new BigNumber(value, system_scale);
75
+ }
76
+ system_scale = system_scale | 0;
77
+ if (!system_scale) system_scale = 10;
78
+ if (system_scale <= 1 || system_scale > 36) throw new Error("进制错误!");
79
+ var num = '0';
80
+ var dotOccurs;
81
+ var scale = system_scale;
82
+ if (system_scale <= 36) {
83
+ value = value.toLowerCase();
62
84
  }
63
- this.value = value;
85
+ for (var v of value) {
86
+ if (v === '.') {
87
+ dotOccurs = true;
88
+ continue;
89
+ }
90
+ if (v === '_') continue;
91
+ if (v === ',') continue;
92
+ if (dotOccurs) {
93
+ num = BigNumber.add(num, BigNumber.div(vmap[v], scale, BigNumber.DECIMAL_DIGIT))
94
+ scale = BigNumber.prd(scale, system_scale);
95
+ }
96
+ else {
97
+ num = BigNumber.add(BigNumber.prd(num, scale), vmap[v]);
98
+ }
99
+ }
100
+ this.value = num;
64
101
  }
65
- toString() {
66
- return this.value;
102
+ static DECIMAL_DIGIT = 120;
103
+ toString(system_scale) {
104
+ system_scale |= 0;
105
+ if (!system_scale || system_scale === 10) return this.value;
106
+ if (system_scale <= 1 || system_scale > 36) throw new Error("进制错误!");
107
+ var [s, n, m] = prepare(this.value);
108
+ var dist = [];
109
+ while (n && n !== "0") {
110
+ var n0 = BigNumber.div(n, system_scale, 0);
111
+ var a = BigNumber.sub(n, BigNumber.prd(n0, system_scale));
112
+ n = n0;
113
+ dist.unshift(vsrc[+a]);
114
+ }
115
+ if (m && m !== "0") {
116
+ var c = 0;
117
+ dist.push('.');
118
+ while (m !== "0") {
119
+ [a, m = '0'] = BigNumber.prd("0." + m, system_scale).split('.');
120
+ dist.push(vsrc[+a]);
121
+ if (++c > BigNumber.DECIMAL_DIGIT || !m) break;
122
+ }
123
+ }
124
+ if (s) dist.unshift('-');
125
+ return dist.join('');
67
126
  };
68
127
  add(bignumber) {
69
128
  return new BigNumber(BigNumber.add(this.value, bignumber));
@@ -79,8 +138,8 @@ class BigNumber {
79
138
  }
80
139
  static fix(numstr, fractionDigits) {
81
140
  fractionDigits = +fractionDigits || 0;
82
- if (fractionDigits < 0 || fractionDigits > 100) {
83
- throw new Error("小数位数只能是0和100之间的数字");
141
+ if (fractionDigits < 0 || fractionDigits > BigNumber.DECIMAL_DIGIT) {
142
+ throw new Error(`小数位数只能是0和${BigNumber.DECIMAL_DIGIT}之间的数字`);
84
143
  }
85
144
  return fixde(numstr, fractionDigits, 4);
86
145
  }
@@ -67,4 +67,6 @@ assert(BigNumber.div("9007199254740992.2345678901", 0.001, 6), "9007199254740992
67
67
  assert(BigNumber.div("9007199254740992.2345678901", "9007199254740992.2345678901", 6), "1.000000");
68
68
  assert(BigNumber.div("9007199254740992.2345678901", "90071992547409922345678.901", 6), "0.000000");
69
69
  assert(BigNumber.div("9007199254740992.2345678901", "900719925474099223456.78901", 6), "0.000010");
70
- assert(BigNumber.div("99999", "9", 6), "11111.000000");
70
+ assert(BigNumber.div("99999", "9", 6), "11111.000000");
71
+ assert(new BigNumber("1.23", 8).toString(), "1.296875");
72
+ assert(new BigNumber("1.23", 8).toString(8), "1.23");
@@ -0,0 +1,3 @@
1
+ function nullish_(a, b) {
2
+ return a === null || a === undefined ? b : a;
3
+ }
@@ -0,0 +1,14 @@
1
+ var BigInt = window.BigInt;
2
+ return BigInt ? function power_(a, b) {
3
+ if (typeof a !== 'bigint') {
4
+ return Math.pow(a, b);
5
+ }
6
+ var u = BigInt(1);
7
+ var result = u;
8
+ while (b) {
9
+ if (b & u) result *= a;
10
+ a *= a;
11
+ b >>= u;
12
+ }
13
+ return result;
14
+ } : Math.pow;
@@ -11,7 +11,16 @@
11
11
  import(...)
12
12
  ```
13
13
  The result imported with `import (...)`, efront will not actively wrap a layer of Promise. If you use `await` in the root scope of the module, the returned result is an instance of `Promise`. Otherwise, what you export in the imported file will be the result of this `import(...)`. If you are unsure about the content of the imported file and do not blindly use methods such as `import(...).then (...)`, you can use `await import(...)` to wait for the import to complete.
14
+
14
15
  3. ```javascript
16
+ import.meta
17
+ import.meta.url
18
+ import.meta.resolve()
19
+ new.target
20
+ ```
21
+ If the above features are used, the compilation can be successful, but it is inconsistent with the content of the native high-level code. Where `import.meta.url` will be the relative path (excluding` file:///... `), and does not include `?` or `#`. the `new.target` will always be `undefined` and should not be used as much as possible.
22
+
23
+ 1. ```javascript
15
24
  (function (a){
16
25
  if (a === void 0) a = 1;
17
26
  a = 1;
@@ -29,7 +38,7 @@
29
38
  ```
30
39
  `arguments` that are not in strict mode and do not have default values will be changed by statements in the code, while the other two cases will not. When the `efront` and `typescript` move the default value assignment statement into the function body, they do not handle this detail, that is, the original read-only `arguments` may be changed by the statement inside the function. Some of the components provided in efront may also have issues that prevent them from being downgraded for use. If you find any related issues, please feel free to provide feedback to me and I will handle them as soon as possible.
31
40
 
32
- 4. ```javascript
41
+ 2. ```javascript
33
42
  async function () {
34
43
  await ...;
35
44
  arguments;
@@ -12,6 +12,14 @@
12
12
  ```
13
13
  用`import(...)`导入的结果,efront不会主动包装一层Promise,如果你在模块的根作用域中中使用了`await`,返回结果就是一个`Promise`的实例,否则你在导入的文件内导出了什么,这个`import(...)`的结果就是什么。如果你不确定导入文件的内容,不盲目使用`import(...).then(...)`这类的方法,可以使用`await import(...)`等待导入完成。
14
14
  3. ```javascript
15
+ import.meta
16
+ import.meta.url
17
+ import.meta.resolve()
18
+ new.target
19
+ ```
20
+ 如果用到以上几个特性,可编译成功,但与原生高级代码的内容不一致。其中`import.meta.url`将是相对路径(不含`file:///...`),且不包含`?`或`#`的参数部分,new.target将始终为`undefined`,尽量不要使用。
21
+
22
+ 4. ```javascript
15
23
  (function (a){
16
24
  if (a === void 0) a = 1;
17
25
  a = 1;
@@ -29,7 +37,7 @@
29
37
  ```
30
38
  非严格模式且没有默认值的`arguments`是会被代码中的语句改掉的,而其他两种情况不会。`efront`和`typescript`在把默认值赋值的语句移动到函数体内时,都没有处理这一细节,即原来只读的`arguments`可能被函数内的语句改掉。`efront`内提供的一些组件,可能也会有一部分有因此而无法降级使用的问题,如果您发现了相关的问题,可以向我反馈,我会尽快处理。
31
39
 
32
- 4. ```javascript
40
+ 5. ```javascript
33
41
  async function () {
34
42
  await ...;
35
43
  arguments;
@@ -42,7 +50,7 @@
42
50
  ```
43
51
  `typescript` 转换这两类新型函数后,`arguments`对象的内容有误。这不是一个难解决的问题,应该只是`typescript`已发现但不愿解决的问题。`efront`在降级编译时临时使用变量重命名的方法对代码中的`arguments`进行替换使其内容与原生高级代码一致。
44
52
 
45
- 5. ```javascript
53
+ 6. ```javascript
46
54
  Object.keys
47
55
  Object.create
48
56
  Array.prototype.map
@@ -53,7 +61,7 @@
53
61
  Function.prototype.bind
54
62
  ```
55
63
  以上几个方法`ie9+`系列浏览器已支持,但`ie8`及以下版本不支持,如果没有指定`--no-polyfill`参数`efront`在降级编译期会使用`[]map.js`中提供的方法进行修补,这些方法会在加载器检测到浏览器不支持`[].map`时进行初始化
56
- 6. ```javascript
64
+ 7. ```javascript
57
65
  Array.prototype.fill
58
66
  Array(3).fill(0) // 类似这种的将变成[0,0,0]一个常量数组
59
67
  var [a,b,c]=Array(3).fill(0).map((_,i)=>i+1) // 类似这种用于生成常量并赋值的,将直接变成赋值语句 var a=1,b=2,c=3
@@ -61,11 +69,11 @@
61
69
  ```
62
70
  `Array(...).fill(...).map(...)`这种写法经常被`efront`开发者用来生成自增赋值序列,并且非所有运行环境都支持,所以包括其它显式用到`Array.prototype.fill`的几种写法都会被替换。为了目标代码的性能考虑,这种替换在自动常量化之前就要执行,所以不再支持用`polyfill`的开关进行关闭。如果要关闭,请使用参数`--no-autoeval`将自动常量化的功能一同关闭。
63
71
 
64
- 7. ```javascript
72
+ 8. ```javascript
65
73
  Object.assign
66
74
  ```
67
75
  Object.assign,`ie`系列浏览器均不支持,由于经常被`efront`开发者使用,在降级编译期,如果没有指定`--no-polyfill`参数,将由`efront`处理成替代品[extend](../basic/extend.js)
68
- 8. ```javascript
76
+ 9. ```javascript
69
77
  Promise
70
78
  Promise.prototype.then
71
79
  Promise.prototype.catch
@@ -75,13 +83,13 @@
75
83
  Promise.resolve
76
84
  ```
77
85
  `Promise`对象也是`ie`系列浏览器均不支持的。`efront`实现的`Promise`与原生的特性并不一致,仅在运行环境不支持的时候进行替代。比如由`.then`触发的方法与`setTimeout`触发的方法执行的先后顺序会与高级的运行环境有所区别,但也会保持在当前语境执行后再执行相关的语句。以上没有提到的`Promise`相关的方法均不支持,如`Promise.prototype.finally`,如果您使用了这些缺失的特性,就只能自己实现或找类似[core-js](https://github.com/zloirock/core-js)的库填充了
78
- 9. ```javascript
86
+ 10. ```javascript
79
87
  obj.if
80
88
  obj.catch
81
89
  obj.for
82
90
  ```
83
91
  类似这种用`.`取属性的语句,由于属性名与`js`的保留字一样,`ie6`等浏览器会报错,但您可以在`efront`提供的环境中放心使用。因为`efront`本身就会把取属性的语句处理掉。
84
- 10. `ie8`及以下浏览器中存在的一些与现代`js`标准不同的特性,`efront`提供的组件可能不兼容,在为这类环境进行应用开发时,应避免使用。
92
+ 11. `ie8`及以下浏览器中存在的一些与现代`js`标准不同的特性,`efront`提供的组件可能不兼容,在为这类环境进行应用开发时,应避免使用。
85
93
  ```javascript
86
94
  Object.defineProperty(...);
87
95
  ({
@@ -0,0 +1,7 @@
1
+ function restIter_(iter) {
2
+ var rest = [];
3
+ for (var a = iter.next(); !a.done; a = iter.next()) {
4
+ rest.push(a.value);
5
+ }
6
+ return rest;
7
+ }
@@ -675,12 +675,17 @@ Javascript.prototype.fix = function (code) {
675
675
  code.envs.require = true;
676
676
  }
677
677
  var requires = code.used.require;
678
- imports.forEach(m => {
679
- m.text = 'require';
678
+ imports = imports.filter(m => {
679
+ if (/^import\.meta($|\.)/.test(m.text)) {
680
+ m.text = m.text.replace(/\./, '_');
681
+ return true;
682
+ }
683
+ m.text = m.text.replace(/^import/g, 'require');
680
684
  requires.push(m);
681
685
  });
682
686
  delete code.used.import;
683
687
  delete code.envs.import;
688
+ if (imports.length) code.used.import_meta = imports;
684
689
  }
685
690
  if (code.exportDecs) {
686
691
  var exportDecs = code.exportDecs;
@@ -11,3 +11,4 @@ testFix(`import("a")`, 'require("a")');
11
11
  testFix(`import "windows.inc"`, 'require("windows.inc")');
12
12
  testFix(`import "windows.inc";import "abc.inc";`, 'require("windows.inc"); require("abc.inc");');
13
13
  testFix(`import "windows.inc";\r\nimport "abc.inc";`, 'require("windows.inc");\r\nrequire("abc.inc");');
14
+ testFix(`console.log(import.meta)`, `console.log(import_meta)`);
@@ -498,7 +498,6 @@ var createScoped = function (parsed, wash) {
498
498
  if (!o.next || o.next.type === QUOTED) break;
499
499
  case "var":
500
500
  m = m || vars;
501
- if (s === 'var' && m !== vars) console.log(m === vars, m === lets, s);
502
501
  var [declared, used0, o0, skiped] = getDeclared(o.next, s);
503
502
  while (skiped.length) {
504
503
  var o1 = run(skiped[0], 0);
@@ -790,6 +789,7 @@ var createScoped = function (parsed, wash) {
790
789
  delete used.await;
791
790
  }
792
791
  delete envs.eval;
792
+ delete envs.new;
793
793
  scoped.envs = envs;
794
794
  return scoped;
795
795
  };
@@ -1244,8 +1244,27 @@ var isEval = function (o) {
1244
1244
  var h = snapExpressHead(o);
1245
1245
  return o === h;
1246
1246
  }
1247
- return false;
1247
+ return true;
1248
1248
  };
1249
+ var canbeTemp = function (body, strip = false) {
1250
+ var cx = 0, dx = body.length - 1;
1251
+ while (cx < dx) {
1252
+ if (body[cx].type & (SPACE | COMMENT)) {
1253
+ cx++;
1254
+ continue;
1255
+ }
1256
+ if (body[dx].type & (SPACE | COMMENT)) {
1257
+ dx--;
1258
+ continue;
1259
+ }
1260
+ break;
1261
+ }
1262
+ if (body[cx] !== body[dx]) return false;
1263
+ var o = body[cx];
1264
+ if (!o) return false;
1265
+ return o.type === EXPRESS && (strip || !/[\.\[]/.test(o.text)) || o.type === VALUE || o.type === QUOTED && !o.length;
1266
+ };
1267
+
1249
1268
 
1250
1269
  module.exports = {
1251
1270
  /* 1 */COMMENT,
@@ -1277,6 +1296,7 @@ module.exports = {
1277
1296
  relink,
1278
1297
  setqueue,
1279
1298
  replace,
1299
+ canbeTemp,
1280
1300
  skipFunction,
1281
1301
  isHalfSentence,
1282
1302
  splice,
@@ -1,7 +1,7 @@
1
1
  var scanner2 = require("./scanner2");
2
2
  var strings = require("../basic/strings");
3
3
  var Program = scanner2.Program;
4
- var { STAMP, SCOPED, STRAP, EXPRESS, COMMENT, SPACE, PROPERTY, VALUE, LABEL, QUOTED, snapExpressFoot, rename, isHalfSentence, skipFunction, getDeclared, skipAssignment, skipSentenceQueue, createScoped, createString, splice, relink, snapExpressHead, needBreakBetween } = require("./common");
4
+ var { STAMP, SCOPED, STRAP, EXPRESS, COMMENT, SPACE, PROPERTY, VALUE, LABEL, QUOTED, snapExpressFoot, isEval, canbeTemp, rename, isHalfSentence, skipFunction, getDeclared, skipAssignment, skipSentenceQueue, createScoped, createString, splice, relink, snapExpressHead, needBreakBetween } = require("./common");
5
5
  var splice2 = function (q, from, to, ...a) {
6
6
  var cx = q.indexOf(from);
7
7
  if (cx < 0) throw console.log(splice2.caller, console.format('\r\n<red2>自</red2>'), from && createString([from]), console.format('\r\n<yellow>至</yellow>'), to && createString([to]), console.format(`\r\n<cyan>码列</cyan>`), createString(q)), '结构异常';
@@ -867,6 +867,9 @@ var killobj = function (body, getobjname, getletname, getname_, letname_, deep =
867
867
  killobj(o, getobjname, getletname, getname_, letname_, deep);
868
868
  if (o.await_) body.await_ = true;
869
869
  };
870
+ var _getnewname = function () {
871
+ return getname_("_");
872
+ };
870
873
  while (i < body.length) {
871
874
  var o = body[i];
872
875
  var islet = false;
@@ -979,29 +982,20 @@ var killobj = function (body, getobjname, getletname, getname_, letname_, deep =
979
982
  i = unarrow(body, i, deepkill, letname_);
980
983
  continue;
981
984
  }
985
+ else i = newpunc(body, i, _getnewname);
982
986
  }
983
987
  else if (o.isdigit) {
984
988
  if (/^0[^\.]/.test(o.text)) {
985
989
  o.text = String(eval(o.text));
986
990
  }
987
991
  }
992
+ else if (o.type === EXPRESS) {
993
+ if (o.text === 'new.target') o.text = 'undefined';
994
+ }
988
995
  i++;
989
996
  }
990
997
  };
991
998
 
992
- // 字面量 false|true|null|Infinity|NaN|undefined|arguments|this|eval|super
993
- var power_map = {};
994
- [
995
- '=,+=,-=,*=,/=,%=,|=,&=,^=,**=,~=',
996
- '=>', '?,:', '&&,||', '&,|,^',
997
- 'instanceof,in,==,>=,<=,>,<,!=,!==,===,!in,!instanceof',
998
- '>>,>>>,<<', '+,-', '*,/,%', '**',
999
- 'typeof,await,yield,!,~', '++,--'
1000
- ].forEach((pp, i) => {
1001
- pp.split(",").forEach(p => {
1002
- power_map[p] = i + 1;
1003
- })
1004
- });
1005
999
  var unawait = function (body, getname, argname) {
1006
1000
  return unstruct(body, function () {
1007
1001
  return getname("_");
@@ -1401,6 +1395,101 @@ var killret = function (body, labels = Object.create(null), gettmpname) {
1401
1395
  return breakmap;
1402
1396
  }
1403
1397
 
1398
+ var newpunc = function (body, i, newname) {
1399
+ var o = body[i];
1400
+ var t = o.text;
1401
+ if (t.length === 3 && /^(\?\?|\*\*|&&|\|\|)=$/.test(t)) {
1402
+ i++;
1403
+ var punc = t.slice(0, 2);
1404
+ o.text = '=';
1405
+ var f = skipAssignment(body, i);
1406
+ var sentence = splice(body, i, f - i);
1407
+ for (var s of sentence) {
1408
+ if (s.type === STAMP && /[^!=]=$/.test(s.text)) {
1409
+ var temp = scanner2(`()`)
1410
+ splice(temp[0], 0, 0, ...sentence);
1411
+ sentence = temp;
1412
+ break;
1413
+ }
1414
+ }
1415
+ var h = snapExpressHead(o.prev);
1416
+ if (!h) return;
1417
+ var rt = h.type === EXPRESS && h.text;
1418
+ var p = o.prev;
1419
+ var hi = body.lastIndexOf(h, i);
1420
+ if (
1421
+ h === p && h.type === EXPRESS && !/\.[\s\S]*\./.test(rt) && !/\[[^\]]*\]\[[^\]]*\]/.test(rt)) {
1422
+ splice(sentence, 0, 0, ...scanner2(rt + punc));
1423
+ hi = i;
1424
+ }
1425
+ else if (p && h === p.prev && p.type === SCOPED && p.entry === "[" && !/[\.\[]/.test(rt)) {
1426
+ if (canbeTemp(p)) {
1427
+ var name = p.first.text;
1428
+ }
1429
+ else {
1430
+ var name = newname();
1431
+ splice(p, 0, 0, ...scanner2(`${name}=`));
1432
+ }
1433
+ splice(sentence, 0, 0, ...scanner2(`${rt}[${name}]` + punc));
1434
+ hi = i;
1435
+ }
1436
+ else {
1437
+ var n = null;
1438
+ var name = newname();
1439
+ var pt = p.type === EXPRESS && p.text;
1440
+ var hp = h.prev;
1441
+ splice(body, i - 1, 1);
1442
+ if (p.type === EXPRESS && (n = /^(?:[\s\S]*[^\.])?(\.[^\.]*|\[[^\]]*\])$/.exec(pt))) {
1443
+ var n = n[1];
1444
+ p.text = pt.slice(0, pt.length - n.length);
1445
+ splice(sentence, 0, 0, ...scanner2(`,${name}${n}=${name}${n}${punc}`));
1446
+ }
1447
+ else if (p.type === SCOPED && p.entry === '[') {
1448
+ if (canbeTemp(p)) {
1449
+ var name2 = p.first.text;
1450
+ }
1451
+ else {
1452
+ var name2 = newname();
1453
+ splice(p, 0, 0, ...scanner2(`${name2}=`));
1454
+ }
1455
+ splice(body, i - 2, 1);
1456
+ splice(sentence, 0, 0, ...scanner2(`,${name}`), p, ...scanner2(`=${name}[${name2}]${punc}`));
1457
+ p = p.prev;
1458
+ }
1459
+ else {
1460
+ var n = p.text.replace(/^\./, '');
1461
+ var pp = p.prev;
1462
+ if (pp.type === EXPRESS) pp.text = pp.text.replace(/\.$/, '');
1463
+ splice(sentence, 0, 0, ...scanner2(`,${name}.${n}=${name}.${n}${punc}`));
1464
+ }
1465
+ splice(sentence, 0, 0, ...scanner2(`${name}=`), ...splice(body, hi, i));
1466
+ if (!isEval(body) || hp && hp.type === STAMP && /[=>]$/.test(hp.text)) {
1467
+ var temp = scanner2(`()`)
1468
+ splice(temp[0], 0, 0, ...sentence);
1469
+ sentence = temp;
1470
+ }
1471
+ }
1472
+ splice(body, hi, 0, ...sentence);
1473
+ hi--;
1474
+ }
1475
+ else {
1476
+ hi = i;
1477
+ if (/^(\?\?|\*\*)$/.test(t)) {
1478
+ var l = powermap.puncLeft(o);
1479
+ var r = powermap.puncRight(o);
1480
+ var li = body.lastIndexOf(l, i);
1481
+ var ri = body.indexOf(r, i);
1482
+ var name = t === '??' ? 'nullish_' : "power_";
1483
+ o.text = ',';
1484
+ sentence = scanner2(`${name}()`)
1485
+ splice(sentence[1], 0, 0, ...splice(body, li, 1 + ri - li));
1486
+ splice(body, li, 0, ...sentence);
1487
+ hi = li;
1488
+ }
1489
+ }
1490
+ return hi;
1491
+ }
1492
+
1404
1493
  var down = function (scoped) {
1405
1494
  var inAsync = scoped.async;
1406
1495
  var inAster = scoped.yield;
@@ -8,6 +8,17 @@ assert = function (a, b) {
8
8
  }
9
9
  var innerJs = new Javascript;
10
10
  innerJs.defaultType = common.STRAP;
11
+ // 运算符
12
+ assert(downLevel(`a??b`), 'nullish_(a, b)', true);
13
+ assert(downLevel(`a**b`), 'power_(a, b)', true);
14
+ assert(downLevel(`a.c**b`), 'power_(a.c, b)', true);
15
+ assert(downLevel(`a??=b`), 'a = nullish_(a, b)', true);
16
+ assert(downLevel(`a**=b`), 'a = power_(a, b)', true);
17
+ assert(downLevel(`a+=b+c**d`), 'a += b + power_(c, d)', true);
18
+ assert(downLevel(`a(c**=d)`), 'a(c = power_(c, d))', true);
19
+ assert(downLevel(`a(c.b.d**=d)`), 'a((_ = c.b, _.d = power_(_.d, d)))\r\nvar _', true);
20
+ assert(downLevel(`a(c.b[a.b]**=d)`), 'a((_ = c.b, _[_0 = a.b] = power_(_[_0], d)))\r\nvar _, _0', true);
21
+ assert(downLevel(`c.b[a.b]**=d`), '_ = c.b, _[_0 = a.b] = power_(_[_0], d)\r\nvar _, _0', true);
11
22
  // 声明及解构
12
23
  assert(downLevel(`var [data, args, strs] = breakcode(data, occurs), strs = []`), 'var _ = breakcode(data, occurs), data = _[0], args = _[1], strs = _[2], strs = []\r\nvar _');
13
24
  assert(downLevel(`var [name, type, options] = piece, key, repeat;`), 'var name = piece[0], type = piece[1], options = piece[2], key, repeat;');
@@ -16,6 +27,7 @@ assert(downLevel(`var [] = piece, key,[]`), 'var key');
16
27
  assert(downLevel(`const`), 'const');
17
28
  assert(downLevel(`let`), 'let');
18
29
  assert(downLevel(`var`), '');
30
+ assert(downLevel(`new.target`), 'undefined');
19
31
  assert(downLevel(`{let a; function b(){a};return;}`), `if (tmp = 0, tmp0 =function (a) { a; function b() { a }; return tmp = 1, void 0; }(a)) { if (tmp === 1) return tmp0; }
20
32
  var tmp, a, tmp0`);
21
33
  assert(downLevel(`const a,b,c`), 'var a, b, c');
@@ -1,6 +1,29 @@
1
- var powermap = {};
1
+ var { STAMP, snapExpressHead, snapExpressFoot } = require("./common");
2
+ var powermap = new class {
3
+ puncLeft(o) {
4
+ var s = snapExpressHead(o.prev);
5
+ var p = Infinity;
6
+ while (o && o.prev) {
7
+ if (o.type !== STAMP || !(o.text in this) || this[o.text] < p) return s;
8
+ s = snapExpressHead(o.prev);
9
+ o = s.prev;
10
+ }
11
+ return s;
12
+ }
13
+ puncRight(o) {
14
+ var s = snapExpressFoot(o.next);
15
+ var p = 0;
16
+ while (o && o.next) {
17
+ if (o.type !== STAMP || !(o.text in this) || this[o.text] <= p) return s;
18
+ s = snapExpressFoot(o.next);
19
+ o = s.next;
20
+ }
21
+ return s;
22
+ }
23
+ };
24
+
2
25
  [
3
- '=,+=,-=,*=,/=,%=,|=,&=,^=,**=,~=,?,:,=>'/* 1 */,
26
+ '=,+=,-=,*=,/=,%=,|=,&=,^=,||=,&&=,??=,<<=,>>=,>>>=,**=,~=,?,:,=>'/* 1 */,
4
27
  '&&,||,^^,??'/* 4 */, '&,|,^'/* 5 */,
5
28
  'instanceof,in,==,>=,<=,>,<,!=,!==,===,!in,!instanceof'/* 6 */,
6
29
  '>>,>>>,<<'/* 7 */, '+,-'/* 8 */, '*,/,%'/* 9 */, '**'/* 10 */,