Comparing version 5.16.0 to 5.16.1
@@ -5,2 +5,10 @@ # Changelog | ||
- Properly handle references in destructurings (`const { [reference]: val } = ...`) | ||
- Allow parsing of `.#privatefield` in nested classes | ||
- Do not evaluate operations that return large strings if that would make the output code larger | ||
- Make `collapse_vars` handle block scope correctly | ||
- Internal improvements: Typos (#1311), more tests, small-scale refactoring | ||
## v5.16.0 | ||
- Disallow private fields in object bodies (#1011) | ||
@@ -7,0 +15,0 @@ - Parse `#privatefield in object` (#1279) |
@@ -102,2 +102,9 @@ /*********************************************************************** | ||
return this; | ||
// Evaluated strings can be larger than the original expression | ||
if (typeof val === "string") { | ||
const unevaluated_size = this.size(compressor); | ||
if (val.length + 2 > unevaluated_size) return this; | ||
} | ||
return val; | ||
@@ -104,0 +111,0 @@ }); |
@@ -576,3 +576,2 @@ /*********************************************************************** | ||
if (node instanceof AST_This && this instanceof AST_Arrow) { | ||
// TODO check arguments too! | ||
result = false; | ||
@@ -698,3 +697,3 @@ return walk_abort; | ||
def_may_throw_on_access(AST_SymbolRef, function(compressor) { | ||
if (this.name === "arguments") return false; | ||
if (this.name === "arguments" && this.scope instanceof AST_Lambda) return false; | ||
if (has_flag(this, UNDEFINED)) return true; | ||
@@ -701,0 +700,0 @@ if (!is_strict(compressor)) return false; |
@@ -60,6 +60,4 @@ /*********************************************************************** | ||
AST_Function, | ||
AST_Infinity, | ||
AST_IterationStatement, | ||
AST_Lambda, | ||
AST_NaN, | ||
AST_Node, | ||
@@ -85,3 +83,2 @@ AST_Number, | ||
AST_VarDef, | ||
AST_With, | ||
@@ -100,3 +97,3 @@ walk, | ||
import "./reduce-vars.js"; | ||
import { is_undeclared_ref, is_lhs } from "./inference.js"; | ||
import { is_lhs } from "./inference.js"; | ||
import { | ||
@@ -152,17 +149,2 @@ SQUEEZED, | ||
export function inline_into_symbolref(self, compressor) { | ||
if ( | ||
!compressor.option("ie8") | ||
&& is_undeclared_ref(self) | ||
&& !compressor.find_parent(AST_With) | ||
) { | ||
switch (self.name) { | ||
case "undefined": | ||
return make_node(AST_Undefined, self).optimize(compressor); | ||
case "NaN": | ||
return make_node(AST_NaN, self).optimize(compressor); | ||
case "Infinity": | ||
return make_node(AST_Infinity, self).optimize(compressor); | ||
} | ||
} | ||
const parent = compressor.parent(); | ||
@@ -169,0 +151,0 @@ if (compressor.option("reduce_vars") && is_lhs(self, parent) !== self) { |
@@ -208,5 +208,6 @@ /*********************************************************************** | ||
export function tighten_body(statements, compressor) { | ||
var in_loop, in_try; | ||
var scope = compressor.find_parent(AST_Scope).get_defun_scope(); | ||
find_loop_scope_try(); | ||
const nearest_scope = compressor.find_scope(); | ||
const defun_scope = nearest_scope.get_defun_scope(); | ||
const { in_loop, in_try } = find_loop_scope_try(); | ||
var CHANGED, max_iter = 10; | ||
@@ -235,3 +236,3 @@ do { | ||
function find_loop_scope_try() { | ||
var node = compressor.self(), level = 0; | ||
var node = compressor.self(), level = 0, in_loop = false, in_try = false; | ||
do { | ||
@@ -243,3 +244,2 @@ if (node instanceof AST_Catch || node instanceof AST_Finally) { | ||
} else if (node instanceof AST_Scope) { | ||
scope = node; | ||
break; | ||
@@ -250,2 +250,4 @@ } else if (node instanceof AST_Try) { | ||
} while (node = compressor.parent(level++)); | ||
return { in_loop, in_try }; | ||
} | ||
@@ -262,3 +264,3 @@ | ||
function collapse(statements, compressor) { | ||
if (scope.pinned()) | ||
if (nearest_scope.pinned() || defun_scope.pinned()) | ||
return statements; | ||
@@ -327,6 +329,7 @@ var args; | ||
// Replace variable with assignment when found | ||
if (can_replace | ||
if ( | ||
can_replace | ||
&& !(node instanceof AST_SymbolDeclaration) | ||
&& lhs.equivalent_to(node) | ||
&& !shadows(node.scope, lvalues) | ||
&& !shadows(scanner.find_scope() || nearest_scope, lvalues) | ||
) { | ||
@@ -536,5 +539,5 @@ if (stop_if_hit) { | ||
var s = node.definition().scope; | ||
if (s !== scope) | ||
if (s !== defun_scope) | ||
while (s = s.parent_scope) { | ||
if (s === scope) | ||
if (s === defun_scope) | ||
return true; | ||
@@ -861,3 +864,3 @@ } | ||
return lhs instanceof AST_SymbolRef | ||
&& lhs.definition().scope === scope | ||
&& lhs.definition().scope.get_defun_scope() === defun_scope | ||
&& !(in_loop | ||
@@ -897,11 +900,7 @@ && (lvalues.has(lhs.name) | ||
return false; | ||
if (def.scope.get_defun_scope() !== scope) | ||
if (def.scope.get_defun_scope() !== defun_scope) | ||
return true; | ||
return !def.references.every((ref) => { | ||
var s = ref.scope.get_defun_scope(); | ||
// "block" scope within AST_Catch | ||
if (s.TYPE == "Scope") | ||
s = s.parent_scope; | ||
return s === scope; | ||
}); | ||
return def.references.some((ref) => | ||
ref.scope.get_defun_scope() !== defun_scope | ||
); | ||
} | ||
@@ -922,3 +921,3 @@ | ||
if (node instanceof AST_SymbolRef) | ||
return node.definition().scope !== scope; | ||
return node.definition().scope.get_defun_scope() !== defun_scope; | ||
} | ||
@@ -928,9 +927,11 @@ return false; | ||
function shadows(newScope, lvalues) { | ||
for (const {def} of lvalues.values()) { | ||
let current = newScope; | ||
while (current && current !== def.scope) { | ||
let nested_def = current.variables.get(def.name); | ||
if (nested_def && nested_def !== def) return true; | ||
current = current.parent_scope; | ||
/** | ||
* Will any of the pulled-in lvalues shadow a variable in newScope or parents? | ||
* similar to scope_encloses_variables_in_this_scope */ | ||
function shadows(my_scope, lvalues) { | ||
for (const { def } of lvalues.values()) { | ||
const looked_up = my_scope.find_variable(def.name); | ||
if (looked_up) { | ||
if (looked_up === def) continue; | ||
return true; | ||
} | ||
@@ -1357,3 +1358,3 @@ } | ||
break; | ||
if (!node.right.is_constant_expression(scope)) | ||
if (!node.right.is_constant_expression(nearest_scope)) | ||
break; | ||
@@ -1360,0 +1361,0 @@ var prop = node.left.property; |
@@ -107,3 +107,4 @@ /*********************************************************************** | ||
TreeWalker, | ||
walk | ||
walk, | ||
walk_abort | ||
} from "./ast.js"; | ||
@@ -422,3 +423,3 @@ import { | ||
} else if (sym.scope instanceof AST_Lambda && name == "arguments") { | ||
sym.scope.uses_arguments = true; | ||
sym.scope.get_defun_scope().uses_arguments = true; | ||
} | ||
@@ -525,4 +526,22 @@ node.thedef = sym; | ||
// TODO uses_with, uses_eval, etc | ||
// Propagate to this.uses_arguments from arrow functions | ||
if ((scope instanceof AST_Arrow) && !this.uses_arguments) { | ||
this.uses_arguments = walk(scope, node => { | ||
if ( | ||
node instanceof AST_SymbolRef | ||
&& node.scope instanceof AST_Lambda | ||
&& node.name === "arguments" | ||
) { | ||
return walk_abort; | ||
} | ||
if (node instanceof AST_Lambda && !(node instanceof AST_Arrow)) { | ||
return true; | ||
} | ||
}); | ||
} | ||
this.uses_with = this.uses_with || scope.uses_with; | ||
this.uses_eval = this.uses_eval || scope.uses_eval; | ||
const scope_ancestry = (() => { | ||
@@ -762,3 +781,6 @@ const ancestry = []; | ||
AST_Toplevel.DEFMETHOD("_default_mangler_options", function(options) { | ||
/** | ||
* Format the mangler options (if any) into their appropriate types | ||
*/ | ||
export function format_mangler_options(options) { | ||
options = defaults(options, { | ||
@@ -784,6 +806,6 @@ eval : false, | ||
return options; | ||
}); | ||
} | ||
AST_Toplevel.DEFMETHOD("mangle_names", function(options) { | ||
options = this._default_mangler_options(options); | ||
options = format_mangler_options(options); | ||
var nth_identifier = options.nth_identifier; | ||
@@ -912,3 +934,3 @@ | ||
AST_Toplevel.DEFMETHOD("expand_names", function(options) { | ||
options = this._default_mangler_options(options); | ||
options = format_mangler_options(options); | ||
var nth_identifier = options.nth_identifier; | ||
@@ -956,3 +978,3 @@ if (nth_identifier.reset && nth_identifier.sort) { | ||
AST_Toplevel.DEFMETHOD("compute_char_frequency", function(options) { | ||
options = this._default_mangler_options(options); | ||
options = format_mangler_options(options); | ||
var nth_identifier = options.nth_identifier; | ||
@@ -959,0 +981,0 @@ if (!nth_identifier.reset || !nth_identifier.consider || !nth_identifier.sort) { |
@@ -428,5 +428,7 @@ import { | ||
AST_Symbol.prototype._size = function () { | ||
return !mangle_options || this.definition().unmangleable(mangle_options) | ||
? this.name.length | ||
: 1; | ||
if (!(mangle_options && this.thedef && !this.thedef.unmangleable(mangle_options))) { | ||
return this.name.length; | ||
} else { | ||
return 1; | ||
} | ||
}; | ||
@@ -440,8 +442,4 @@ | ||
AST_SymbolRef.prototype._size = AST_SymbolDeclaration.prototype._size = function () { | ||
const { name, thedef } = this; | ||
if (this.name === "arguments") return 9; | ||
if (thedef && thedef.global) return name.length; | ||
if (name === "arguments") return 9; | ||
return AST_Symbol.prototype._size.call(this); | ||
@@ -448,0 +446,0 @@ }; |
@@ -7,3 +7,3 @@ { | ||
"license": "BSD-2-Clause", | ||
"version": "5.16.0", | ||
"version": "5.16.1", | ||
"engines": { | ||
@@ -10,0 +10,0 @@ "node": ">=10" |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
2055397
42
58557