terser 5.17.0 → 5.17.2
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/CHANGELOG.md +8 -0
- package/dist/bundle.min.js +79 -56
- package/lib/ast.js +13 -3
- package/lib/compress/evaluate.js +2 -10
- package/lib/compress/index.js +0 -20
- package/lib/compress/inference.js +2 -0
- package/lib/compress/reduce-vars.js +25 -12
- package/lib/compress/tighten-body.js +41 -12
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
@@ -1,5 +1,13 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## v5.17.2
|
4
|
+
- Be less conservative when detecting use-before-definition of `var` in hoisted functions.
|
5
|
+
- Support unusual (but perfectly valid) initializers of for-in and for-of loops.
|
6
|
+
- Fix issue where hoisted function would be dropped if it was after a `continue` statement
|
7
|
+
|
8
|
+
## v5.17.1
|
9
|
+
- Fix evaluating `.length` when the source array might've been mutated
|
10
|
+
|
3
11
|
## v5.17.0
|
4
12
|
- Drop vestigial `= undefined` default argument in IIFE calls (#1366)
|
5
13
|
- Evaluate known arrays' `.length` property when statically determinable
|
package/dist/bundle.min.js
CHANGED
@@ -4515,11 +4515,14 @@ var AST_Destructuring = DEFNODE("Destructuring", "names is_array", function AST_
|
|
4515
4515
|
},
|
4516
4516
|
all_symbols: function() {
|
4517
4517
|
var out = [];
|
4518
|
-
|
4519
|
-
if (node instanceof
|
4518
|
+
walk(this, node => {
|
4519
|
+
if (node instanceof AST_SymbolDeclaration) {
|
4520
4520
|
out.push(node);
|
4521
4521
|
}
|
4522
|
-
|
4522
|
+
if (node instanceof AST_Lambda) {
|
4523
|
+
return true;
|
4524
|
+
}
|
4525
|
+
});
|
4523
4526
|
return out;
|
4524
4527
|
}
|
4525
4528
|
});
|
@@ -5050,6 +5053,13 @@ var AST_VarDef = DEFNODE("VarDef", "name value", function AST_VarDef(props) {
|
|
5050
5053
|
if (this.value) push(this.value);
|
5051
5054
|
push(this.name);
|
5052
5055
|
},
|
5056
|
+
declarations_as_names() {
|
5057
|
+
if (this.name instanceof AST_SymbolDeclaration) {
|
5058
|
+
return [this];
|
5059
|
+
} else {
|
5060
|
+
return this.name.all_symbols();
|
5061
|
+
}
|
5062
|
+
}
|
5053
5063
|
});
|
5054
5064
|
|
5055
5065
|
var AST_NameMapping = DEFNODE("NameMapping", "foreign_name name", function AST_NameMapping(props) {
|
@@ -13908,6 +13918,7 @@ function is_nullish(node, compressor) {
|
|
13908
13918
|
function is_lhs(node, parent) {
|
13909
13919
|
if (parent instanceof AST_Unary && unary_side_effects.has(parent.operator)) return parent.expression;
|
13910
13920
|
if (parent instanceof AST_Assign && parent.left === node) return node;
|
13921
|
+
if (parent instanceof AST_ForIn && parent.init === node) return node;
|
13911
13922
|
}
|
13912
13923
|
|
13913
13924
|
(function(def_find_defs) {
|
@@ -14496,24 +14507,16 @@ def_eval(AST_PropAccess, function (compressor, depth) {
|
|
14496
14507
|
return obj.length;
|
14497
14508
|
}
|
14498
14509
|
|
14499
|
-
const is_spreadless_array =
|
14510
|
+
const is_spreadless_array =
|
14500
14511
|
obj instanceof AST_Array
|
14501
14512
|
&& obj.elements.every(el => !(el instanceof AST_Expansion));
|
14502
14513
|
|
14503
14514
|
if (
|
14504
|
-
is_spreadless_array
|
14515
|
+
is_spreadless_array
|
14505
14516
|
&& obj.elements.every(el => !el.has_side_effects(compressor))
|
14506
14517
|
) {
|
14507
14518
|
return obj.elements.length;
|
14508
14519
|
}
|
14509
|
-
|
14510
|
-
let fixed;
|
14511
|
-
if (
|
14512
|
-
obj instanceof AST_SymbolRef
|
14513
|
-
&& is_spreadless_array((fixed = obj.definition().fixed_value()))
|
14514
|
-
) {
|
14515
|
-
return fixed.elements.length;
|
14516
|
-
}
|
14517
14520
|
}
|
14518
14521
|
|
14519
14522
|
if (compressor.option("unsafe")) {
|
@@ -15845,20 +15848,31 @@ function handle_defined_after_hoist(parent) {
|
|
15845
15848
|
continue;
|
15846
15849
|
}
|
15847
15850
|
|
15848
|
-
// Detect `call_defun(); var used_in_defun =
|
15849
|
-
// Because `used_in_defun`
|
15850
|
-
let
|
15851
|
+
// Detect `call_defun(); var used_in_defun = X`
|
15852
|
+
// Because `used_in_defun` is not certainly X when it's defined after.
|
15853
|
+
let found_defun_ref = false;
|
15851
15854
|
let found_def_after_defun = false;
|
15852
|
-
|
15855
|
+
walk_parent(parent, (node, info) => {
|
15853
15856
|
if (node === defun) return true;
|
15854
15857
|
|
15855
|
-
|
15856
|
-
|
15857
|
-
|
15858
|
-
|
15859
|
-
|
15860
|
-
|
15861
|
-
|
15858
|
+
// Step 1: find `call_defun()` or other refs to the defun
|
15859
|
+
if (
|
15860
|
+
!found_defun_ref
|
15861
|
+
&& node.thedef === fname_def
|
15862
|
+
&& node instanceof AST_Symbol
|
15863
|
+
) {
|
15864
|
+
found_defun_ref = true;
|
15865
|
+
}
|
15866
|
+
|
15867
|
+
// Step 2: if Step 1 occurred, find a var the defun uses
|
15868
|
+
if (
|
15869
|
+
found_defun_ref
|
15870
|
+
&& node.thedef === def
|
15871
|
+
&& (node instanceof AST_SymbolDeclaration
|
15872
|
+
|| is_lhs(node, info))
|
15873
|
+
) {
|
15874
|
+
found_def_after_defun = true;
|
15875
|
+
return walk_abort;
|
15862
15876
|
}
|
15863
15877
|
});
|
15864
15878
|
|
@@ -16138,12 +16152,31 @@ function is_lhs_read_only(lhs) {
|
|
16138
16152
|
return false;
|
16139
16153
|
}
|
16140
16154
|
|
16141
|
-
|
16155
|
+
/** var a = 1 --> var a*/
|
16156
|
+
function remove_initializers(var_statement) {
|
16157
|
+
var decls = [];
|
16158
|
+
var_statement.definitions.forEach(function(def) {
|
16159
|
+
if (def.name instanceof AST_SymbolDeclaration) {
|
16160
|
+
def.value = null;
|
16161
|
+
decls.push(def);
|
16162
|
+
} else {
|
16163
|
+
def.declarations_as_names().forEach(name => {
|
16164
|
+
decls.push(make_node(AST_VarDef, def, {
|
16165
|
+
name,
|
16166
|
+
value: null
|
16167
|
+
}));
|
16168
|
+
});
|
16169
|
+
}
|
16170
|
+
});
|
16171
|
+
return decls.length ? make_node(AST_Var, var_statement, { definitions: decls }) : null;
|
16172
|
+
}
|
16173
|
+
|
16174
|
+
/** Called on code which we know is unreachable, to keep elements that affect outside of it. */
|
16142
16175
|
function trim_unreachable_code(compressor, stat, target) {
|
16143
16176
|
walk(stat, node => {
|
16144
16177
|
if (node instanceof AST_Var) {
|
16145
|
-
|
16146
|
-
target.push(
|
16178
|
+
const no_initializers = remove_initializers(node);
|
16179
|
+
if (no_initializers) target.push(no_initializers);
|
16147
16180
|
return true;
|
16148
16181
|
}
|
16149
16182
|
if (
|
@@ -16951,27 +16984,34 @@ function tighten_body(statements, compressor) {
|
|
16951
16984
|
}
|
16952
16985
|
|
16953
16986
|
if (stat instanceof AST_If) {
|
16954
|
-
|
16955
|
-
|
16987
|
+
let ab, new_else;
|
16988
|
+
|
16989
|
+
ab = aborts(stat.body);
|
16990
|
+
if (
|
16991
|
+
can_merge_flow(ab)
|
16992
|
+
&& (new_else = as_statement_array_with_return(stat.body, ab))
|
16993
|
+
) {
|
16956
16994
|
if (ab.label) {
|
16957
16995
|
remove(ab.label.thedef.references, ab);
|
16958
16996
|
}
|
16959
16997
|
CHANGED = true;
|
16960
16998
|
stat = stat.clone();
|
16961
16999
|
stat.condition = stat.condition.negate(compressor);
|
16962
|
-
var body = as_statement_array_with_return(stat.body, ab);
|
16963
17000
|
stat.body = make_node(AST_BlockStatement, stat, {
|
16964
17001
|
body: as_statement_array(stat.alternative).concat(extract_functions())
|
16965
17002
|
});
|
16966
17003
|
stat.alternative = make_node(AST_BlockStatement, stat, {
|
16967
|
-
body:
|
17004
|
+
body: new_else
|
16968
17005
|
});
|
16969
17006
|
statements[i] = stat.transform(compressor);
|
16970
17007
|
continue;
|
16971
17008
|
}
|
16972
17009
|
|
16973
|
-
|
16974
|
-
if (
|
17010
|
+
ab = aborts(stat.alternative);
|
17011
|
+
if (
|
17012
|
+
can_merge_flow(ab)
|
17013
|
+
&& (new_else = as_statement_array_with_return(stat.alternative, ab))
|
17014
|
+
) {
|
16975
17015
|
if (ab.label) {
|
16976
17016
|
remove(ab.label.thedef.references, ab);
|
16977
17017
|
}
|
@@ -16980,9 +17020,8 @@ function tighten_body(statements, compressor) {
|
|
16980
17020
|
stat.body = make_node(AST_BlockStatement, stat.body, {
|
16981
17021
|
body: as_statement_array(stat.body).concat(extract_functions())
|
16982
17022
|
});
|
16983
|
-
var body = as_statement_array_with_return(stat.alternative, ab);
|
16984
17023
|
stat.alternative = make_node(AST_BlockStatement, stat.alternative, {
|
16985
|
-
body:
|
17024
|
+
body: new_else
|
16986
17025
|
});
|
16987
17026
|
statements[i] = stat.transform(compressor);
|
16988
17027
|
continue;
|
@@ -17097,7 +17136,11 @@ function tighten_body(statements, compressor) {
|
|
17097
17136
|
}
|
17098
17137
|
|
17099
17138
|
function as_statement_array_with_return(node, ab) {
|
17100
|
-
var body = as_statement_array(node)
|
17139
|
+
var body = as_statement_array(node);
|
17140
|
+
if (ab !== body[body.length - 1]) {
|
17141
|
+
return undefined;
|
17142
|
+
}
|
17143
|
+
body = body.slice(0, -1);
|
17101
17144
|
if (ab.value) {
|
17102
17145
|
body.push(make_node(AST_SimpleStatement, ab.value, {
|
17103
17146
|
body: ab.value.expression
|
@@ -19373,26 +19416,6 @@ def_optimize(AST_Try, function(self, compressor) {
|
|
19373
19416
|
return self;
|
19374
19417
|
});
|
19375
19418
|
|
19376
|
-
AST_Definitions.DEFMETHOD("remove_initializers", function() {
|
19377
|
-
var decls = [];
|
19378
|
-
this.definitions.forEach(function(def) {
|
19379
|
-
if (def.name instanceof AST_SymbolDeclaration) {
|
19380
|
-
def.value = null;
|
19381
|
-
decls.push(def);
|
19382
|
-
} else {
|
19383
|
-
walk(def.name, node => {
|
19384
|
-
if (node instanceof AST_SymbolDeclaration) {
|
19385
|
-
decls.push(make_node(AST_VarDef, def, {
|
19386
|
-
name: node,
|
19387
|
-
value: null
|
19388
|
-
}));
|
19389
|
-
}
|
19390
|
-
});
|
19391
|
-
}
|
19392
|
-
});
|
19393
|
-
this.definitions = decls;
|
19394
|
-
});
|
19395
|
-
|
19396
19419
|
AST_Definitions.DEFMETHOD("to_assignments", function(compressor) {
|
19397
19420
|
var reduce_vars = compressor.option("reduce_vars");
|
19398
19421
|
var assignments = [];
|
package/lib/ast.js
CHANGED
@@ -905,11 +905,14 @@ var AST_Destructuring = DEFNODE("Destructuring", "names is_array", function AST_
|
|
905
905
|
},
|
906
906
|
all_symbols: function() {
|
907
907
|
var out = [];
|
908
|
-
|
909
|
-
if (node instanceof
|
908
|
+
walk(this, node => {
|
909
|
+
if (node instanceof AST_SymbolDeclaration) {
|
910
910
|
out.push(node);
|
911
911
|
}
|
912
|
-
|
912
|
+
if (node instanceof AST_Lambda) {
|
913
|
+
return true;
|
914
|
+
}
|
915
|
+
});
|
913
916
|
return out;
|
914
917
|
}
|
915
918
|
});
|
@@ -1440,6 +1443,13 @@ var AST_VarDef = DEFNODE("VarDef", "name value", function AST_VarDef(props) {
|
|
1440
1443
|
if (this.value) push(this.value);
|
1441
1444
|
push(this.name);
|
1442
1445
|
},
|
1446
|
+
declarations_as_names() {
|
1447
|
+
if (this.name instanceof AST_SymbolDeclaration) {
|
1448
|
+
return [this];
|
1449
|
+
} else {
|
1450
|
+
return this.name.all_symbols();
|
1451
|
+
}
|
1452
|
+
}
|
1443
1453
|
});
|
1444
1454
|
|
1445
1455
|
var AST_NameMapping = DEFNODE("NameMapping", "foreign_name name", function AST_NameMapping(props) {
|
package/lib/compress/evaluate.js
CHANGED
@@ -359,24 +359,16 @@ def_eval(AST_PropAccess, function (compressor, depth) {
|
|
359
359
|
return obj.length;
|
360
360
|
}
|
361
361
|
|
362
|
-
const is_spreadless_array =
|
362
|
+
const is_spreadless_array =
|
363
363
|
obj instanceof AST_Array
|
364
364
|
&& obj.elements.every(el => !(el instanceof AST_Expansion));
|
365
365
|
|
366
366
|
if (
|
367
|
-
is_spreadless_array
|
367
|
+
is_spreadless_array
|
368
368
|
&& obj.elements.every(el => !el.has_side_effects(compressor))
|
369
369
|
) {
|
370
370
|
return obj.elements.length;
|
371
371
|
}
|
372
|
-
|
373
|
-
let fixed;
|
374
|
-
if (
|
375
|
-
obj instanceof AST_SymbolRef
|
376
|
-
&& is_spreadless_array((fixed = obj.definition().fixed_value()))
|
377
|
-
) {
|
378
|
-
return fixed.elements.length;
|
379
|
-
}
|
380
372
|
}
|
381
373
|
|
382
374
|
if (compressor.option("unsafe")) {
|
package/lib/compress/index.js
CHANGED
@@ -1545,26 +1545,6 @@ def_optimize(AST_Try, function(self, compressor) {
|
|
1545
1545
|
return self;
|
1546
1546
|
});
|
1547
1547
|
|
1548
|
-
AST_Definitions.DEFMETHOD("remove_initializers", function() {
|
1549
|
-
var decls = [];
|
1550
|
-
this.definitions.forEach(function(def) {
|
1551
|
-
if (def.name instanceof AST_SymbolDeclaration) {
|
1552
|
-
def.value = null;
|
1553
|
-
decls.push(def);
|
1554
|
-
} else {
|
1555
|
-
walk(def.name, node => {
|
1556
|
-
if (node instanceof AST_SymbolDeclaration) {
|
1557
|
-
decls.push(make_node(AST_VarDef, def, {
|
1558
|
-
name: node,
|
1559
|
-
value: null
|
1560
|
-
}));
|
1561
|
-
}
|
1562
|
-
});
|
1563
|
-
}
|
1564
|
-
});
|
1565
|
-
this.definitions = decls;
|
1566
|
-
});
|
1567
|
-
|
1568
1548
|
AST_Definitions.DEFMETHOD("to_assignments", function(compressor) {
|
1569
1549
|
var reduce_vars = compressor.option("reduce_vars");
|
1570
1550
|
var assignments = [];
|
@@ -64,6 +64,7 @@ import {
|
|
64
64
|
AST_EmptyStatement,
|
65
65
|
AST_Expansion,
|
66
66
|
AST_False,
|
67
|
+
AST_ForIn,
|
67
68
|
AST_Function,
|
68
69
|
AST_If,
|
69
70
|
AST_Import,
|
@@ -712,6 +713,7 @@ export function is_nullish(node, compressor) {
|
|
712
713
|
export function is_lhs(node, parent) {
|
713
714
|
if (parent instanceof AST_Unary && unary_side_effects.has(parent.operator)) return parent.expression;
|
714
715
|
if (parent instanceof AST_Assign && parent.left === node) return node;
|
716
|
+
if (parent instanceof AST_ForIn && parent.init === node) return node;
|
715
717
|
}
|
716
718
|
|
717
719
|
(function(def_find_defs) {
|
@@ -77,6 +77,7 @@ import {
|
|
77
77
|
AST_Symbol,
|
78
78
|
AST_SymbolCatch,
|
79
79
|
AST_SymbolConst,
|
80
|
+
AST_SymbolDeclaration,
|
80
81
|
AST_SymbolDefun,
|
81
82
|
AST_SymbolFunarg,
|
82
83
|
AST_SymbolLambda,
|
@@ -92,6 +93,7 @@ import {
|
|
92
93
|
AST_Yield,
|
93
94
|
|
94
95
|
walk,
|
96
|
+
walk_parent,
|
95
97
|
walk_abort,
|
96
98
|
walk_body,
|
97
99
|
|
@@ -101,7 +103,7 @@ import {
|
|
101
103
|
} from "../ast.js";
|
102
104
|
import { HOP, make_node, noop } from "../utils/index.js";
|
103
105
|
|
104
|
-
import { lazy_op, is_modified } from "./inference.js";
|
106
|
+
import { lazy_op, is_modified, is_lhs } from "./inference.js";
|
105
107
|
import { INLINED, clear_flag } from "./compressor-flags.js";
|
106
108
|
import { read_property, has_break_or_continue, is_recursive_ref } from "./common.js";
|
107
109
|
|
@@ -540,20 +542,31 @@ function handle_defined_after_hoist(parent) {
|
|
540
542
|
continue;
|
541
543
|
}
|
542
544
|
|
543
|
-
// Detect `call_defun(); var used_in_defun =
|
544
|
-
// Because `used_in_defun`
|
545
|
-
let
|
545
|
+
// Detect `call_defun(); var used_in_defun = X`
|
546
|
+
// Because `used_in_defun` is not certainly X when it's defined after.
|
547
|
+
let found_defun_ref = false;
|
546
548
|
let found_def_after_defun = false;
|
547
|
-
|
549
|
+
walk_parent(parent, (node, info) => {
|
548
550
|
if (node === defun) return true;
|
549
551
|
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
552
|
+
// Step 1: find `call_defun()` or other refs to the defun
|
553
|
+
if (
|
554
|
+
!found_defun_ref
|
555
|
+
&& node.thedef === fname_def
|
556
|
+
&& node instanceof AST_Symbol
|
557
|
+
) {
|
558
|
+
found_defun_ref = true;
|
559
|
+
}
|
560
|
+
|
561
|
+
// Step 2: if Step 1 occurred, find a var the defun uses
|
562
|
+
if (
|
563
|
+
found_defun_ref
|
564
|
+
&& node.thedef === def
|
565
|
+
&& (node instanceof AST_SymbolDeclaration
|
566
|
+
|| is_lhs(node, info))
|
567
|
+
) {
|
568
|
+
found_def_after_defun = true;
|
569
|
+
return walk_abort;
|
557
570
|
}
|
558
571
|
});
|
559
572
|
|
@@ -170,12 +170,31 @@ function is_lhs_read_only(lhs) {
|
|
170
170
|
return false;
|
171
171
|
}
|
172
172
|
|
173
|
-
|
173
|
+
/** var a = 1 --> var a*/
|
174
|
+
function remove_initializers(var_statement) {
|
175
|
+
var decls = [];
|
176
|
+
var_statement.definitions.forEach(function(def) {
|
177
|
+
if (def.name instanceof AST_SymbolDeclaration) {
|
178
|
+
def.value = null;
|
179
|
+
decls.push(def);
|
180
|
+
} else {
|
181
|
+
def.declarations_as_names().forEach(name => {
|
182
|
+
decls.push(make_node(AST_VarDef, def, {
|
183
|
+
name,
|
184
|
+
value: null
|
185
|
+
}));
|
186
|
+
});
|
187
|
+
}
|
188
|
+
});
|
189
|
+
return decls.length ? make_node(AST_Var, var_statement, { definitions: decls }) : null;
|
190
|
+
}
|
191
|
+
|
192
|
+
/** Called on code which we know is unreachable, to keep elements that affect outside of it. */
|
174
193
|
export function trim_unreachable_code(compressor, stat, target) {
|
175
194
|
walk(stat, node => {
|
176
195
|
if (node instanceof AST_Var) {
|
177
|
-
|
178
|
-
target.push(
|
196
|
+
const no_initializers = remove_initializers(node);
|
197
|
+
if (no_initializers) target.push(no_initializers);
|
179
198
|
return true;
|
180
199
|
}
|
181
200
|
if (
|
@@ -983,27 +1002,34 @@ export function tighten_body(statements, compressor) {
|
|
983
1002
|
}
|
984
1003
|
|
985
1004
|
if (stat instanceof AST_If) {
|
986
|
-
|
987
|
-
|
1005
|
+
let ab, new_else;
|
1006
|
+
|
1007
|
+
ab = aborts(stat.body);
|
1008
|
+
if (
|
1009
|
+
can_merge_flow(ab)
|
1010
|
+
&& (new_else = as_statement_array_with_return(stat.body, ab))
|
1011
|
+
) {
|
988
1012
|
if (ab.label) {
|
989
1013
|
remove(ab.label.thedef.references, ab);
|
990
1014
|
}
|
991
1015
|
CHANGED = true;
|
992
1016
|
stat = stat.clone();
|
993
1017
|
stat.condition = stat.condition.negate(compressor);
|
994
|
-
var body = as_statement_array_with_return(stat.body, ab);
|
995
1018
|
stat.body = make_node(AST_BlockStatement, stat, {
|
996
1019
|
body: as_statement_array(stat.alternative).concat(extract_functions())
|
997
1020
|
});
|
998
1021
|
stat.alternative = make_node(AST_BlockStatement, stat, {
|
999
|
-
body:
|
1022
|
+
body: new_else
|
1000
1023
|
});
|
1001
1024
|
statements[i] = stat.transform(compressor);
|
1002
1025
|
continue;
|
1003
1026
|
}
|
1004
1027
|
|
1005
|
-
|
1006
|
-
if (
|
1028
|
+
ab = aborts(stat.alternative);
|
1029
|
+
if (
|
1030
|
+
can_merge_flow(ab)
|
1031
|
+
&& (new_else = as_statement_array_with_return(stat.alternative, ab))
|
1032
|
+
) {
|
1007
1033
|
if (ab.label) {
|
1008
1034
|
remove(ab.label.thedef.references, ab);
|
1009
1035
|
}
|
@@ -1012,9 +1038,8 @@ export function tighten_body(statements, compressor) {
|
|
1012
1038
|
stat.body = make_node(AST_BlockStatement, stat.body, {
|
1013
1039
|
body: as_statement_array(stat.body).concat(extract_functions())
|
1014
1040
|
});
|
1015
|
-
var body = as_statement_array_with_return(stat.alternative, ab);
|
1016
1041
|
stat.alternative = make_node(AST_BlockStatement, stat.alternative, {
|
1017
|
-
body:
|
1042
|
+
body: new_else
|
1018
1043
|
});
|
1019
1044
|
statements[i] = stat.transform(compressor);
|
1020
1045
|
continue;
|
@@ -1129,7 +1154,11 @@ export function tighten_body(statements, compressor) {
|
|
1129
1154
|
}
|
1130
1155
|
|
1131
1156
|
function as_statement_array_with_return(node, ab) {
|
1132
|
-
var body = as_statement_array(node)
|
1157
|
+
var body = as_statement_array(node);
|
1158
|
+
if (ab !== body[body.length - 1]) {
|
1159
|
+
return undefined;
|
1160
|
+
}
|
1161
|
+
body = body.slice(0, -1);
|
1133
1162
|
if (ab.value) {
|
1134
1163
|
body.push(make_node(AST_SimpleStatement, ab.value, {
|
1135
1164
|
body: ab.value.expression
|