Updated the files.
This commit is contained in:
parent
1553e6b971
commit
753967d4f5
23418 changed files with 3784666 additions and 0 deletions
680
my-app/node_modules/terser/CHANGELOG.md
generated
vendored
Executable file
680
my-app/node_modules/terser/CHANGELOG.md
generated
vendored
Executable file
|
@ -0,0 +1,680 @@
|
|||
# Changelog
|
||||
|
||||
## v5.26.0
|
||||
- Do not take the `/*#__PURE__*/` annotation into account when the `side_effects` compress option is off.
|
||||
- The `preserve_annotations` option now automatically opts annotation comments in, instead of requiring the `comments` option to be configured for this.
|
||||
- Refuse to parse empty parenthesized expressions (`()`)
|
||||
|
||||
## v5.25.0
|
||||
- Regex properties added to reserved property mangler (#1471)
|
||||
- `pure_new` option added to drop unused `new` expressions.
|
||||
|
||||
## v5.24.0
|
||||
- Improve formatting performance in V8 by keeping a small work string and a large output string
|
||||
|
||||
## v5.23.0
|
||||
- When top_retain will keep a variable assignment around, inline the assignee when it's shorter than the name (#1434)
|
||||
- Remove empty class `static {}` blocks.
|
||||
|
||||
## v5.22.0
|
||||
- Do not `unsafe`ly shorten expressions like a?.toString() when they're conditional.
|
||||
- Avoid running drop_unused in nodes that aren't scopes. Fixes a rare crash.
|
||||
- When 'module' is enabled, assume strict mode when figuring out scopes.
|
||||
|
||||
## v5.21.0
|
||||
- Do not inline functions that would be retained in the toplevel (as this would cause code duplication).
|
||||
- Fix precedence of arrow function and ternary operator when formatting output.
|
||||
|
||||
## v5.20.0
|
||||
- Passing `minify()` zero files will now throw a clean exception (#1450)
|
||||
- `drop_console` supports passing in an array of `console.*` method names (#1445)
|
||||
- New DOM properties from the WebGPU API have been added for use in the property mangler (#1436)
|
||||
- Internal code simplification (#1437)
|
||||
|
||||
## v5.19.4
|
||||
- Prevent creating very deeply nested ternaries from a long list of `if..return`
|
||||
- Prevent inlining classes into other functions, to avoid constructors being compared.
|
||||
|
||||
## v5.19.3
|
||||
- Fix side effect detection of `optional?.chains`.
|
||||
- Add roundRect to domprops.js (#1426)
|
||||
|
||||
## v5.19.2
|
||||
- fix performance hit from avoiding HTML comments in the output
|
||||
|
||||
## v5.19.1
|
||||
- Better avoid outputting `</script>` and HTML comments.
|
||||
- Fix unused variables in class static blocks not being dropped correctly.
|
||||
- Fix sourcemap names of methods that are `async` or `static`
|
||||
|
||||
## v5.19.0
|
||||
- Allow `/*@__MANGLE_PROP__*/` annotation in `object.property`, in addition to property declarations.
|
||||
|
||||
## v5.18.2
|
||||
- Stop using recursion in hoisted defuns fix.
|
||||
|
||||
## v5.18.1
|
||||
- Fix major performance issue caused by hoisted defuns' scopes bugfix.
|
||||
|
||||
## v5.18.0
|
||||
- Add new `/*@__MANGLE_PROP__*/` annotation, to mark properties that should be mangled.
|
||||
|
||||
## v5.17.7
|
||||
- Update some dependencies
|
||||
- Add consistent sorting for `v` RegExp flag
|
||||
- Add `inert` DOM attribute to domprops
|
||||
|
||||
## v5.17.6
|
||||
- Fixes to mozilla AST input and output, for class properties, private properties and static blocks
|
||||
- Fix outputting a shorthand property in quotes when safari10 and ecma=2015 options are enabled
|
||||
- `configurable` and `enumerable`, used in Object.defineProperty, added to domprops (#1393)
|
||||
|
||||
## v5.17.5
|
||||
- Take into account the non-deferred bits of a class, such as static properties, while dropping unused code.
|
||||
|
||||
## v5.17.4
|
||||
|
||||
- Fix crash when trying to negate a class (`!class{}`)
|
||||
- Avoid outputting comments between `yield`/`await` and its argument
|
||||
- Fix detection of left-hand-side of assignment, to avoid optimizing it like any other expression in some edge cases
|
||||
|
||||
## v5.17.3
|
||||
|
||||
- Fix issue with trimming a static class property's contents accessing the class as `this`.
|
||||
|
||||
## v5.17.2
|
||||
- Be less conservative when detecting use-before-definition of `var` in hoisted functions.
|
||||
- Support unusual (but perfectly valid) initializers of for-in and for-of loops.
|
||||
- Fix issue where hoisted function would be dropped if it was after a `continue` statement
|
||||
|
||||
## v5.17.1
|
||||
- Fix evaluating `.length` when the source array might've been mutated
|
||||
|
||||
## v5.17.0
|
||||
- Drop vestigial `= undefined` default argument in IIFE calls (#1366)
|
||||
- Evaluate known arrays' `.length` property when statically determinable
|
||||
- Add `@__KEY__` annotation to mangle string literals (#1365)
|
||||
|
||||
## v5.16.9
|
||||
- Fix parentheses in output of optional chains (`a?.b`) (#1374)
|
||||
- More documentation on source maps (#1368)
|
||||
- New `lhs_constants` option, allowing to stop Terser from swapping comparison operands (#1361)
|
||||
|
||||
## v5.16.8
|
||||
|
||||
- Become even less conservative around function definitions for `reduce_vars`
|
||||
- Fix parsing context of `import.meta` expressions such that method calls are allowed
|
||||
|
||||
## v5.16.6
|
||||
|
||||
- Become less conservative with analyzing function definitions for `reduce_vars`
|
||||
- Parse `import.meta` as a real AST node and not an `object.property`
|
||||
|
||||
## v5.16.5
|
||||
|
||||
- Correctly handle AST transform functions that mutate children arrays
|
||||
- Don't mutate the options object passed to Terser (#1342)
|
||||
- Do not treat BigInt like a number
|
||||
|
||||
## v5.16.4
|
||||
|
||||
- Keep `(defaultArg = undefined) => ...`, because default args don't count for function length
|
||||
- Prevent inlining variables into `?.` optional chains
|
||||
- Avoid removing unused arguments while transforming
|
||||
- Optimize iterating AST node lists
|
||||
- Make sure `catch` and `finally` aren't children of `try` in the AST
|
||||
- Use modern unicode property escapes (`\p{...}`) to parse identifiers when available
|
||||
|
||||
## v5.16.3
|
||||
|
||||
- Ensure function definitions, don't assume the values of variables defined after them.
|
||||
|
||||
## v5.16.2
|
||||
|
||||
- Fix sourcemaps with non-ascii characters (#1318)
|
||||
- Support string module name and export * as (#1336)
|
||||
- Do not move `let` out of `for` initializers, as it can change scoping
|
||||
- Fix a corner case that would generate the invalid syntax `if (something) let x` ("let" in braceless if body)
|
||||
- Knowledge of more native object properties (#1330)
|
||||
- Got rid of Travis (#1323)
|
||||
- Added semi-secret `asObject` sourcemap option to typescript defs (#1321)
|
||||
|
||||
## v5.16.1
|
||||
|
||||
- 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)
|
||||
- Parse `#privatefield in object` (#1279)
|
||||
- Compress `#privatefield in object`
|
||||
|
||||
## v5.15.1
|
||||
|
||||
- Fixed missing parentheses around optional chains
|
||||
- Avoid bare `let` or `const` as the bodies of `if` statements (#1253)
|
||||
- Small internal fixes (#1271)
|
||||
- Avoid inlining a class twice and creating two equivalent but `!==` classes.
|
||||
|
||||
## v5.15.0
|
||||
- Basic support for ES2022 class static initializer blocks.
|
||||
- Add `AudioWorkletNode` constructor options to domprops list (#1230)
|
||||
- Make identity function inliner not inline `id(...expandedArgs)`
|
||||
|
||||
## v5.14.2
|
||||
|
||||
- Security fix for RegExps that should not be evaluated (regexp DDOS)
|
||||
- Source maps improvements (#1211)
|
||||
- Performance improvements in long property access evaluation (#1213)
|
||||
|
||||
## v5.14.1
|
||||
- keep_numbers option added to TypeScript defs (#1208)
|
||||
- Fixed parsing of nested template strings (#1204)
|
||||
|
||||
## v5.14.0
|
||||
- Switched to @jridgewell/source-map for sourcemap generation (#1190, #1181)
|
||||
- Fixed source maps with non-terminated segments (#1106)
|
||||
- Enabled typescript types to be imported from the package (#1194)
|
||||
- Extra DOM props have been added (#1191)
|
||||
- Delete the AST while generating code, as a means to save RAM
|
||||
|
||||
## v5.13.1
|
||||
- Removed self-assignments (`varname=varname`) (closes #1081)
|
||||
- Separated inlining code (for inlining things into references, or removing IIFEs)
|
||||
- Allow multiple identifiers with the same name in `var` destructuring (eg `var { a, a } = x`) (#1176)
|
||||
|
||||
## v5.13.0
|
||||
|
||||
- All calls to eval() were removed (#1171, #1184)
|
||||
- `source-map` was updated to 0.8.0-beta.0 (#1164)
|
||||
- NavigatorUAData was added to domprops to avoid property mangling (#1166)
|
||||
|
||||
## v5.12.1
|
||||
|
||||
- Fixed an issue with function definitions inside blocks (#1155)
|
||||
- Fixed parens of `new` in some situations (closes #1159)
|
||||
|
||||
## v5.12.0
|
||||
|
||||
- `TERSER_DEBUG_DIR` environment variable
|
||||
- @copyright comments are now preserved with the comments="some" option (#1153)
|
||||
|
||||
## v5.11.0
|
||||
|
||||
- Unicode code point escapes (`\u{abcde}`) are not emitted inside RegExp literals anymore (#1147)
|
||||
- acorn is now a regular dependency
|
||||
|
||||
## v5.10.0
|
||||
|
||||
- Massive optimization to max_line_len (#1109)
|
||||
- Basic support for import assertions
|
||||
- Marked ES2022 Object.hasOwn as a pure function
|
||||
- Fix `delete optional?.property`
|
||||
- New CI/CD pipeline with github actions (#1057)
|
||||
- Fix reordering of switch branches (#1092), (#1084)
|
||||
- Fix error when creating a class property called `get`
|
||||
- Acorn dependency is now an optional peerDependency
|
||||
- Fix mangling collision with exported variables (#1072)
|
||||
- Fix an issue with `return someVariable = (async () => { ... })()` (#1073)
|
||||
|
||||
## v5.9.0
|
||||
|
||||
- Collapsing switch cases with the same bodies (even if they're not next to each other) (#1070).
|
||||
- Fix evaluation of optional chain expressions (#1062)
|
||||
- Fix mangling collision in ESM exports (#1063)
|
||||
- Fix issue with mutating function objects after a second pass (#1047)
|
||||
- Fix for inlining object spread `{ ...obj }` (#1071)
|
||||
- Typescript typings fix (#1069)
|
||||
|
||||
## v5.8.0
|
||||
|
||||
- Fixed shadowing variables while moving code in some cases (#1065)
|
||||
- Stop mangling computed & quoted properties when keep_quoted is enabled.
|
||||
- Fix for mangling private getter/setter and .#private access (#1060, #1068)
|
||||
- Array.from has a new optimization when the unsafe option is set (#737)
|
||||
- Mangle/propmangle let you generate your own identifiers through the nth_identifier option (#1061)
|
||||
- More optimizations to switch statements (#1044)
|
||||
|
||||
## v5.7.2
|
||||
|
||||
- Fixed issues with compressing functions defined in `global_defs` option (#1036)
|
||||
- New recipe for using Terser in gulp was added to RECIPES.md (#1035)
|
||||
- Fixed issues with `??` and `?.` (#1045)
|
||||
- Future reserved words such as `package` no longer require you to disable strict mode to be used as names.
|
||||
- Refactored huge compressor file into multiple more focused files.
|
||||
- Avoided unparenthesized `in` operator in some for loops (it breaks parsing because of for..in loops)
|
||||
- Improved documentation (#1021, #1025)
|
||||
- More type definitions (#1021)
|
||||
|
||||
## v5.7.1
|
||||
|
||||
- Avoided collapsing assignments together if it would place a chain assignment on the left hand side, which is invalid syntax (`a?.b = c`)
|
||||
- Removed undefined from object expansions (`{ ...void 0 }` -> `{}`)
|
||||
- Fix crash when checking if something is nullish or undefined (#1009)
|
||||
- Fixed comparison of private class properties (#1015)
|
||||
- Minor performance improvements (#993)
|
||||
- Fixed scope of function defs in strict mode (they are block scoped)
|
||||
|
||||
## v5.7.0
|
||||
|
||||
- Several compile-time evaluation and inlining fixes
|
||||
- Allow `reduce_funcs` to be disabled again.
|
||||
- Add `spidermonkey` options to parse and format (#974)
|
||||
- Accept `{get = "default val"}` and `{set = "default val"}` in destructuring arguments.
|
||||
- Change package.json export map to help require.resolve (#971)
|
||||
- Improve docs
|
||||
- Fix `export default` of an anonymous class with `extends`
|
||||
|
||||
## v5.6.1
|
||||
|
||||
- Mark assignments to the `.prototype` of a class as pure
|
||||
- Parenthesize `await` on the left of `**` (while accepting legacy non-parenthesised input)
|
||||
- Avoided outputting NUL bytes in optimized RegExps, to stop the output from breaking other tools
|
||||
- Added `exports` to domprops (#939)
|
||||
- Fixed a crash when spreading `...this`
|
||||
- Fixed the computed size of arrow functions, which improves their inlining
|
||||
|
||||
## v5.6.0
|
||||
|
||||
- Added top-level await
|
||||
- Beautify option has been removed in #895
|
||||
- Private properties, getters and setters have been added in #913 and some more commits
|
||||
- Docs improvements: #896, #903, #916
|
||||
|
||||
## v5.5.1
|
||||
|
||||
- Fixed object properties with unicode surrogates on safari.
|
||||
|
||||
## v5.5.0
|
||||
|
||||
- Fixed crash when inlining uninitialized variable into template string.
|
||||
- The sourcemap for dist was removed for being too large.
|
||||
|
||||
## v5.4.0
|
||||
|
||||
- Logical assignment
|
||||
- Change `let x = undefined` to just `let x`
|
||||
- Removed some optimizations for template strings, placing them behind `unsafe` options. Reason: adding strings is not equivalent to template strings, due to valueOf differences.
|
||||
- The AST_Token class was slimmed down in order to use less memory.
|
||||
|
||||
## v5.3.8
|
||||
|
||||
- Restore node 13 support
|
||||
|
||||
## v5.3.7
|
||||
|
||||
Hotfix release, fixes package.json "engines" syntax
|
||||
|
||||
## v5.3.6
|
||||
|
||||
- Fixed parentheses when outputting `??` mixed with `||` and `&&`
|
||||
- Improved hygiene of the symbol generator
|
||||
|
||||
## v5.3.5
|
||||
|
||||
- Avoid moving named functions into default exports.
|
||||
- Enabled transform() for chain expressions. This allows AST transformers to reach inside chain expressions.
|
||||
|
||||
## v5.3.4
|
||||
|
||||
- Fixed a crash when hoisting (with `hoist_vars`) a destructuring variable declaration
|
||||
|
||||
## v5.3.3
|
||||
|
||||
- `source-map` library has been updated, bringing memory usage and CPU time improvements when reading input source maps (the SourceMapConsumer is now WASM based).
|
||||
- The `wrap_func_args` option now also wraps arrow functions, as opposed to only function expressions.
|
||||
|
||||
## v5.3.2
|
||||
|
||||
- Prevented spread operations from being expanded when the expanded array/object contains getters, setters, or array holes.
|
||||
- Fixed _very_ slow self-recursion in some cases of removing extraneous parentheses from `+` operations.
|
||||
|
||||
## v5.3.1
|
||||
|
||||
- An issue with destructuring declarations when `pure_getters` is enabled has been fixed
|
||||
- Fixed a crash when chain expressions need to be shallowly compared
|
||||
- Made inlining functions more conservative to make sure a function that contains a reference to itself isn't moved into a place that can create multiple instances of itself.
|
||||
|
||||
## v5.3.0
|
||||
|
||||
- Fixed a crash when compressing object spreads in some cases
|
||||
- Fixed compiletime evaluation of optional chains (caused typeof a?.b to always return "object")
|
||||
- domprops has been updated to contain every single possible prop
|
||||
|
||||
## v5.2.1
|
||||
|
||||
- The parse step now doesn't accept an `ecma` option, so that all ES code is accepted.
|
||||
- Optional dotted chains now accept keywords, just like dotted expressions (`foo?.default`)
|
||||
|
||||
## v5.2.0
|
||||
|
||||
- Optional chaining syntax is now supported.
|
||||
- Consecutive await expressions don't have unnecessary parens
|
||||
- Taking the variable name's length (after mangling) into consideration when deciding to inline
|
||||
|
||||
## v5.1.0
|
||||
|
||||
- `import.meta` is now supported
|
||||
- Typescript typings have been improved
|
||||
|
||||
## v5.0.0
|
||||
|
||||
- `in` operator now taken into account during property mangle.
|
||||
- Fixed infinite loop in face of a reference loop in some situations.
|
||||
- Kept exports and imports around even if there's something which will throw before them.
|
||||
- The main exported bundle for commonjs, dist/bundle.min.js is no longer minified.
|
||||
|
||||
## v5.0.0-beta.0
|
||||
|
||||
- BREAKING: `minify()` is now async and rejects a promise instead of returning an error.
|
||||
- BREAKING: Internal AST is no longer exposed, so that it can be improved without releasing breaking changes.
|
||||
- BREAKING: Lowest supported node version is 10
|
||||
- BREAKING: There are no more warnings being emitted
|
||||
- Module is now distributed as a dual package - You can `import` and `require()` too.
|
||||
- Inline improvements were made
|
||||
|
||||
|
||||
-----
|
||||
|
||||
## v4.8.1 (backport)
|
||||
|
||||
- Security fix for RegExps that should not be evaluated (regexp DDOS)
|
||||
|
||||
## v4.8.0
|
||||
|
||||
- Support for numeric separators (`million = 1_000_000`) was added.
|
||||
- Assigning properties to a class is now assumed to be pure.
|
||||
- Fixed bug where `yield` wasn't considered a valid property key in generators.
|
||||
|
||||
## v4.7.0
|
||||
|
||||
- A bug was fixed where an arrow function would have the wrong size
|
||||
- `arguments` object is now considered safe to retrieve properties from (useful for `length`, or `0`) even when `pure_getters` is not set.
|
||||
- Fixed erroneous `const` declarations without value (which is invalid) in some corner cases when using `collapse_vars`.
|
||||
|
||||
## v4.6.13
|
||||
|
||||
- Fixed issue where ES5 object properties were being turned into ES6 object properties due to more lax unicode rules.
|
||||
- Fixed parsing of BigInt with lowercase `e` in them.
|
||||
|
||||
## v4.6.12
|
||||
|
||||
- Fixed subtree comparison code, making it see that `[1,[2, 3]]` is different from `[1, 2, [3]]`
|
||||
- Printing of unicode identifiers has been improved
|
||||
|
||||
## v4.6.11
|
||||
|
||||
- Read unused classes' properties and method keys, to figure out if they use other variables.
|
||||
- Prevent inlining into block scopes when there are name collisions
|
||||
- Functions are no longer inlined into parameter defaults, because they live in their own special scope.
|
||||
- When inlining identity functions, take into account the fact they may be used to drop `this` in function calls.
|
||||
- Nullish coalescing operator (`x ?? y`), plus basic optimization for it.
|
||||
- Template literals in binary expressions such as `+` have been further optimized
|
||||
|
||||
## v4.6.10
|
||||
|
||||
- Do not use reduce_vars when classes are present
|
||||
|
||||
## v4.6.9
|
||||
|
||||
- Check if block scopes actually exist in blocks
|
||||
|
||||
## v4.6.8
|
||||
|
||||
- Take into account "executed bits" of classes like static properties or computed keys, when checking if a class evaluation might throw or have side effects.
|
||||
|
||||
## v4.6.7
|
||||
|
||||
- Some new performance gains through a `AST_Node.size()` method which measures a node's source code length without printing it to a string first.
|
||||
- An issue with setting `--comments` to `false` in the CLI has been fixed.
|
||||
- Fixed some issues with inlining
|
||||
- `unsafe_symbols` compress option was added, which turns `Symbol("name")` into just `Symbol()`
|
||||
- Brought back compress performance improvement through the `AST_Node.equivalent_to(other)` method (which was reverted in v4.6.6).
|
||||
|
||||
## v4.6.6
|
||||
|
||||
(hotfix release)
|
||||
|
||||
- Reverted code to 4.6.4 to allow for more time to investigate an issue.
|
||||
|
||||
## v4.6.5 (REVERTED)
|
||||
|
||||
- Improved compress performance through using a new method to see if two nodes are equivalent, instead of printing them to a string.
|
||||
|
||||
## v4.6.4
|
||||
|
||||
- The `"some"` value in the `comments` output option now preserves `@lic` and other important comments when using `//`
|
||||
- `</script>` is now better escaped in regex, and in comments, when using the `inline_script` output option
|
||||
- Fixed an issue when transforming `new RegExp` into `/.../` when slashes are included in the source
|
||||
- `AST_Node.prototype.constructor` now exists, allowing for easier debugging of crashes
|
||||
- Multiple if statements with the same consequents are now collapsed
|
||||
- Typescript typings improvements
|
||||
- Optimizations while looking for surrogate pairs in strings
|
||||
|
||||
## v4.6.3
|
||||
|
||||
- Annotations such as `/*#__NOINLINE__*/` and `/*#__PURE__*/` may now be preserved using the `preserve_annotations` output option
|
||||
- A TypeScript definition update for the `keep_quoted` output option.
|
||||
|
||||
## v4.6.2
|
||||
|
||||
- A bug where functions were inlined into other functions with scope conflicts has been fixed.
|
||||
- `/*#__NOINLINE__*/` annotation fixed for more use cases where inlining happens.
|
||||
|
||||
## v4.6.1
|
||||
|
||||
- Fixed an issue where a class is duplicated by reduce_vars when there's a recursive reference to the class.
|
||||
|
||||
## v4.6.0
|
||||
|
||||
- Fixed issues with recursive class references.
|
||||
- BigInt evaluation has been prevented, stopping Terser from evaluating BigInts like it would do regular numbers.
|
||||
- Class property support has been added
|
||||
|
||||
## v4.5.1
|
||||
|
||||
(hotfix release)
|
||||
|
||||
- Fixed issue where `() => ({})[something]` was not parenthesised correctly.
|
||||
|
||||
## v4.5.0
|
||||
|
||||
- Inlining has been improved
|
||||
- An issue where keep_fnames combined with functions declared through variables was causing name shadowing has been fixed
|
||||
- You can now set the ES version through their year
|
||||
- The output option `keep_numbers` has been added, which prevents Terser from turning `1000` into `1e3` and such
|
||||
- Internal small optimisations and refactors
|
||||
|
||||
## v4.4.3
|
||||
|
||||
- Number and BigInt parsing has been fixed
|
||||
- `/*#__INLINE__*/` annotation fixed for arrow functions with non-block bodies.
|
||||
- Functional tests have been added, using [this repository](https://github.com/terser/terser-functional-tests).
|
||||
- A memory leak, where the entire AST lives on after compression, has been plugged.
|
||||
|
||||
## v4.4.2
|
||||
|
||||
- Fixed a problem with inlining identity functions
|
||||
|
||||
## v4.4.1
|
||||
|
||||
*note:* This introduced a feature, therefore it should have been a minor release.
|
||||
|
||||
- Fixed a crash when `unsafe` was enabled.
|
||||
- An issue has been fixed where `let` statements might be collapsed out of their scope.
|
||||
- Some error messages have been improved by adding quotes around variable names.
|
||||
|
||||
## v4.4.0
|
||||
|
||||
- Added `/*#__INLINE__*/` and `/*#__NOINLINE__*/` annotations for calls. If a call has one of these, it either forces or forbids inlining.
|
||||
|
||||
## v4.3.11
|
||||
|
||||
- Fixed a problem where `window` was considered safe to access, even though there are situations where it isn't (Node.js, workers...)
|
||||
- Fixed an error where `++` and `--` were considered side-effect free
|
||||
- `Number(x)` now needs both `unsafe` and and `unsafe_math` to be compressed into `+x` because `x` might be a `BigInt`
|
||||
- `keep_fnames` now correctly supports regexes when the function is in a variable declaration
|
||||
|
||||
## v4.3.10
|
||||
|
||||
- Fixed syntax error when repeated semicolons were encountered in classes
|
||||
- Fixed invalid output caused by the creation of empty sequences internally
|
||||
- Scopes are now updated when scopes are inlined into them
|
||||
|
||||
## v4.3.9
|
||||
- Fixed issue with mangle's `keep_fnames` option, introduced when adding code to keep variable names of anonymous functions
|
||||
|
||||
## v4.3.8
|
||||
|
||||
- Typescript typings fix
|
||||
|
||||
## v4.3.7
|
||||
|
||||
- Parsing of regex options in the CLI (which broke in v4.3.5) was fixed.
|
||||
- typescript definition updates
|
||||
|
||||
## v4.3.6
|
||||
|
||||
(crash hotfix)
|
||||
|
||||
## v4.3.5
|
||||
|
||||
- Fixed an issue with DOS line endings strings separated by `\` and a new line.
|
||||
- Improved fix for the output size regression related to unused references within the extends section of a class.
|
||||
- Variable names of anonymous functions (eg: `const x = () => { ... }` or `var func = function () {...}`) are now preserved when keep_fnames is true.
|
||||
- Fixed performance degradation introduced for large payloads in v4.2.0
|
||||
|
||||
## v4.3.4
|
||||
|
||||
- Fixed a regression where the output size was increased when unused classes were referred to in the extends clause of a class.
|
||||
- Small typescript typings fixes.
|
||||
- Comments with `@preserve`, `@license`, `@cc_on` as well as comments starting with `/*!` and `/**!` are now preserved by default.
|
||||
|
||||
## v4.3.3
|
||||
|
||||
- Fixed a problem where parsing template strings would mix up octal notation and a slash followed by a zero representing a null character.
|
||||
- Started accepting the name `async` in destructuring arguments with default value.
|
||||
- Now Terser takes into account side effects inside class `extends` clauses.
|
||||
- Added parens whenever there's a comment between a return statement and the returned value, to prevent issues with ASI.
|
||||
- Stopped using raw RegExp objects, since the spec is going to continue to evolve. This ensures Terser is able to process new, unknown RegExp flags and features. This is a breaking change in the AST node AST_RegExp.
|
||||
|
||||
## v4.3.2
|
||||
|
||||
- Typescript typing fix
|
||||
- Ensure that functions can't be inlined, by reduce_vars, into places where they're accessing variables with the same name, but from somewhere else.
|
||||
|
||||
## v4.3.1
|
||||
|
||||
- Fixed an issue from 4.3.0 where any block scope within a for loop erroneously had its parent set to the function scopee
|
||||
- Fixed an issue where compressing IIFEs with argument expansions would result in some parameters becoming undefined
|
||||
- addEventListener options argument's properties are now part of the DOM properties list.
|
||||
|
||||
## v4.3.0
|
||||
|
||||
- Do not drop computed object keys with side effects
|
||||
- Functions passed to other functions in calls are now wrapped in parentheses by default, which speeds up loading most modules
|
||||
- Objects with computed properties are now less likely to be hoisted
|
||||
- Speed and memory efficiency optimizations
|
||||
- Fixed scoping issues with `try` and `switch`
|
||||
|
||||
## v4.2.1
|
||||
|
||||
- Minor refactors
|
||||
- Fixed a bug similar to #369 in collapse_vars
|
||||
- Functions can no longer be inlined into a place where they're going to be compared with themselves.
|
||||
- reduce_funcs option is now legacy, as using reduce_vars without reduce_funcs caused some weird corner cases. As a result, it is now implied in reduce_vars and can't be turned off without turning off reduce_vars.
|
||||
- Bug which would cause a random stack overflow has now been fixed.
|
||||
|
||||
## v4.2.0
|
||||
|
||||
- When the source map URL is `inline`, don't write it to a file.
|
||||
- Fixed output parens when a lambda literal is the tag on a tagged template string.
|
||||
- The `mangle.properties.undeclared` option was added. This enables the property mangler to mangle properties of variables which can be found in the name cache, but whose properties are not known to this Terser run.
|
||||
- The v8 bug where the toString and source representations of regexes like `RegExp("\\\n")` includes an actual newline is now fixed.
|
||||
- Now we're guaranteed to not have duplicate comments in the output
|
||||
- Domprops updates
|
||||
|
||||
## v4.1.4
|
||||
|
||||
- Fixed a crash when inlining a function into somewhere else when it has interdependent, non-removable variables.
|
||||
|
||||
## v4.1.3
|
||||
|
||||
- Several issues with the `reduce_vars` option were fixed.
|
||||
- Starting this version, we only have a dist/bundle.min.js
|
||||
|
||||
## v4.1.2
|
||||
|
||||
- The hotfix was hotfixed
|
||||
|
||||
## v4.1.1
|
||||
|
||||
- Fixed a bug where toplevel scopes were being mixed up with lambda scopes
|
||||
|
||||
## v4.1.0
|
||||
|
||||
- Internal functions were replaced by `Object.assign`, `Array.prototype.some`, `Array.prototype.find` and `Array.prototype.every`.
|
||||
- A serious issue where some ESM-native code was broken was fixed.
|
||||
- Performance improvements were made.
|
||||
- Support for BigInt was added.
|
||||
- Inline efficiency was improved. Functions are now being inlined more proactively instead of being inlined only after another Compressor pass.
|
||||
|
||||
## v4.0.2
|
||||
|
||||
(Hotfix release. Reverts unmapped segments PR [#342](https://github.com/terser/terser/pull/342), which will be put back on Terser when the upstream issue is resolved)
|
||||
|
||||
## v4.0.1
|
||||
|
||||
- Collisions between the arguments of inlined functions and names in the outer scope are now being avoided while inlining
|
||||
- Unmapped segments are now preserved when compressing a file which has source maps
|
||||
- Default values of functions are now correctly converted from Mozilla AST to Terser AST
|
||||
- JSON ⊂ ECMAScript spec (if you don't know what this is you don't need to)
|
||||
- Export AST_* classes to library users
|
||||
- Fixed issue with `collapse_vars` when functions are created with the same name as a variable which already exists
|
||||
- Added `MutationObserverInit` (Object with options for initialising a mutation observer) properties to the DOM property list
|
||||
- Custom `Error` subclasses are now internally used instead of old-school Error inheritance hacks.
|
||||
- Documentation fixes
|
||||
- Performance optimizations
|
||||
|
||||
## v4.0.0
|
||||
|
||||
- **breaking change**: The `variables` property of all scopes has become a standard JavaScript `Map` as opposed to the old bespoke `Dictionary` object.
|
||||
- Typescript definitions were fixed
|
||||
- `terser --help` was fixed
|
||||
- The public interface was cleaned up
|
||||
- Fixed optimisation of `Array` and `new Array`
|
||||
- Added the `keep_quoted=strict` mode to mangle_props, which behaves more like Google Closure Compiler by mangling all unquoted property names, instead of reserving quoted property names automatically.
|
||||
- Fixed parent functions' parameters being shadowed in some cases
|
||||
- Allowed Terser to run in a situation where there are custom functions attached to Object.prototype
|
||||
- And more bug fixes, optimisations and internal changes
|
||||
|
||||
## v3.17.0
|
||||
|
||||
- More DOM properties added to --mangle-properties's DOM property list
|
||||
- Closed issue where if 2 functions had the same argument name, Terser would not inline them together properly
|
||||
- Fixed issue with `hasOwnProperty.call`
|
||||
- You can now list files to minify in a Terser config file
|
||||
- Started replacing `new Array(<number>)` with an array literal
|
||||
- Started using ES6 capabilities like `Set` and the `includes` method for strings and arrays
|
||||
|
||||
## v3.16.1
|
||||
|
||||
- Fixed issue where Terser being imported with `import` would cause it not to work due to the `__esModule` property. (PR #254 was submitted, which was nice, but since it wasn't a pure commonJS approach I decided to go with my own solution)
|
||||
|
||||
## v3.16.0
|
||||
|
||||
- No longer leaves names like Array or Object or window as a SimpleStatement (statement which is just a single expression).
|
||||
- Add support for sections sourcemaps (IndexedSourceMapConsumer)
|
||||
- Drops node.js v4 and starts using commonJS
|
||||
- Is now built with rollup
|
||||
|
||||
## v3.15.0
|
||||
|
||||
- Inlined spread syntax (`[...[1, 2, 3], 4, 5] => [1, 2, 3, 4, 5]`) in arrays and objects.
|
||||
- Fixed typo in compressor warning
|
||||
- Fixed inline source map input bug
|
||||
- Fixed parsing of template literals with unnecessary escapes (Like `\\a`)
|
27
my-app/node_modules/terser/LICENSE
generated
vendored
Executable file
27
my-app/node_modules/terser/LICENSE
generated
vendored
Executable file
|
@ -0,0 +1,27 @@
|
|||
Copyright 2012-2018 (c) Mihai Bazon <mihai.bazon@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials
|
||||
provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
15
my-app/node_modules/terser/PATRONS.md
generated
vendored
Executable file
15
my-app/node_modules/terser/PATRONS.md
generated
vendored
Executable file
|
@ -0,0 +1,15 @@
|
|||
# Our patrons
|
||||
|
||||
These are the first-tier patrons from Patreon (notice: **The Terser Patreon is shutting down in favor of opencollective**). My appreciation goes to everyone on this list for supporting the project!
|
||||
|
||||
* 38elements
|
||||
* Alan Orozco
|
||||
* Aria Buckles
|
||||
* CKEditor
|
||||
* Mariusz Nowak
|
||||
* Nakshatra Mukhopadhyay
|
||||
* Philippe Léger
|
||||
* Piotrek Koszuliński
|
||||
* Serhiy Shyyko
|
||||
* Viktor Hubert
|
||||
* 龙腾道
|
1419
my-app/node_modules/terser/README.md
generated
vendored
Executable file
1419
my-app/node_modules/terser/README.md
generated
vendored
Executable file
File diff suppressed because it is too large
Load diff
10
my-app/node_modules/terser/bin/package.json
generated
vendored
Executable file
10
my-app/node_modules/terser/bin/package.json
generated
vendored
Executable file
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"name": "bin",
|
||||
"private": true,
|
||||
"version": "1.0.0",
|
||||
"main": "terser",
|
||||
"type": "commonjs",
|
||||
"author": "",
|
||||
"license": "BSD-2-Clause",
|
||||
"description": "A package to hold the Terser bin bundle as commonjs while keeping the rest of it ESM."
|
||||
}
|
21
my-app/node_modules/terser/bin/terser
generated
vendored
Executable file
21
my-app/node_modules/terser/bin/terser
generated
vendored
Executable file
|
@ -0,0 +1,21 @@
|
|||
#!/usr/bin/env node
|
||||
|
||||
"use strict";
|
||||
|
||||
require("../tools/exit.cjs");
|
||||
|
||||
try {
|
||||
require("source-map-support").install();
|
||||
} catch (err) {}
|
||||
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
const program = require("commander");
|
||||
|
||||
const packageJson = require("../package.json");
|
||||
const { _run_cli: run_cli } = require("..");
|
||||
|
||||
run_cli({ program, packageJson, fs, path }).catch((error) => {
|
||||
console.error(error);
|
||||
process.exitCode = 1;
|
||||
});
|
10
my-app/node_modules/terser/bin/uglifyjs
generated
vendored
Executable file
10
my-app/node_modules/terser/bin/uglifyjs
generated
vendored
Executable file
|
@ -0,0 +1,10 @@
|
|||
#!/usr/bin/env node
|
||||
// -*- js -*-
|
||||
/* eslint-env node */
|
||||
|
||||
"use strict";
|
||||
|
||||
process.stderr.write( "DEPRECATION WARNING: uglifyjs binary will soon be discontinued!\n");
|
||||
process.stderr.write("Please use \"terser\" instead.\n\n");
|
||||
|
||||
require("./terser");
|
0
my-app/node_modules/terser/dist/.gitkeep
generated
vendored
Executable file
0
my-app/node_modules/terser/dist/.gitkeep
generated
vendored
Executable file
31338
my-app/node_modules/terser/dist/bundle.min.js
generated
vendored
Executable file
31338
my-app/node_modules/terser/dist/bundle.min.js
generated
vendored
Executable file
File diff suppressed because one or more lines are too long
10
my-app/node_modules/terser/dist/package.json
generated
vendored
Executable file
10
my-app/node_modules/terser/dist/package.json
generated
vendored
Executable file
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"name": "dist",
|
||||
"private": true,
|
||||
"version": "1.0.0",
|
||||
"main": "bundle.min.js",
|
||||
"type": "commonjs",
|
||||
"author": "",
|
||||
"license": "BSD-2-Clause",
|
||||
"description": "A package to hold the Terser dist bundle as commonjs while keeping the rest of it ESM. Nothing to see here."
|
||||
}
|
3339
my-app/node_modules/terser/lib/ast.js
generated
vendored
Executable file
3339
my-app/node_modules/terser/lib/ast.js
generated
vendored
Executable file
File diff suppressed because it is too large
Load diff
481
my-app/node_modules/terser/lib/cli.js
generated
vendored
Executable file
481
my-app/node_modules/terser/lib/cli.js
generated
vendored
Executable file
|
@ -0,0 +1,481 @@
|
|||
import { minify, _default_options } from "../main.js";
|
||||
import { parse } from "./parse.js";
|
||||
import {
|
||||
AST_Assign,
|
||||
AST_Array,
|
||||
AST_Constant,
|
||||
AST_Node,
|
||||
AST_PropAccess,
|
||||
AST_RegExp,
|
||||
AST_Sequence,
|
||||
AST_Symbol,
|
||||
AST_Token,
|
||||
walk
|
||||
} from "./ast.js";
|
||||
import { OutputStream } from "./output.js";
|
||||
|
||||
export async function run_cli({ program, packageJson, fs, path }) {
|
||||
const skip_keys = new Set([ "cname", "parent_scope", "scope", "uses_eval", "uses_with" ]);
|
||||
var files = {};
|
||||
var options = {
|
||||
compress: false,
|
||||
mangle: false
|
||||
};
|
||||
const default_options = await _default_options();
|
||||
program.version(packageJson.name + " " + packageJson.version);
|
||||
program.parseArgv = program.parse;
|
||||
program.parse = undefined;
|
||||
|
||||
if (process.argv.includes("ast")) program.helpInformation = describe_ast;
|
||||
else if (process.argv.includes("options")) program.helpInformation = function() {
|
||||
var text = [];
|
||||
for (var option in default_options) {
|
||||
text.push("--" + (option === "sourceMap" ? "source-map" : option) + " options:");
|
||||
text.push(format_object(default_options[option]));
|
||||
text.push("");
|
||||
}
|
||||
return text.join("\n");
|
||||
};
|
||||
|
||||
program.option("-p, --parse <options>", "Specify parser options.", parse_js());
|
||||
program.option("-c, --compress [options]", "Enable compressor/specify compressor options.", parse_js());
|
||||
program.option("-m, --mangle [options]", "Mangle names/specify mangler options.", parse_js());
|
||||
program.option("--mangle-props [options]", "Mangle properties/specify mangler options.", parse_js());
|
||||
program.option("-f, --format [options]", "Format options.", parse_js());
|
||||
program.option("-b, --beautify [options]", "Alias for --format.", parse_js());
|
||||
program.option("-o, --output <file>", "Output file (default STDOUT).");
|
||||
program.option("--comments [filter]", "Preserve copyright comments in the output.");
|
||||
program.option("--config-file <file>", "Read minify() options from JSON file.");
|
||||
program.option("-d, --define <expr>[=value]", "Global definitions.", parse_js("define"));
|
||||
program.option("--ecma <version>", "Specify ECMAScript release: 5, 2015, 2016 or 2017...");
|
||||
program.option("-e, --enclose [arg[,...][:value[,...]]]", "Embed output in a big function with configurable arguments and values.");
|
||||
program.option("--ie8", "Support non-standard Internet Explorer 8.");
|
||||
program.option("--keep-classnames", "Do not mangle/drop class names.");
|
||||
program.option("--keep-fnames", "Do not mangle/drop function names. Useful for code relying on Function.prototype.name.");
|
||||
program.option("--module", "Input is an ES6 module");
|
||||
program.option("--name-cache <file>", "File to hold mangled name mappings.");
|
||||
program.option("--rename", "Force symbol expansion.");
|
||||
program.option("--no-rename", "Disable symbol expansion.");
|
||||
program.option("--safari10", "Support non-standard Safari 10.");
|
||||
program.option("--source-map [options]", "Enable source map/specify source map options.", parse_js());
|
||||
program.option("--timings", "Display operations run time on STDERR.");
|
||||
program.option("--toplevel", "Compress and/or mangle variables in toplevel scope.");
|
||||
program.option("--wrap <name>", "Embed everything as a function with “exports” corresponding to “name” globally.");
|
||||
program.arguments("[files...]").parseArgv(process.argv);
|
||||
if (program.configFile) {
|
||||
options = JSON.parse(read_file(program.configFile));
|
||||
}
|
||||
if (!program.output && program.sourceMap && program.sourceMap.url != "inline") {
|
||||
fatal("ERROR: cannot write source map to STDOUT");
|
||||
}
|
||||
|
||||
[
|
||||
"compress",
|
||||
"enclose",
|
||||
"ie8",
|
||||
"mangle",
|
||||
"module",
|
||||
"safari10",
|
||||
"sourceMap",
|
||||
"toplevel",
|
||||
"wrap"
|
||||
].forEach(function(name) {
|
||||
if (name in program) {
|
||||
options[name] = program[name];
|
||||
}
|
||||
});
|
||||
|
||||
if ("ecma" in program) {
|
||||
if (program.ecma != (program.ecma | 0)) fatal("ERROR: ecma must be an integer");
|
||||
const ecma = program.ecma | 0;
|
||||
if (ecma > 5 && ecma < 2015)
|
||||
options.ecma = ecma + 2009;
|
||||
else
|
||||
options.ecma = ecma;
|
||||
}
|
||||
if (program.format || program.beautify) {
|
||||
const chosenOption = program.format || program.beautify;
|
||||
options.format = typeof chosenOption === "object" ? chosenOption : {};
|
||||
}
|
||||
if (program.comments) {
|
||||
if (typeof options.format != "object") options.format = {};
|
||||
options.format.comments = typeof program.comments == "string" ? (program.comments == "false" ? false : program.comments) : "some";
|
||||
}
|
||||
if (program.define) {
|
||||
if (typeof options.compress != "object") options.compress = {};
|
||||
if (typeof options.compress.global_defs != "object") options.compress.global_defs = {};
|
||||
for (var expr in program.define) {
|
||||
options.compress.global_defs[expr] = program.define[expr];
|
||||
}
|
||||
}
|
||||
if (program.keepClassnames) {
|
||||
options.keep_classnames = true;
|
||||
}
|
||||
if (program.keepFnames) {
|
||||
options.keep_fnames = true;
|
||||
}
|
||||
if (program.mangleProps) {
|
||||
if (program.mangleProps.domprops) {
|
||||
delete program.mangleProps.domprops;
|
||||
} else {
|
||||
if (typeof program.mangleProps != "object") program.mangleProps = {};
|
||||
if (!Array.isArray(program.mangleProps.reserved)) program.mangleProps.reserved = [];
|
||||
}
|
||||
if (typeof options.mangle != "object") options.mangle = {};
|
||||
options.mangle.properties = program.mangleProps;
|
||||
}
|
||||
if (program.nameCache) {
|
||||
options.nameCache = JSON.parse(read_file(program.nameCache, "{}"));
|
||||
}
|
||||
if (program.output == "ast") {
|
||||
options.format = {
|
||||
ast: true,
|
||||
code: false
|
||||
};
|
||||
}
|
||||
if (program.parse) {
|
||||
if (!program.parse.acorn && !program.parse.spidermonkey) {
|
||||
options.parse = program.parse;
|
||||
} else if (program.sourceMap && program.sourceMap.content == "inline") {
|
||||
fatal("ERROR: inline source map only works with built-in parser");
|
||||
}
|
||||
}
|
||||
if (~program.rawArgs.indexOf("--rename")) {
|
||||
options.rename = true;
|
||||
} else if (!program.rename) {
|
||||
options.rename = false;
|
||||
}
|
||||
|
||||
let convert_path = name => name;
|
||||
if (typeof program.sourceMap == "object" && "base" in program.sourceMap) {
|
||||
convert_path = function() {
|
||||
var base = program.sourceMap.base;
|
||||
delete options.sourceMap.base;
|
||||
return function(name) {
|
||||
return path.relative(base, name);
|
||||
};
|
||||
}();
|
||||
}
|
||||
|
||||
let filesList;
|
||||
if (options.files && options.files.length) {
|
||||
filesList = options.files;
|
||||
|
||||
delete options.files;
|
||||
} else if (program.args.length) {
|
||||
filesList = program.args;
|
||||
}
|
||||
|
||||
if (filesList) {
|
||||
simple_glob(filesList).forEach(function(name) {
|
||||
files[convert_path(name)] = read_file(name);
|
||||
});
|
||||
} else {
|
||||
await new Promise((resolve) => {
|
||||
var chunks = [];
|
||||
process.stdin.setEncoding("utf8");
|
||||
process.stdin.on("data", function(chunk) {
|
||||
chunks.push(chunk);
|
||||
}).on("end", function() {
|
||||
files = [ chunks.join("") ];
|
||||
resolve();
|
||||
});
|
||||
process.stdin.resume();
|
||||
});
|
||||
}
|
||||
|
||||
await run_cli();
|
||||
|
||||
function convert_ast(fn) {
|
||||
return AST_Node.from_mozilla_ast(Object.keys(files).reduce(fn, null));
|
||||
}
|
||||
|
||||
async function run_cli() {
|
||||
var content = program.sourceMap && program.sourceMap.content;
|
||||
if (content && content !== "inline") {
|
||||
options.sourceMap.content = read_file(content, content);
|
||||
}
|
||||
if (program.timings) options.timings = true;
|
||||
|
||||
try {
|
||||
if (program.parse) {
|
||||
if (program.parse.acorn) {
|
||||
files = convert_ast(function(toplevel, name) {
|
||||
return require("acorn").parse(files[name], {
|
||||
ecmaVersion: 2018,
|
||||
locations: true,
|
||||
program: toplevel,
|
||||
sourceFile: name,
|
||||
sourceType: options.module || program.parse.module ? "module" : "script"
|
||||
});
|
||||
});
|
||||
} else if (program.parse.spidermonkey) {
|
||||
files = convert_ast(function(toplevel, name) {
|
||||
var obj = JSON.parse(files[name]);
|
||||
if (!toplevel) return obj;
|
||||
toplevel.body = toplevel.body.concat(obj.body);
|
||||
return toplevel;
|
||||
});
|
||||
}
|
||||
}
|
||||
} catch (ex) {
|
||||
fatal(ex);
|
||||
}
|
||||
|
||||
let result;
|
||||
try {
|
||||
result = await minify(files, options, fs);
|
||||
} catch (ex) {
|
||||
if (ex.name == "SyntaxError") {
|
||||
print_error("Parse error at " + ex.filename + ":" + ex.line + "," + ex.col);
|
||||
var col = ex.col;
|
||||
var lines = files[ex.filename].split(/\r?\n/);
|
||||
var line = lines[ex.line - 1];
|
||||
if (!line && !col) {
|
||||
line = lines[ex.line - 2];
|
||||
col = line.length;
|
||||
}
|
||||
if (line) {
|
||||
var limit = 70;
|
||||
if (col > limit) {
|
||||
line = line.slice(col - limit);
|
||||
col = limit;
|
||||
}
|
||||
print_error(line.slice(0, 80));
|
||||
print_error(line.slice(0, col).replace(/\S/g, " ") + "^");
|
||||
}
|
||||
}
|
||||
if (ex.defs) {
|
||||
print_error("Supported options:");
|
||||
print_error(format_object(ex.defs));
|
||||
}
|
||||
fatal(ex);
|
||||
return;
|
||||
}
|
||||
|
||||
if (program.output == "ast") {
|
||||
if (!options.compress && !options.mangle) {
|
||||
result.ast.figure_out_scope({});
|
||||
}
|
||||
console.log(JSON.stringify(result.ast, function(key, value) {
|
||||
if (value) switch (key) {
|
||||
case "thedef":
|
||||
return symdef(value);
|
||||
case "enclosed":
|
||||
return value.length ? value.map(symdef) : undefined;
|
||||
case "variables":
|
||||
case "globals":
|
||||
return value.size ? collect_from_map(value, symdef) : undefined;
|
||||
}
|
||||
if (skip_keys.has(key)) return;
|
||||
if (value instanceof AST_Token) return;
|
||||
if (value instanceof Map) return;
|
||||
if (value instanceof AST_Node) {
|
||||
var result = {
|
||||
_class: "AST_" + value.TYPE
|
||||
};
|
||||
if (value.block_scope) {
|
||||
result.variables = value.block_scope.variables;
|
||||
result.enclosed = value.block_scope.enclosed;
|
||||
}
|
||||
value.CTOR.PROPS.forEach(function(prop) {
|
||||
if (prop !== "block_scope") {
|
||||
result[prop] = value[prop];
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
return value;
|
||||
}, 2));
|
||||
} else if (program.output == "spidermonkey") {
|
||||
try {
|
||||
const minified = await minify(
|
||||
result.code,
|
||||
{
|
||||
compress: false,
|
||||
mangle: false,
|
||||
format: {
|
||||
ast: true,
|
||||
code: false
|
||||
}
|
||||
},
|
||||
fs
|
||||
);
|
||||
console.log(JSON.stringify(minified.ast.to_mozilla_ast(), null, 2));
|
||||
} catch (ex) {
|
||||
fatal(ex);
|
||||
return;
|
||||
}
|
||||
} else if (program.output) {
|
||||
fs.writeFileSync(program.output, result.code);
|
||||
if (options.sourceMap && options.sourceMap.url !== "inline" && result.map) {
|
||||
fs.writeFileSync(program.output + ".map", result.map);
|
||||
}
|
||||
} else {
|
||||
console.log(result.code);
|
||||
}
|
||||
if (program.nameCache) {
|
||||
fs.writeFileSync(program.nameCache, JSON.stringify(options.nameCache));
|
||||
}
|
||||
if (result.timings) for (var phase in result.timings) {
|
||||
print_error("- " + phase + ": " + result.timings[phase].toFixed(3) + "s");
|
||||
}
|
||||
}
|
||||
|
||||
function fatal(message) {
|
||||
if (message instanceof Error) message = message.stack.replace(/^\S*?Error:/, "ERROR:");
|
||||
print_error(message);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// A file glob function that only supports "*" and "?" wildcards in the basename.
|
||||
// Example: "foo/bar/*baz??.*.js"
|
||||
// Argument `glob` may be a string or an array of strings.
|
||||
// Returns an array of strings. Garbage in, garbage out.
|
||||
function simple_glob(glob) {
|
||||
if (Array.isArray(glob)) {
|
||||
return [].concat.apply([], glob.map(simple_glob));
|
||||
}
|
||||
if (glob && glob.match(/[*?]/)) {
|
||||
var dir = path.dirname(glob);
|
||||
try {
|
||||
var entries = fs.readdirSync(dir);
|
||||
} catch (ex) {}
|
||||
if (entries) {
|
||||
var pattern = "^" + path.basename(glob)
|
||||
.replace(/[.+^$[\]\\(){}]/g, "\\$&")
|
||||
.replace(/\*/g, "[^/\\\\]*")
|
||||
.replace(/\?/g, "[^/\\\\]") + "$";
|
||||
var mod = process.platform === "win32" ? "i" : "";
|
||||
var rx = new RegExp(pattern, mod);
|
||||
var results = entries.filter(function(name) {
|
||||
return rx.test(name);
|
||||
}).map(function(name) {
|
||||
return path.join(dir, name);
|
||||
});
|
||||
if (results.length) return results;
|
||||
}
|
||||
}
|
||||
return [ glob ];
|
||||
}
|
||||
|
||||
function read_file(path, default_value) {
|
||||
try {
|
||||
return fs.readFileSync(path, "utf8");
|
||||
} catch (ex) {
|
||||
if ((ex.code == "ENOENT" || ex.code == "ENAMETOOLONG") && default_value != null) return default_value;
|
||||
fatal(ex);
|
||||
}
|
||||
}
|
||||
|
||||
function parse_js(flag) {
|
||||
return function(value, options) {
|
||||
options = options || {};
|
||||
try {
|
||||
walk(parse(value, { expression: true }), node => {
|
||||
if (node instanceof AST_Assign) {
|
||||
var name = node.left.print_to_string();
|
||||
var value = node.right;
|
||||
if (flag) {
|
||||
options[name] = value;
|
||||
} else if (value instanceof AST_Array) {
|
||||
options[name] = value.elements.map(to_string);
|
||||
} else if (value instanceof AST_RegExp) {
|
||||
value = value.value;
|
||||
options[name] = new RegExp(value.source, value.flags);
|
||||
} else {
|
||||
options[name] = to_string(value);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (node instanceof AST_Symbol || node instanceof AST_PropAccess) {
|
||||
var name = node.print_to_string();
|
||||
options[name] = true;
|
||||
return true;
|
||||
}
|
||||
if (!(node instanceof AST_Sequence)) throw node;
|
||||
|
||||
function to_string(value) {
|
||||
return value instanceof AST_Constant ? value.getValue() : value.print_to_string({
|
||||
quote_keys: true
|
||||
});
|
||||
}
|
||||
});
|
||||
} catch(ex) {
|
||||
if (flag) {
|
||||
fatal("Error parsing arguments for '" + flag + "': " + value);
|
||||
} else {
|
||||
options[value] = null;
|
||||
}
|
||||
}
|
||||
return options;
|
||||
};
|
||||
}
|
||||
|
||||
function symdef(def) {
|
||||
var ret = (1e6 + def.id) + " " + def.name;
|
||||
if (def.mangled_name) ret += " " + def.mangled_name;
|
||||
return ret;
|
||||
}
|
||||
|
||||
function collect_from_map(map, callback) {
|
||||
var result = [];
|
||||
map.forEach(function (def) {
|
||||
result.push(callback(def));
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
function format_object(obj) {
|
||||
var lines = [];
|
||||
var padding = "";
|
||||
Object.keys(obj).map(function(name) {
|
||||
if (padding.length < name.length) padding = Array(name.length + 1).join(" ");
|
||||
return [ name, JSON.stringify(obj[name]) ];
|
||||
}).forEach(function(tokens) {
|
||||
lines.push(" " + tokens[0] + padding.slice(tokens[0].length - 2) + tokens[1]);
|
||||
});
|
||||
return lines.join("\n");
|
||||
}
|
||||
|
||||
function print_error(msg) {
|
||||
process.stderr.write(msg);
|
||||
process.stderr.write("\n");
|
||||
}
|
||||
|
||||
function describe_ast() {
|
||||
var out = OutputStream({ beautify: true });
|
||||
function doitem(ctor) {
|
||||
out.print("AST_" + ctor.TYPE);
|
||||
const props = ctor.SELF_PROPS.filter(prop => !/^\$/.test(prop));
|
||||
|
||||
if (props.length > 0) {
|
||||
out.space();
|
||||
out.with_parens(function() {
|
||||
props.forEach(function(prop, i) {
|
||||
if (i) out.space();
|
||||
out.print(prop);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
if (ctor.documentation) {
|
||||
out.space();
|
||||
out.print_string(ctor.documentation);
|
||||
}
|
||||
|
||||
if (ctor.SUBCLASSES.length > 0) {
|
||||
out.space();
|
||||
out.with_block(function() {
|
||||
ctor.SUBCLASSES.forEach(function(ctor) {
|
||||
out.indent();
|
||||
doitem(ctor);
|
||||
out.newline();
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
doitem(AST_Node);
|
||||
return out + "\n";
|
||||
}
|
||||
}
|
348
my-app/node_modules/terser/lib/compress/common.js
generated
vendored
Executable file
348
my-app/node_modules/terser/lib/compress/common.js
generated
vendored
Executable file
|
@ -0,0 +1,348 @@
|
|||
/***********************************************************************
|
||||
|
||||
A JavaScript tokenizer / parser / beautifier / compressor.
|
||||
https://github.com/mishoo/UglifyJS2
|
||||
|
||||
-------------------------------- (C) ---------------------------------
|
||||
|
||||
Author: Mihai Bazon
|
||||
<mihai.bazon@gmail.com>
|
||||
http://mihai.bazon.net/blog
|
||||
|
||||
Distributed under the BSD license:
|
||||
|
||||
Copyright 2012 (c) Mihai Bazon <mihai.bazon@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials
|
||||
provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
import {
|
||||
AST_Array,
|
||||
AST_Arrow,
|
||||
AST_BlockStatement,
|
||||
AST_Call,
|
||||
AST_Chain,
|
||||
AST_Class,
|
||||
AST_Const,
|
||||
AST_Constant,
|
||||
AST_DefClass,
|
||||
AST_Defun,
|
||||
AST_EmptyStatement,
|
||||
AST_Export,
|
||||
AST_False,
|
||||
AST_Function,
|
||||
AST_Import,
|
||||
AST_Infinity,
|
||||
AST_LabeledStatement,
|
||||
AST_Lambda,
|
||||
AST_Let,
|
||||
AST_LoopControl,
|
||||
AST_NaN,
|
||||
AST_Node,
|
||||
AST_Null,
|
||||
AST_Number,
|
||||
AST_Object,
|
||||
AST_ObjectKeyVal,
|
||||
AST_PropAccess,
|
||||
AST_RegExp,
|
||||
AST_Scope,
|
||||
AST_Sequence,
|
||||
AST_SimpleStatement,
|
||||
AST_Statement,
|
||||
AST_String,
|
||||
AST_SymbolRef,
|
||||
AST_True,
|
||||
AST_UnaryPrefix,
|
||||
AST_Undefined,
|
||||
|
||||
TreeWalker,
|
||||
walk,
|
||||
walk_abort,
|
||||
walk_parent,
|
||||
} from "../ast.js";
|
||||
import { make_node, regexp_source_fix, string_template, makePredicate } from "../utils/index.js";
|
||||
import { first_in_statement } from "../utils/first_in_statement.js";
|
||||
import { has_flag, TOP } from "./compressor-flags.js";
|
||||
|
||||
export function merge_sequence(array, node) {
|
||||
if (node instanceof AST_Sequence) {
|
||||
array.push(...node.expressions);
|
||||
} else {
|
||||
array.push(node);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
export function make_sequence(orig, expressions) {
|
||||
if (expressions.length == 1) return expressions[0];
|
||||
if (expressions.length == 0) throw new Error("trying to create a sequence with length zero!");
|
||||
return make_node(AST_Sequence, orig, {
|
||||
expressions: expressions.reduce(merge_sequence, [])
|
||||
});
|
||||
}
|
||||
|
||||
export function make_node_from_constant(val, orig) {
|
||||
switch (typeof val) {
|
||||
case "string":
|
||||
return make_node(AST_String, orig, {
|
||||
value: val
|
||||
});
|
||||
case "number":
|
||||
if (isNaN(val)) return make_node(AST_NaN, orig);
|
||||
if (isFinite(val)) {
|
||||
return 1 / val < 0 ? make_node(AST_UnaryPrefix, orig, {
|
||||
operator: "-",
|
||||
expression: make_node(AST_Number, orig, { value: -val })
|
||||
}) : make_node(AST_Number, orig, { value: val });
|
||||
}
|
||||
return val < 0 ? make_node(AST_UnaryPrefix, orig, {
|
||||
operator: "-",
|
||||
expression: make_node(AST_Infinity, orig)
|
||||
}) : make_node(AST_Infinity, orig);
|
||||
case "boolean":
|
||||
return make_node(val ? AST_True : AST_False, orig);
|
||||
case "undefined":
|
||||
return make_node(AST_Undefined, orig);
|
||||
default:
|
||||
if (val === null) {
|
||||
return make_node(AST_Null, orig, { value: null });
|
||||
}
|
||||
if (val instanceof RegExp) {
|
||||
return make_node(AST_RegExp, orig, {
|
||||
value: {
|
||||
source: regexp_source_fix(val.source),
|
||||
flags: val.flags
|
||||
}
|
||||
});
|
||||
}
|
||||
throw new Error(string_template("Can't handle constant of type: {type}", {
|
||||
type: typeof val
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
export function best_of_expression(ast1, ast2) {
|
||||
return ast1.size() > ast2.size() ? ast2 : ast1;
|
||||
}
|
||||
|
||||
export function best_of_statement(ast1, ast2) {
|
||||
return best_of_expression(
|
||||
make_node(AST_SimpleStatement, ast1, {
|
||||
body: ast1
|
||||
}),
|
||||
make_node(AST_SimpleStatement, ast2, {
|
||||
body: ast2
|
||||
})
|
||||
).body;
|
||||
}
|
||||
|
||||
/** Find which node is smaller, and return that */
|
||||
export function best_of(compressor, ast1, ast2) {
|
||||
if (first_in_statement(compressor)) {
|
||||
return best_of_statement(ast1, ast2);
|
||||
} else {
|
||||
return best_of_expression(ast1, ast2);
|
||||
}
|
||||
}
|
||||
|
||||
/** Simplify an object property's key, if possible */
|
||||
export function get_simple_key(key) {
|
||||
if (key instanceof AST_Constant) {
|
||||
return key.getValue();
|
||||
}
|
||||
if (key instanceof AST_UnaryPrefix
|
||||
&& key.operator == "void"
|
||||
&& key.expression instanceof AST_Constant) {
|
||||
return;
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
export function read_property(obj, key) {
|
||||
key = get_simple_key(key);
|
||||
if (key instanceof AST_Node) return;
|
||||
|
||||
var value;
|
||||
if (obj instanceof AST_Array) {
|
||||
var elements = obj.elements;
|
||||
if (key == "length") return make_node_from_constant(elements.length, obj);
|
||||
if (typeof key == "number" && key in elements) value = elements[key];
|
||||
} else if (obj instanceof AST_Object) {
|
||||
key = "" + key;
|
||||
var props = obj.properties;
|
||||
for (var i = props.length; --i >= 0;) {
|
||||
var prop = props[i];
|
||||
if (!(prop instanceof AST_ObjectKeyVal)) return;
|
||||
if (!value && props[i].key === key) value = props[i].value;
|
||||
}
|
||||
}
|
||||
|
||||
return value instanceof AST_SymbolRef && value.fixed_value() || value;
|
||||
}
|
||||
|
||||
export function has_break_or_continue(loop, parent) {
|
||||
var found = false;
|
||||
var tw = new TreeWalker(function(node) {
|
||||
if (found || node instanceof AST_Scope) return true;
|
||||
if (node instanceof AST_LoopControl && tw.loopcontrol_target(node) === loop) {
|
||||
return found = true;
|
||||
}
|
||||
});
|
||||
if (parent instanceof AST_LabeledStatement) tw.push(parent);
|
||||
tw.push(loop);
|
||||
loop.body.walk(tw);
|
||||
return found;
|
||||
}
|
||||
|
||||
// we shouldn't compress (1,func)(something) to
|
||||
// func(something) because that changes the meaning of
|
||||
// the func (becomes lexical instead of global).
|
||||
export function maintain_this_binding(parent, orig, val) {
|
||||
if (
|
||||
parent instanceof AST_UnaryPrefix && parent.operator == "delete"
|
||||
|| parent instanceof AST_Call && parent.expression === orig
|
||||
&& (
|
||||
val instanceof AST_Chain
|
||||
|| val instanceof AST_PropAccess
|
||||
|| val instanceof AST_SymbolRef && val.name == "eval"
|
||||
)
|
||||
) {
|
||||
const zero = make_node(AST_Number, orig, { value: 0 });
|
||||
return make_sequence(orig, [ zero, val ]);
|
||||
} else {
|
||||
return val;
|
||||
}
|
||||
}
|
||||
|
||||
export function is_func_expr(node) {
|
||||
return node instanceof AST_Arrow || node instanceof AST_Function;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to determine whether the node can benefit from negation.
|
||||
* Not the case with arrow functions (you need an extra set of parens). */
|
||||
export function is_iife_call(node) {
|
||||
if (node.TYPE != "Call") return false;
|
||||
return node.expression instanceof AST_Function || is_iife_call(node.expression);
|
||||
}
|
||||
|
||||
export function is_empty(thing) {
|
||||
if (thing === null) return true;
|
||||
if (thing instanceof AST_EmptyStatement) return true;
|
||||
if (thing instanceof AST_BlockStatement) return thing.body.length == 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
export const identifier_atom = makePredicate("Infinity NaN undefined");
|
||||
export function is_identifier_atom(node) {
|
||||
return node instanceof AST_Infinity
|
||||
|| node instanceof AST_NaN
|
||||
|| node instanceof AST_Undefined;
|
||||
}
|
||||
|
||||
/** Check if this is a SymbolRef node which has one def of a certain AST type */
|
||||
export function is_ref_of(ref, type) {
|
||||
if (!(ref instanceof AST_SymbolRef)) return false;
|
||||
var orig = ref.definition().orig;
|
||||
for (var i = orig.length; --i >= 0;) {
|
||||
if (orig[i] instanceof type) return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**Can we turn { block contents... } into just the block contents ?
|
||||
* Not if one of these is inside.
|
||||
**/
|
||||
export function can_be_evicted_from_block(node) {
|
||||
return !(
|
||||
node instanceof AST_DefClass ||
|
||||
node instanceof AST_Defun ||
|
||||
node instanceof AST_Let ||
|
||||
node instanceof AST_Const ||
|
||||
node instanceof AST_Export ||
|
||||
node instanceof AST_Import
|
||||
);
|
||||
}
|
||||
|
||||
export function as_statement_array(thing) {
|
||||
if (thing === null) return [];
|
||||
if (thing instanceof AST_BlockStatement) return thing.body;
|
||||
if (thing instanceof AST_EmptyStatement) return [];
|
||||
if (thing instanceof AST_Statement) return [ thing ];
|
||||
throw new Error("Can't convert thing to statement array");
|
||||
}
|
||||
|
||||
export function is_reachable(scope_node, defs) {
|
||||
const find_ref = node => {
|
||||
if (node instanceof AST_SymbolRef && defs.includes(node.definition())) {
|
||||
return walk_abort;
|
||||
}
|
||||
};
|
||||
|
||||
return walk_parent(scope_node, (node, info) => {
|
||||
if (node instanceof AST_Scope && node !== scope_node) {
|
||||
var parent = info.parent();
|
||||
|
||||
if (
|
||||
parent instanceof AST_Call
|
||||
&& parent.expression === node
|
||||
// Async/Generators aren't guaranteed to sync evaluate all of
|
||||
// their body steps, so it's possible they close over the variable.
|
||||
&& !(node.async || node.is_generator)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (walk(node, find_ref)) return walk_abort;
|
||||
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/** Check if a ref refers to the name of a function/class it's defined within */
|
||||
export function is_recursive_ref(compressor, def) {
|
||||
var node;
|
||||
for (var i = 0; node = compressor.parent(i); i++) {
|
||||
if (node instanceof AST_Lambda || node instanceof AST_Class) {
|
||||
var name = node.name;
|
||||
if (name && name.definition() === def) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO this only works with AST_Defun, shouldn't it work for other ways of defining functions?
|
||||
export function retain_top_func(fn, compressor) {
|
||||
return compressor.top_retain
|
||||
&& fn instanceof AST_Defun
|
||||
&& has_flag(fn, TOP)
|
||||
&& fn.name
|
||||
&& compressor.top_retain(fn.name.definition());
|
||||
}
|
63
my-app/node_modules/terser/lib/compress/compressor-flags.js
generated
vendored
Executable file
63
my-app/node_modules/terser/lib/compress/compressor-flags.js
generated
vendored
Executable file
|
@ -0,0 +1,63 @@
|
|||
/***********************************************************************
|
||||
|
||||
A JavaScript tokenizer / parser / beautifier / compressor.
|
||||
https://github.com/mishoo/UglifyJS2
|
||||
|
||||
-------------------------------- (C) ---------------------------------
|
||||
|
||||
Author: Mihai Bazon
|
||||
<mihai.bazon@gmail.com>
|
||||
http://mihai.bazon.net/blog
|
||||
|
||||
Distributed under the BSD license:
|
||||
|
||||
Copyright 2012 (c) Mihai Bazon <mihai.bazon@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials
|
||||
provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
// bitfield flags to be stored in node.flags.
|
||||
// These are set and unset during compression, and store information in the node without requiring multiple fields.
|
||||
export const UNUSED = 0b00000001;
|
||||
export const TRUTHY = 0b00000010;
|
||||
export const FALSY = 0b00000100;
|
||||
export const UNDEFINED = 0b00001000;
|
||||
export const INLINED = 0b00010000;
|
||||
|
||||
// Nodes to which values are ever written. Used when keep_assign is part of the unused option string.
|
||||
export const WRITE_ONLY = 0b00100000;
|
||||
|
||||
// information specific to a single compression pass
|
||||
export const SQUEEZED = 0b0000000100000000;
|
||||
export const OPTIMIZED = 0b0000001000000000;
|
||||
export const TOP = 0b0000010000000000;
|
||||
export const CLEAR_BETWEEN_PASSES = SQUEEZED | OPTIMIZED | TOP;
|
||||
|
||||
export const has_flag = (node, flag) => node.flags & flag;
|
||||
export const set_flag = (node, flag) => { node.flags |= flag; };
|
||||
export const clear_flag = (node, flag) => { node.flags &= ~flag; };
|
375
my-app/node_modules/terser/lib/compress/drop-side-effect-free.js
generated
vendored
Executable file
375
my-app/node_modules/terser/lib/compress/drop-side-effect-free.js
generated
vendored
Executable file
|
@ -0,0 +1,375 @@
|
|||
/***********************************************************************
|
||||
|
||||
A JavaScript tokenizer / parser / beautifier / compressor.
|
||||
https://github.com/mishoo/UglifyJS2
|
||||
|
||||
-------------------------------- (C) ---------------------------------
|
||||
|
||||
Author: Mihai Bazon
|
||||
<mihai.bazon@gmail.com>
|
||||
http://mihai.bazon.net/blog
|
||||
|
||||
Distributed under the BSD license:
|
||||
|
||||
Copyright 2012 (c) Mihai Bazon <mihai.bazon@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials
|
||||
provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
import {
|
||||
AST_Accessor,
|
||||
AST_Array,
|
||||
AST_Arrow,
|
||||
AST_Assign,
|
||||
AST_Binary,
|
||||
AST_Call,
|
||||
AST_Chain,
|
||||
AST_Class,
|
||||
AST_ClassStaticBlock,
|
||||
AST_ClassProperty,
|
||||
AST_ConciseMethod,
|
||||
AST_Conditional,
|
||||
AST_Constant,
|
||||
AST_DefClass,
|
||||
AST_Dot,
|
||||
AST_Expansion,
|
||||
AST_Function,
|
||||
AST_Node,
|
||||
AST_Number,
|
||||
AST_Object,
|
||||
AST_ObjectGetter,
|
||||
AST_ObjectKeyVal,
|
||||
AST_ObjectProperty,
|
||||
AST_ObjectSetter,
|
||||
AST_PropAccess,
|
||||
AST_Scope,
|
||||
AST_Sequence,
|
||||
AST_SimpleStatement,
|
||||
AST_Sub,
|
||||
AST_SymbolRef,
|
||||
AST_TemplateSegment,
|
||||
AST_TemplateString,
|
||||
AST_This,
|
||||
AST_Unary,
|
||||
} from "../ast.js";
|
||||
import { make_node, return_null, return_this } from "../utils/index.js";
|
||||
import { first_in_statement } from "../utils/first_in_statement.js";
|
||||
|
||||
import { pure_prop_access_globals } from "./native-objects.js";
|
||||
import { lazy_op, unary_side_effects, is_nullish_shortcircuited } from "./inference.js";
|
||||
import { WRITE_ONLY, set_flag, clear_flag } from "./compressor-flags.js";
|
||||
import { make_sequence, is_func_expr, is_iife_call } from "./common.js";
|
||||
|
||||
// AST_Node#drop_side_effect_free() gets called when we don't care about the value,
|
||||
// only about side effects. We'll be defining this method for each node type in this module
|
||||
//
|
||||
// Examples:
|
||||
// foo++ -> foo++
|
||||
// 1 + func() -> func()
|
||||
// 10 -> (nothing)
|
||||
// knownPureFunc(foo++) -> foo++
|
||||
|
||||
function def_drop_side_effect_free(node, func) {
|
||||
node.DEFMETHOD("drop_side_effect_free", func);
|
||||
}
|
||||
|
||||
// Drop side-effect-free elements from an array of expressions.
|
||||
// Returns an array of expressions with side-effects or null
|
||||
// if all elements were dropped. Note: original array may be
|
||||
// returned if nothing changed.
|
||||
function trim(nodes, compressor, first_in_statement) {
|
||||
var len = nodes.length;
|
||||
if (!len) return null;
|
||||
|
||||
var ret = [], changed = false;
|
||||
for (var i = 0; i < len; i++) {
|
||||
var node = nodes[i].drop_side_effect_free(compressor, first_in_statement);
|
||||
changed |= node !== nodes[i];
|
||||
if (node) {
|
||||
ret.push(node);
|
||||
first_in_statement = false;
|
||||
}
|
||||
}
|
||||
return changed ? ret.length ? ret : null : nodes;
|
||||
}
|
||||
|
||||
def_drop_side_effect_free(AST_Node, return_this);
|
||||
def_drop_side_effect_free(AST_Constant, return_null);
|
||||
def_drop_side_effect_free(AST_This, return_null);
|
||||
|
||||
def_drop_side_effect_free(AST_Call, function (compressor, first_in_statement) {
|
||||
if (is_nullish_shortcircuited(this, compressor)) {
|
||||
return this.expression.drop_side_effect_free(compressor, first_in_statement);
|
||||
}
|
||||
|
||||
if (!this.is_callee_pure(compressor)) {
|
||||
if (this.expression.is_call_pure(compressor)) {
|
||||
var exprs = this.args.slice();
|
||||
exprs.unshift(this.expression.expression);
|
||||
exprs = trim(exprs, compressor, first_in_statement);
|
||||
return exprs && make_sequence(this, exprs);
|
||||
}
|
||||
if (is_func_expr(this.expression)
|
||||
&& (!this.expression.name || !this.expression.name.definition().references.length)) {
|
||||
var node = this.clone();
|
||||
node.expression.process_expression(false, compressor);
|
||||
return node;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
var args = trim(this.args, compressor, first_in_statement);
|
||||
return args && make_sequence(this, args);
|
||||
});
|
||||
|
||||
def_drop_side_effect_free(AST_Accessor, return_null);
|
||||
|
||||
def_drop_side_effect_free(AST_Function, return_null);
|
||||
|
||||
def_drop_side_effect_free(AST_Arrow, return_null);
|
||||
|
||||
def_drop_side_effect_free(AST_Class, function (compressor) {
|
||||
const with_effects = [];
|
||||
const trimmed_extends = this.extends && this.extends.drop_side_effect_free(compressor);
|
||||
if (trimmed_extends)
|
||||
with_effects.push(trimmed_extends);
|
||||
|
||||
for (const prop of this.properties) {
|
||||
if (prop instanceof AST_ClassStaticBlock) {
|
||||
if (prop.has_side_effects(compressor)) {
|
||||
return this; // Be cautious about these
|
||||
}
|
||||
} else {
|
||||
const trimmed_prop = prop.drop_side_effect_free(compressor);
|
||||
if (trimmed_prop) {
|
||||
if (trimmed_prop.contains_this()) return this;
|
||||
|
||||
with_effects.push(trimmed_prop);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!with_effects.length)
|
||||
return null;
|
||||
|
||||
const exprs = make_sequence(this, with_effects);
|
||||
if (this instanceof AST_DefClass) {
|
||||
// We want a statement
|
||||
return make_node(AST_SimpleStatement, this, { body: exprs });
|
||||
} else {
|
||||
return exprs;
|
||||
}
|
||||
});
|
||||
|
||||
def_drop_side_effect_free(AST_ClassProperty, function (compressor) {
|
||||
const key = this.computed_key() && this.key.drop_side_effect_free(compressor);
|
||||
|
||||
const value = this.static && this.value
|
||||
&& this.value.drop_side_effect_free(compressor);
|
||||
|
||||
if (key && value)
|
||||
return make_sequence(this, [key, value]);
|
||||
return key || value || null;
|
||||
});
|
||||
|
||||
def_drop_side_effect_free(AST_Binary, function (compressor, first_in_statement) {
|
||||
var right = this.right.drop_side_effect_free(compressor);
|
||||
if (!right)
|
||||
return this.left.drop_side_effect_free(compressor, first_in_statement);
|
||||
if (lazy_op.has(this.operator)) {
|
||||
if (right === this.right)
|
||||
return this;
|
||||
var node = this.clone();
|
||||
node.right = right;
|
||||
return node;
|
||||
} else {
|
||||
var left = this.left.drop_side_effect_free(compressor, first_in_statement);
|
||||
if (!left)
|
||||
return this.right.drop_side_effect_free(compressor, first_in_statement);
|
||||
return make_sequence(this, [left, right]);
|
||||
}
|
||||
});
|
||||
|
||||
def_drop_side_effect_free(AST_Assign, function (compressor) {
|
||||
if (this.logical)
|
||||
return this;
|
||||
|
||||
var left = this.left;
|
||||
if (left.has_side_effects(compressor)
|
||||
|| compressor.has_directive("use strict")
|
||||
&& left instanceof AST_PropAccess
|
||||
&& left.expression.is_constant()) {
|
||||
return this;
|
||||
}
|
||||
set_flag(this, WRITE_ONLY);
|
||||
while (left instanceof AST_PropAccess) {
|
||||
left = left.expression;
|
||||
}
|
||||
if (left.is_constant_expression(compressor.find_parent(AST_Scope))) {
|
||||
return this.right.drop_side_effect_free(compressor);
|
||||
}
|
||||
return this;
|
||||
});
|
||||
|
||||
def_drop_side_effect_free(AST_Conditional, function (compressor) {
|
||||
var consequent = this.consequent.drop_side_effect_free(compressor);
|
||||
var alternative = this.alternative.drop_side_effect_free(compressor);
|
||||
if (consequent === this.consequent && alternative === this.alternative)
|
||||
return this;
|
||||
if (!consequent)
|
||||
return alternative ? make_node(AST_Binary, this, {
|
||||
operator: "||",
|
||||
left: this.condition,
|
||||
right: alternative
|
||||
}) : this.condition.drop_side_effect_free(compressor);
|
||||
if (!alternative)
|
||||
return make_node(AST_Binary, this, {
|
||||
operator: "&&",
|
||||
left: this.condition,
|
||||
right: consequent
|
||||
});
|
||||
var node = this.clone();
|
||||
node.consequent = consequent;
|
||||
node.alternative = alternative;
|
||||
return node;
|
||||
});
|
||||
|
||||
def_drop_side_effect_free(AST_Unary, function (compressor, first_in_statement) {
|
||||
if (unary_side_effects.has(this.operator)) {
|
||||
if (!this.expression.has_side_effects(compressor)) {
|
||||
set_flag(this, WRITE_ONLY);
|
||||
} else {
|
||||
clear_flag(this, WRITE_ONLY);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
if (this.operator == "typeof" && this.expression instanceof AST_SymbolRef)
|
||||
return null;
|
||||
var expression = this.expression.drop_side_effect_free(compressor, first_in_statement);
|
||||
if (first_in_statement && expression && is_iife_call(expression)) {
|
||||
if (expression === this.expression && this.operator == "!")
|
||||
return this;
|
||||
return expression.negate(compressor, first_in_statement);
|
||||
}
|
||||
return expression;
|
||||
});
|
||||
|
||||
def_drop_side_effect_free(AST_SymbolRef, function (compressor) {
|
||||
const safe_access = this.is_declared(compressor)
|
||||
|| pure_prop_access_globals.has(this.name);
|
||||
return safe_access ? null : this;
|
||||
});
|
||||
|
||||
def_drop_side_effect_free(AST_Object, function (compressor, first_in_statement) {
|
||||
var values = trim(this.properties, compressor, first_in_statement);
|
||||
return values && make_sequence(this, values);
|
||||
});
|
||||
|
||||
def_drop_side_effect_free(AST_ObjectProperty, function (compressor, first_in_statement) {
|
||||
const computed_key = this instanceof AST_ObjectKeyVal && this.key instanceof AST_Node;
|
||||
const key = computed_key && this.key.drop_side_effect_free(compressor, first_in_statement);
|
||||
const value = this.value && this.value.drop_side_effect_free(compressor, first_in_statement);
|
||||
if (key && value) {
|
||||
return make_sequence(this, [key, value]);
|
||||
}
|
||||
return key || value;
|
||||
});
|
||||
|
||||
def_drop_side_effect_free(AST_ConciseMethod, function () {
|
||||
return this.computed_key() ? this.key : null;
|
||||
});
|
||||
|
||||
def_drop_side_effect_free(AST_ObjectGetter, function () {
|
||||
return this.computed_key() ? this.key : null;
|
||||
});
|
||||
|
||||
def_drop_side_effect_free(AST_ObjectSetter, function () {
|
||||
return this.computed_key() ? this.key : null;
|
||||
});
|
||||
|
||||
def_drop_side_effect_free(AST_Array, function (compressor, first_in_statement) {
|
||||
var values = trim(this.elements, compressor, first_in_statement);
|
||||
return values && make_sequence(this, values);
|
||||
});
|
||||
|
||||
def_drop_side_effect_free(AST_Dot, function (compressor, first_in_statement) {
|
||||
if (is_nullish_shortcircuited(this, compressor)) {
|
||||
return this.expression.drop_side_effect_free(compressor, first_in_statement);
|
||||
}
|
||||
if (!this.optional && this.expression.may_throw_on_access(compressor)) {
|
||||
return this;
|
||||
}
|
||||
|
||||
return this.expression.drop_side_effect_free(compressor, first_in_statement);
|
||||
});
|
||||
|
||||
def_drop_side_effect_free(AST_Sub, function (compressor, first_in_statement) {
|
||||
if (is_nullish_shortcircuited(this, compressor)) {
|
||||
return this.expression.drop_side_effect_free(compressor, first_in_statement);
|
||||
}
|
||||
if (!this.optional && this.expression.may_throw_on_access(compressor)) {
|
||||
return this;
|
||||
}
|
||||
|
||||
var property = this.property.drop_side_effect_free(compressor);
|
||||
if (property && this.optional) return this;
|
||||
|
||||
var expression = this.expression.drop_side_effect_free(compressor, first_in_statement);
|
||||
|
||||
if (expression && property) return make_sequence(this, [expression, property]);
|
||||
return expression || property;
|
||||
});
|
||||
|
||||
def_drop_side_effect_free(AST_Chain, function (compressor, first_in_statement) {
|
||||
return this.expression.drop_side_effect_free(compressor, first_in_statement);
|
||||
});
|
||||
|
||||
def_drop_side_effect_free(AST_Sequence, function (compressor) {
|
||||
var last = this.tail_node();
|
||||
var expr = last.drop_side_effect_free(compressor);
|
||||
if (expr === last)
|
||||
return this;
|
||||
var expressions = this.expressions.slice(0, -1);
|
||||
if (expr)
|
||||
expressions.push(expr);
|
||||
if (!expressions.length) {
|
||||
return make_node(AST_Number, this, { value: 0 });
|
||||
}
|
||||
return make_sequence(this, expressions);
|
||||
});
|
||||
|
||||
def_drop_side_effect_free(AST_Expansion, function (compressor, first_in_statement) {
|
||||
return this.expression.drop_side_effect_free(compressor, first_in_statement);
|
||||
});
|
||||
|
||||
def_drop_side_effect_free(AST_TemplateSegment, return_null);
|
||||
|
||||
def_drop_side_effect_free(AST_TemplateString, function (compressor) {
|
||||
var values = trim(this.segments, compressor, first_in_statement);
|
||||
return values && make_sequence(this, values);
|
||||
});
|
482
my-app/node_modules/terser/lib/compress/drop-unused.js
generated
vendored
Executable file
482
my-app/node_modules/terser/lib/compress/drop-unused.js
generated
vendored
Executable file
|
@ -0,0 +1,482 @@
|
|||
/***********************************************************************
|
||||
|
||||
A JavaScript tokenizer / parser / beautifier / compressor.
|
||||
https://github.com/mishoo/UglifyJS2
|
||||
|
||||
-------------------------------- (C) ---------------------------------
|
||||
|
||||
Author: Mihai Bazon
|
||||
<mihai.bazon@gmail.com>
|
||||
http://mihai.bazon.net/blog
|
||||
|
||||
Distributed under the BSD license:
|
||||
|
||||
Copyright 2012 (c) Mihai Bazon <mihai.bazon@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials
|
||||
provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
import {
|
||||
AST_Accessor,
|
||||
AST_Assign,
|
||||
AST_BlockStatement,
|
||||
AST_Class,
|
||||
AST_ClassExpression,
|
||||
AST_ClassStaticBlock,
|
||||
AST_DefaultAssign,
|
||||
AST_DefClass,
|
||||
AST_Definitions,
|
||||
AST_Defun,
|
||||
AST_Destructuring,
|
||||
AST_EmptyStatement,
|
||||
AST_Expansion,
|
||||
AST_Export,
|
||||
AST_For,
|
||||
AST_ForIn,
|
||||
AST_Function,
|
||||
AST_LabeledStatement,
|
||||
AST_Lambda,
|
||||
AST_Number,
|
||||
AST_Scope,
|
||||
AST_SimpleStatement,
|
||||
AST_SymbolBlockDeclaration,
|
||||
AST_SymbolCatch,
|
||||
AST_SymbolDeclaration,
|
||||
AST_SymbolFunarg,
|
||||
AST_SymbolRef,
|
||||
AST_SymbolVar,
|
||||
AST_Toplevel,
|
||||
AST_Unary,
|
||||
AST_Var,
|
||||
|
||||
TreeTransformer,
|
||||
TreeWalker,
|
||||
walk,
|
||||
} from "../ast.js";
|
||||
import {
|
||||
keep_name,
|
||||
make_node,
|
||||
map_add,
|
||||
MAP,
|
||||
remove,
|
||||
return_false,
|
||||
} from "../utils/index.js";
|
||||
import { SymbolDef } from "../scope.js";
|
||||
|
||||
import {
|
||||
WRITE_ONLY,
|
||||
UNUSED,
|
||||
|
||||
has_flag,
|
||||
set_flag,
|
||||
} from "./compressor-flags.js";
|
||||
import {
|
||||
make_sequence,
|
||||
maintain_this_binding,
|
||||
is_empty,
|
||||
is_ref_of,
|
||||
can_be_evicted_from_block,
|
||||
} from "./common.js";
|
||||
|
||||
const r_keep_assign = /keep_assign/;
|
||||
|
||||
/** Drop unused variables from this scope */
|
||||
AST_Scope.DEFMETHOD("drop_unused", function(compressor) {
|
||||
if (!compressor.option("unused")) return;
|
||||
if (compressor.has_directive("use asm")) return;
|
||||
if (!this.variables) return; // not really a scope (eg: AST_Class)
|
||||
|
||||
var self = this;
|
||||
if (self.pinned()) return;
|
||||
var drop_funcs = !(self instanceof AST_Toplevel) || compressor.toplevel.funcs;
|
||||
var drop_vars = !(self instanceof AST_Toplevel) || compressor.toplevel.vars;
|
||||
const assign_as_unused = r_keep_assign.test(compressor.option("unused")) ? return_false : function(node) {
|
||||
if (node instanceof AST_Assign
|
||||
&& !node.logical
|
||||
&& (has_flag(node, WRITE_ONLY) || node.operator == "=")
|
||||
) {
|
||||
return node.left;
|
||||
}
|
||||
if (node instanceof AST_Unary && has_flag(node, WRITE_ONLY)) {
|
||||
return node.expression;
|
||||
}
|
||||
};
|
||||
var in_use_ids = new Map();
|
||||
var fixed_ids = new Map();
|
||||
if (self instanceof AST_Toplevel && compressor.top_retain) {
|
||||
self.variables.forEach(function(def) {
|
||||
if (compressor.top_retain(def)) {
|
||||
in_use_ids.set(def.id, def);
|
||||
}
|
||||
});
|
||||
}
|
||||
var var_defs_by_id = new Map();
|
||||
var initializations = new Map();
|
||||
// pass 1: find out which symbols are directly used in
|
||||
// this scope (not in nested scopes).
|
||||
var scope = this;
|
||||
var tw = new TreeWalker(function(node, descend) {
|
||||
if (node instanceof AST_Lambda && node.uses_arguments && !tw.has_directive("use strict")) {
|
||||
node.argnames.forEach(function(argname) {
|
||||
if (!(argname instanceof AST_SymbolDeclaration)) return;
|
||||
var def = argname.definition();
|
||||
in_use_ids.set(def.id, def);
|
||||
});
|
||||
}
|
||||
if (node === self) return;
|
||||
if (node instanceof AST_Class) {
|
||||
if (node.has_side_effects(compressor)) {
|
||||
node.visit_nondeferred_class_parts(tw);
|
||||
}
|
||||
}
|
||||
if (node instanceof AST_Defun || node instanceof AST_DefClass) {
|
||||
var node_def = node.name.definition();
|
||||
const in_export = tw.parent() instanceof AST_Export;
|
||||
if (in_export || !drop_funcs && scope === self) {
|
||||
if (node_def.global) {
|
||||
in_use_ids.set(node_def.id, node_def);
|
||||
}
|
||||
}
|
||||
|
||||
map_add(initializations, node_def.id, node);
|
||||
return true; // don't go in nested scopes
|
||||
}
|
||||
// In the root scope, we drop things. In inner scopes, we just check for uses.
|
||||
const in_root_scope = scope === self;
|
||||
if (node instanceof AST_SymbolFunarg && in_root_scope) {
|
||||
map_add(var_defs_by_id, node.definition().id, node);
|
||||
}
|
||||
if (node instanceof AST_Definitions && in_root_scope) {
|
||||
const in_export = tw.parent() instanceof AST_Export;
|
||||
node.definitions.forEach(function(def) {
|
||||
if (def.name instanceof AST_SymbolVar) {
|
||||
map_add(var_defs_by_id, def.name.definition().id, def);
|
||||
}
|
||||
if (in_export || !drop_vars) {
|
||||
walk(def.name, node => {
|
||||
if (node instanceof AST_SymbolDeclaration) {
|
||||
const def = node.definition();
|
||||
if (def.global) {
|
||||
in_use_ids.set(def.id, def);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
if (def.name instanceof AST_Destructuring) {
|
||||
def.walk(tw);
|
||||
}
|
||||
if (def.name instanceof AST_SymbolDeclaration && def.value) {
|
||||
var node_def = def.name.definition();
|
||||
map_add(initializations, node_def.id, def.value);
|
||||
if (!node_def.chained && def.name.fixed_value() === def.value) {
|
||||
fixed_ids.set(node_def.id, def);
|
||||
}
|
||||
if (def.value.has_side_effects(compressor)) {
|
||||
def.value.walk(tw);
|
||||
}
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
return scan_ref_scoped(node, descend);
|
||||
});
|
||||
self.walk(tw);
|
||||
// pass 2: for every used symbol we need to walk its
|
||||
// initialization code to figure out if it uses other
|
||||
// symbols (that may not be in_use).
|
||||
tw = new TreeWalker(scan_ref_scoped);
|
||||
in_use_ids.forEach(function (def) {
|
||||
var init = initializations.get(def.id);
|
||||
if (init) init.forEach(function(init) {
|
||||
init.walk(tw);
|
||||
});
|
||||
});
|
||||
// pass 3: we should drop declarations not in_use
|
||||
var tt = new TreeTransformer(
|
||||
function before(node, descend, in_list) {
|
||||
var parent = tt.parent();
|
||||
if (drop_vars) {
|
||||
const sym = assign_as_unused(node);
|
||||
if (sym instanceof AST_SymbolRef) {
|
||||
var def = sym.definition();
|
||||
var in_use = in_use_ids.has(def.id);
|
||||
if (node instanceof AST_Assign) {
|
||||
if (!in_use || fixed_ids.has(def.id) && fixed_ids.get(def.id) !== node) {
|
||||
return maintain_this_binding(parent, node, node.right.transform(tt));
|
||||
}
|
||||
} else if (!in_use) {
|
||||
return in_list ? MAP.skip : make_node(AST_Number, node, { value: 0 });
|
||||
}
|
||||
}
|
||||
}
|
||||
if (scope !== self) return;
|
||||
var def;
|
||||
if (node.name
|
||||
&& (node instanceof AST_ClassExpression
|
||||
&& !keep_name(compressor.option("keep_classnames"), (def = node.name.definition()).name)
|
||||
|| node instanceof AST_Function
|
||||
&& !keep_name(compressor.option("keep_fnames"), (def = node.name.definition()).name))) {
|
||||
// any declarations with same name will overshadow
|
||||
// name of this anonymous function and can therefore
|
||||
// never be used anywhere
|
||||
if (!in_use_ids.has(def.id) || def.orig.length > 1) node.name = null;
|
||||
}
|
||||
if (node instanceof AST_Lambda && !(node instanceof AST_Accessor)) {
|
||||
var trim = !compressor.option("keep_fargs");
|
||||
for (var a = node.argnames, i = a.length; --i >= 0;) {
|
||||
var sym = a[i];
|
||||
if (sym instanceof AST_Expansion) {
|
||||
sym = sym.expression;
|
||||
}
|
||||
if (sym instanceof AST_DefaultAssign) {
|
||||
sym = sym.left;
|
||||
}
|
||||
// Do not drop destructuring arguments.
|
||||
// They constitute a type assertion of sorts
|
||||
if (
|
||||
!(sym instanceof AST_Destructuring)
|
||||
&& !in_use_ids.has(sym.definition().id)
|
||||
) {
|
||||
set_flag(sym, UNUSED);
|
||||
if (trim) {
|
||||
a.pop();
|
||||
}
|
||||
} else {
|
||||
trim = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (node instanceof AST_DefClass && node !== self) {
|
||||
const def = node.name.definition();
|
||||
descend(node, this);
|
||||
const keep_class = def.global && !drop_funcs || in_use_ids.has(def.id);
|
||||
if (!keep_class) {
|
||||
const kept = node.drop_side_effect_free(compressor);
|
||||
if (kept == null) {
|
||||
def.eliminated++;
|
||||
return in_list ? MAP.skip : make_node(AST_EmptyStatement, node);
|
||||
}
|
||||
return kept;
|
||||
}
|
||||
return node;
|
||||
}
|
||||
if (node instanceof AST_Defun && node !== self) {
|
||||
const def = node.name.definition();
|
||||
const keep = def.global && !drop_funcs || in_use_ids.has(def.id);
|
||||
if (!keep) {
|
||||
def.eliminated++;
|
||||
return in_list ? MAP.skip : make_node(AST_EmptyStatement, node);
|
||||
}
|
||||
}
|
||||
if (node instanceof AST_Definitions && !(parent instanceof AST_ForIn && parent.init === node)) {
|
||||
var drop_block = !(parent instanceof AST_Toplevel) && !(node instanceof AST_Var);
|
||||
// place uninitialized names at the start
|
||||
var body = [], head = [], tail = [];
|
||||
// for unused names whose initialization has
|
||||
// side effects, we can cascade the init. code
|
||||
// into the next one, or next statement.
|
||||
var side_effects = [];
|
||||
node.definitions.forEach(function(def) {
|
||||
if (def.value) def.value = def.value.transform(tt);
|
||||
var is_destructure = def.name instanceof AST_Destructuring;
|
||||
var sym = is_destructure
|
||||
? new SymbolDef(null, { name: "<destructure>" }) /* fake SymbolDef */
|
||||
: def.name.definition();
|
||||
if (drop_block && sym.global) return tail.push(def);
|
||||
if (!(drop_vars || drop_block)
|
||||
|| is_destructure
|
||||
&& (def.name.names.length
|
||||
|| def.name.is_array
|
||||
|| compressor.option("pure_getters") != true)
|
||||
|| in_use_ids.has(sym.id)
|
||||
) {
|
||||
if (def.value && fixed_ids.has(sym.id) && fixed_ids.get(sym.id) !== def) {
|
||||
def.value = def.value.drop_side_effect_free(compressor);
|
||||
}
|
||||
if (def.name instanceof AST_SymbolVar) {
|
||||
var var_defs = var_defs_by_id.get(sym.id);
|
||||
if (var_defs.length > 1 && (!def.value || sym.orig.indexOf(def.name) > sym.eliminated)) {
|
||||
if (def.value) {
|
||||
var ref = make_node(AST_SymbolRef, def.name, def.name);
|
||||
sym.references.push(ref);
|
||||
var assign = make_node(AST_Assign, def, {
|
||||
operator: "=",
|
||||
logical: false,
|
||||
left: ref,
|
||||
right: def.value
|
||||
});
|
||||
if (fixed_ids.get(sym.id) === def) {
|
||||
fixed_ids.set(sym.id, assign);
|
||||
}
|
||||
side_effects.push(assign.transform(tt));
|
||||
}
|
||||
remove(var_defs, def);
|
||||
sym.eliminated++;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (def.value) {
|
||||
if (side_effects.length > 0) {
|
||||
if (tail.length > 0) {
|
||||
side_effects.push(def.value);
|
||||
def.value = make_sequence(def.value, side_effects);
|
||||
} else {
|
||||
body.push(make_node(AST_SimpleStatement, node, {
|
||||
body: make_sequence(node, side_effects)
|
||||
}));
|
||||
}
|
||||
side_effects = [];
|
||||
}
|
||||
tail.push(def);
|
||||
} else {
|
||||
head.push(def);
|
||||
}
|
||||
} else if (sym.orig[0] instanceof AST_SymbolCatch) {
|
||||
var value = def.value && def.value.drop_side_effect_free(compressor);
|
||||
if (value) side_effects.push(value);
|
||||
def.value = null;
|
||||
head.push(def);
|
||||
} else {
|
||||
var value = def.value && def.value.drop_side_effect_free(compressor);
|
||||
if (value) {
|
||||
side_effects.push(value);
|
||||
}
|
||||
sym.eliminated++;
|
||||
}
|
||||
});
|
||||
if (head.length > 0 || tail.length > 0) {
|
||||
node.definitions = head.concat(tail);
|
||||
body.push(node);
|
||||
}
|
||||
if (side_effects.length > 0) {
|
||||
body.push(make_node(AST_SimpleStatement, node, {
|
||||
body: make_sequence(node, side_effects)
|
||||
}));
|
||||
}
|
||||
switch (body.length) {
|
||||
case 0:
|
||||
return in_list ? MAP.skip : make_node(AST_EmptyStatement, node);
|
||||
case 1:
|
||||
return body[0];
|
||||
default:
|
||||
return in_list ? MAP.splice(body) : make_node(AST_BlockStatement, node, { body });
|
||||
}
|
||||
}
|
||||
// certain combination of unused name + side effect leads to:
|
||||
// https://github.com/mishoo/UglifyJS2/issues/44
|
||||
// https://github.com/mishoo/UglifyJS2/issues/1830
|
||||
// https://github.com/mishoo/UglifyJS2/issues/1838
|
||||
// that's an invalid AST.
|
||||
// We fix it at this stage by moving the `var` outside the `for`.
|
||||
if (node instanceof AST_For) {
|
||||
descend(node, this);
|
||||
var block;
|
||||
if (node.init instanceof AST_BlockStatement) {
|
||||
block = node.init;
|
||||
node.init = block.body.pop();
|
||||
block.body.push(node);
|
||||
}
|
||||
if (node.init instanceof AST_SimpleStatement) {
|
||||
node.init = node.init.body;
|
||||
} else if (is_empty(node.init)) {
|
||||
node.init = null;
|
||||
}
|
||||
return !block ? node : in_list ? MAP.splice(block.body) : block;
|
||||
}
|
||||
if (node instanceof AST_LabeledStatement
|
||||
&& node.body instanceof AST_For
|
||||
) {
|
||||
descend(node, this);
|
||||
if (node.body instanceof AST_BlockStatement) {
|
||||
var block = node.body;
|
||||
node.body = block.body.pop();
|
||||
block.body.push(node);
|
||||
return in_list ? MAP.splice(block.body) : block;
|
||||
}
|
||||
return node;
|
||||
}
|
||||
if (node instanceof AST_BlockStatement) {
|
||||
descend(node, this);
|
||||
if (in_list && node.body.every(can_be_evicted_from_block)) {
|
||||
return MAP.splice(node.body);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
if (node instanceof AST_Scope && !(node instanceof AST_ClassStaticBlock)) {
|
||||
const save_scope = scope;
|
||||
scope = node;
|
||||
descend(node, this);
|
||||
scope = save_scope;
|
||||
return node;
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
self.transform(tt);
|
||||
|
||||
function scan_ref_scoped(node, descend) {
|
||||
var node_def;
|
||||
const sym = assign_as_unused(node);
|
||||
if (sym instanceof AST_SymbolRef
|
||||
&& !is_ref_of(node.left, AST_SymbolBlockDeclaration)
|
||||
&& self.variables.get(sym.name) === (node_def = sym.definition())
|
||||
) {
|
||||
if (node instanceof AST_Assign) {
|
||||
node.right.walk(tw);
|
||||
if (!node_def.chained && node.left.fixed_value() === node.right) {
|
||||
fixed_ids.set(node_def.id, node);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (node instanceof AST_SymbolRef) {
|
||||
node_def = node.definition();
|
||||
if (!in_use_ids.has(node_def.id)) {
|
||||
in_use_ids.set(node_def.id, node_def);
|
||||
if (node_def.orig[0] instanceof AST_SymbolCatch) {
|
||||
const redef = node_def.scope.is_block_scope()
|
||||
&& node_def.scope.get_defun_scope().variables.get(node_def.name);
|
||||
if (redef) in_use_ids.set(redef.id, redef);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (node instanceof AST_Class) {
|
||||
descend();
|
||||
return true;
|
||||
}
|
||||
if (node instanceof AST_Scope && !(node instanceof AST_ClassStaticBlock)) {
|
||||
var save_scope = scope;
|
||||
scope = node;
|
||||
descend();
|
||||
scope = save_scope;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
488
my-app/node_modules/terser/lib/compress/evaluate.js
generated
vendored
Executable file
488
my-app/node_modules/terser/lib/compress/evaluate.js
generated
vendored
Executable file
|
@ -0,0 +1,488 @@
|
|||
/***********************************************************************
|
||||
|
||||
A JavaScript tokenizer / parser / beautifier / compressor.
|
||||
https://github.com/mishoo/UglifyJS2
|
||||
|
||||
-------------------------------- (C) ---------------------------------
|
||||
|
||||
Author: Mihai Bazon
|
||||
<mihai.bazon@gmail.com>
|
||||
http://mihai.bazon.net/blog
|
||||
|
||||
Distributed under the BSD license:
|
||||
|
||||
Copyright 2012 (c) Mihai Bazon <mihai.bazon@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials
|
||||
provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
import {
|
||||
HOP,
|
||||
makePredicate,
|
||||
return_this,
|
||||
string_template,
|
||||
regexp_source_fix,
|
||||
regexp_is_safe,
|
||||
} from "../utils/index.js";
|
||||
import {
|
||||
AST_Array,
|
||||
AST_BigInt,
|
||||
AST_Binary,
|
||||
AST_Call,
|
||||
AST_Chain,
|
||||
AST_Class,
|
||||
AST_Conditional,
|
||||
AST_Constant,
|
||||
AST_Dot,
|
||||
AST_Expansion,
|
||||
AST_Function,
|
||||
AST_Lambda,
|
||||
AST_New,
|
||||
AST_Node,
|
||||
AST_Object,
|
||||
AST_PropAccess,
|
||||
AST_RegExp,
|
||||
AST_Statement,
|
||||
AST_Symbol,
|
||||
AST_SymbolRef,
|
||||
AST_TemplateString,
|
||||
AST_UnaryPrefix,
|
||||
AST_With,
|
||||
} from "../ast.js";
|
||||
import { is_undeclared_ref} from "./inference.js";
|
||||
import { is_pure_native_value, is_pure_native_fn, is_pure_native_method } from "./native-objects.js";
|
||||
|
||||
// methods to evaluate a constant expression
|
||||
|
||||
function def_eval(node, func) {
|
||||
node.DEFMETHOD("_eval", func);
|
||||
}
|
||||
|
||||
// Used to propagate a nullish short-circuit signal upwards through the chain.
|
||||
export const nullish = Symbol("This AST_Chain is nullish");
|
||||
|
||||
// If the node has been successfully reduced to a constant,
|
||||
// then its value is returned; otherwise the element itself
|
||||
// is returned.
|
||||
// They can be distinguished as constant value is never a
|
||||
// descendant of AST_Node.
|
||||
AST_Node.DEFMETHOD("evaluate", function (compressor) {
|
||||
if (!compressor.option("evaluate"))
|
||||
return this;
|
||||
var val = this._eval(compressor, 1);
|
||||
if (!val || val instanceof RegExp)
|
||||
return val;
|
||||
if (typeof val == "function" || typeof val == "object" || val == nullish)
|
||||
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;
|
||||
});
|
||||
|
||||
var unaryPrefix = makePredicate("! ~ - + void");
|
||||
AST_Node.DEFMETHOD("is_constant", function () {
|
||||
// Accomodate when compress option evaluate=false
|
||||
// as well as the common constant expressions !0 and -1
|
||||
if (this instanceof AST_Constant) {
|
||||
return !(this instanceof AST_RegExp);
|
||||
} else {
|
||||
return this instanceof AST_UnaryPrefix
|
||||
&& this.expression instanceof AST_Constant
|
||||
&& unaryPrefix.has(this.operator);
|
||||
}
|
||||
});
|
||||
|
||||
def_eval(AST_Statement, function () {
|
||||
throw new Error(string_template("Cannot evaluate a statement [{file}:{line},{col}]", this.start));
|
||||
});
|
||||
|
||||
def_eval(AST_Lambda, return_this);
|
||||
def_eval(AST_Class, return_this);
|
||||
def_eval(AST_Node, return_this);
|
||||
def_eval(AST_Constant, function () {
|
||||
return this.getValue();
|
||||
});
|
||||
|
||||
def_eval(AST_BigInt, return_this);
|
||||
|
||||
def_eval(AST_RegExp, function (compressor) {
|
||||
let evaluated = compressor.evaluated_regexps.get(this.value);
|
||||
if (evaluated === undefined && regexp_is_safe(this.value.source)) {
|
||||
try {
|
||||
const { source, flags } = this.value;
|
||||
evaluated = new RegExp(source, flags);
|
||||
} catch (e) {
|
||||
evaluated = null;
|
||||
}
|
||||
compressor.evaluated_regexps.set(this.value, evaluated);
|
||||
}
|
||||
return evaluated || this;
|
||||
});
|
||||
|
||||
def_eval(AST_TemplateString, function () {
|
||||
if (this.segments.length !== 1) return this;
|
||||
return this.segments[0].value;
|
||||
});
|
||||
|
||||
def_eval(AST_Function, function (compressor) {
|
||||
if (compressor.option("unsafe")) {
|
||||
var fn = function () { };
|
||||
fn.node = this;
|
||||
fn.toString = () => this.print_to_string();
|
||||
return fn;
|
||||
}
|
||||
return this;
|
||||
});
|
||||
|
||||
def_eval(AST_Array, function (compressor, depth) {
|
||||
if (compressor.option("unsafe")) {
|
||||
var elements = [];
|
||||
for (var i = 0, len = this.elements.length; i < len; i++) {
|
||||
var element = this.elements[i];
|
||||
var value = element._eval(compressor, depth);
|
||||
if (element === value)
|
||||
return this;
|
||||
elements.push(value);
|
||||
}
|
||||
return elements;
|
||||
}
|
||||
return this;
|
||||
});
|
||||
|
||||
def_eval(AST_Object, function (compressor, depth) {
|
||||
if (compressor.option("unsafe")) {
|
||||
var val = {};
|
||||
for (var i = 0, len = this.properties.length; i < len; i++) {
|
||||
var prop = this.properties[i];
|
||||
if (prop instanceof AST_Expansion)
|
||||
return this;
|
||||
var key = prop.key;
|
||||
if (key instanceof AST_Symbol) {
|
||||
key = key.name;
|
||||
} else if (key instanceof AST_Node) {
|
||||
key = key._eval(compressor, depth);
|
||||
if (key === prop.key)
|
||||
return this;
|
||||
}
|
||||
if (typeof Object.prototype[key] === "function") {
|
||||
return this;
|
||||
}
|
||||
if (prop.value instanceof AST_Function)
|
||||
continue;
|
||||
val[key] = prop.value._eval(compressor, depth);
|
||||
if (val[key] === prop.value)
|
||||
return this;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
return this;
|
||||
});
|
||||
|
||||
var non_converting_unary = makePredicate("! typeof void");
|
||||
def_eval(AST_UnaryPrefix, function (compressor, depth) {
|
||||
var e = this.expression;
|
||||
// Function would be evaluated to an array and so typeof would
|
||||
// incorrectly return 'object'. Hence making is a special case.
|
||||
if (compressor.option("typeofs")
|
||||
&& this.operator == "typeof"
|
||||
&& (e instanceof AST_Lambda
|
||||
|| e instanceof AST_SymbolRef
|
||||
&& e.fixed_value() instanceof AST_Lambda)) {
|
||||
return typeof function () { };
|
||||
}
|
||||
if (!non_converting_unary.has(this.operator))
|
||||
depth++;
|
||||
e = e._eval(compressor, depth);
|
||||
if (e === this.expression)
|
||||
return this;
|
||||
switch (this.operator) {
|
||||
case "!": return !e;
|
||||
case "typeof":
|
||||
// typeof <RegExp> returns "object" or "function" on different platforms
|
||||
// so cannot evaluate reliably
|
||||
if (e instanceof RegExp)
|
||||
return this;
|
||||
return typeof e;
|
||||
case "void": return void e;
|
||||
case "~": return ~e;
|
||||
case "-": return -e;
|
||||
case "+": return +e;
|
||||
}
|
||||
return this;
|
||||
});
|
||||
|
||||
var non_converting_binary = makePredicate("&& || ?? === !==");
|
||||
const identity_comparison = makePredicate("== != === !==");
|
||||
const has_identity = value => typeof value === "object"
|
||||
|| typeof value === "function"
|
||||
|| typeof value === "symbol";
|
||||
|
||||
def_eval(AST_Binary, function (compressor, depth) {
|
||||
if (!non_converting_binary.has(this.operator))
|
||||
depth++;
|
||||
|
||||
var left = this.left._eval(compressor, depth);
|
||||
if (left === this.left)
|
||||
return this;
|
||||
var right = this.right._eval(compressor, depth);
|
||||
if (right === this.right)
|
||||
return this;
|
||||
var result;
|
||||
|
||||
if (left != null
|
||||
&& right != null
|
||||
&& identity_comparison.has(this.operator)
|
||||
&& has_identity(left)
|
||||
&& has_identity(right)
|
||||
&& typeof left === typeof right) {
|
||||
// Do not compare by reference
|
||||
return this;
|
||||
}
|
||||
|
||||
switch (this.operator) {
|
||||
case "&&": result = left && right; break;
|
||||
case "||": result = left || right; break;
|
||||
case "??": result = left != null ? left : right; break;
|
||||
case "|": result = left | right; break;
|
||||
case "&": result = left & right; break;
|
||||
case "^": result = left ^ right; break;
|
||||
case "+": result = left + right; break;
|
||||
case "*": result = left * right; break;
|
||||
case "**": result = Math.pow(left, right); break;
|
||||
case "/": result = left / right; break;
|
||||
case "%": result = left % right; break;
|
||||
case "-": result = left - right; break;
|
||||
case "<<": result = left << right; break;
|
||||
case ">>": result = left >> right; break;
|
||||
case ">>>": result = left >>> right; break;
|
||||
case "==": result = left == right; break;
|
||||
case "===": result = left === right; break;
|
||||
case "!=": result = left != right; break;
|
||||
case "!==": result = left !== right; break;
|
||||
case "<": result = left < right; break;
|
||||
case "<=": result = left <= right; break;
|
||||
case ">": result = left > right; break;
|
||||
case ">=": result = left >= right; break;
|
||||
default:
|
||||
return this;
|
||||
}
|
||||
if (isNaN(result) && compressor.find_parent(AST_With)) {
|
||||
// leave original expression as is
|
||||
return this;
|
||||
}
|
||||
return result;
|
||||
});
|
||||
|
||||
def_eval(AST_Conditional, function (compressor, depth) {
|
||||
var condition = this.condition._eval(compressor, depth);
|
||||
if (condition === this.condition)
|
||||
return this;
|
||||
var node = condition ? this.consequent : this.alternative;
|
||||
var value = node._eval(compressor, depth);
|
||||
return value === node ? this : value;
|
||||
});
|
||||
|
||||
// Set of AST_SymbolRef which are currently being evaluated.
|
||||
// Avoids infinite recursion of ._eval()
|
||||
const reentrant_ref_eval = new Set();
|
||||
def_eval(AST_SymbolRef, function (compressor, depth) {
|
||||
if (reentrant_ref_eval.has(this))
|
||||
return this;
|
||||
|
||||
var fixed = this.fixed_value();
|
||||
if (!fixed)
|
||||
return this;
|
||||
|
||||
reentrant_ref_eval.add(this);
|
||||
const value = fixed._eval(compressor, depth);
|
||||
reentrant_ref_eval.delete(this);
|
||||
|
||||
if (value === fixed)
|
||||
return this;
|
||||
|
||||
if (value && typeof value == "object") {
|
||||
var escaped = this.definition().escaped;
|
||||
if (escaped && depth > escaped)
|
||||
return this;
|
||||
}
|
||||
return value;
|
||||
});
|
||||
|
||||
const global_objs = { Array, Math, Number, Object, String };
|
||||
|
||||
const regexp_flags = new Set([
|
||||
"dotAll",
|
||||
"global",
|
||||
"ignoreCase",
|
||||
"multiline",
|
||||
"sticky",
|
||||
"unicode",
|
||||
]);
|
||||
|
||||
def_eval(AST_PropAccess, function (compressor, depth) {
|
||||
let obj = this.expression._eval(compressor, depth + 1);
|
||||
if (obj === nullish || (this.optional && obj == null)) return nullish;
|
||||
|
||||
// `.length` of strings and arrays is always safe
|
||||
if (this.property === "length") {
|
||||
if (typeof obj === "string") {
|
||||
return obj.length;
|
||||
}
|
||||
|
||||
const is_spreadless_array =
|
||||
obj instanceof AST_Array
|
||||
&& obj.elements.every(el => !(el instanceof AST_Expansion));
|
||||
|
||||
if (
|
||||
is_spreadless_array
|
||||
&& obj.elements.every(el => !el.has_side_effects(compressor))
|
||||
) {
|
||||
return obj.elements.length;
|
||||
}
|
||||
}
|
||||
|
||||
if (compressor.option("unsafe")) {
|
||||
var key = this.property;
|
||||
if (key instanceof AST_Node) {
|
||||
key = key._eval(compressor, depth);
|
||||
if (key === this.property)
|
||||
return this;
|
||||
}
|
||||
|
||||
var exp = this.expression;
|
||||
if (is_undeclared_ref(exp)) {
|
||||
var aa;
|
||||
var first_arg = exp.name === "hasOwnProperty"
|
||||
&& key === "call"
|
||||
&& (aa = compressor.parent() && compressor.parent().args)
|
||||
&& (aa && aa[0]
|
||||
&& aa[0].evaluate(compressor));
|
||||
|
||||
first_arg = first_arg instanceof AST_Dot ? first_arg.expression : first_arg;
|
||||
|
||||
if (first_arg == null || first_arg.thedef && first_arg.thedef.undeclared) {
|
||||
return this.clone();
|
||||
}
|
||||
if (!is_pure_native_value(exp.name, key))
|
||||
return this;
|
||||
obj = global_objs[exp.name];
|
||||
} else {
|
||||
if (obj instanceof RegExp) {
|
||||
if (key == "source") {
|
||||
return regexp_source_fix(obj.source);
|
||||
} else if (key == "flags" || regexp_flags.has(key)) {
|
||||
return obj[key];
|
||||
}
|
||||
}
|
||||
if (!obj || obj === exp || !HOP(obj, key))
|
||||
return this;
|
||||
|
||||
if (typeof obj == "function")
|
||||
switch (key) {
|
||||
case "name":
|
||||
return obj.node.name ? obj.node.name.name : "";
|
||||
case "length":
|
||||
return obj.node.length_property();
|
||||
default:
|
||||
return this;
|
||||
}
|
||||
}
|
||||
return obj[key];
|
||||
}
|
||||
return this;
|
||||
});
|
||||
|
||||
def_eval(AST_Chain, function (compressor, depth) {
|
||||
const evaluated = this.expression._eval(compressor, depth);
|
||||
return evaluated === nullish
|
||||
? undefined
|
||||
: evaluated === this.expression
|
||||
? this
|
||||
: evaluated;
|
||||
});
|
||||
|
||||
def_eval(AST_Call, function (compressor, depth) {
|
||||
var exp = this.expression;
|
||||
|
||||
const callee = exp._eval(compressor, depth);
|
||||
if (callee === nullish || (this.optional && callee == null)) return nullish;
|
||||
|
||||
if (compressor.option("unsafe") && exp instanceof AST_PropAccess) {
|
||||
var key = exp.property;
|
||||
if (key instanceof AST_Node) {
|
||||
key = key._eval(compressor, depth);
|
||||
if (key === exp.property)
|
||||
return this;
|
||||
}
|
||||
var val;
|
||||
var e = exp.expression;
|
||||
if (is_undeclared_ref(e)) {
|
||||
var first_arg = e.name === "hasOwnProperty" &&
|
||||
key === "call" &&
|
||||
(this.args[0] && this.args[0].evaluate(compressor));
|
||||
|
||||
first_arg = first_arg instanceof AST_Dot ? first_arg.expression : first_arg;
|
||||
|
||||
if ((first_arg == null || first_arg.thedef && first_arg.thedef.undeclared)) {
|
||||
return this.clone();
|
||||
}
|
||||
if (!is_pure_native_fn(e.name, key)) return this;
|
||||
val = global_objs[e.name];
|
||||
} else {
|
||||
val = e._eval(compressor, depth + 1);
|
||||
if (val === e || !val)
|
||||
return this;
|
||||
if (!is_pure_native_method(val.constructor.name, key))
|
||||
return this;
|
||||
}
|
||||
var args = [];
|
||||
for (var i = 0, len = this.args.length; i < len; i++) {
|
||||
var arg = this.args[i];
|
||||
var value = arg._eval(compressor, depth);
|
||||
if (arg === value)
|
||||
return this;
|
||||
if (arg instanceof AST_Lambda)
|
||||
return this;
|
||||
args.push(value);
|
||||
}
|
||||
try {
|
||||
return val[key].apply(val, args);
|
||||
} catch (ex) {
|
||||
// We don't really care
|
||||
}
|
||||
}
|
||||
return this;
|
||||
});
|
||||
|
||||
// Also a subclass of AST_Call
|
||||
def_eval(AST_New, return_this);
|
92
my-app/node_modules/terser/lib/compress/global-defs.js
generated
vendored
Executable file
92
my-app/node_modules/terser/lib/compress/global-defs.js
generated
vendored
Executable file
|
@ -0,0 +1,92 @@
|
|||
import {
|
||||
AST_Array,
|
||||
AST_Chain,
|
||||
AST_Constant,
|
||||
AST_Dot,
|
||||
AST_ImportMeta,
|
||||
AST_Node,
|
||||
AST_Object,
|
||||
AST_ObjectKeyVal,
|
||||
AST_PropAccess,
|
||||
AST_SymbolDeclaration,
|
||||
AST_SymbolRef,
|
||||
AST_Toplevel,
|
||||
TreeTransformer,
|
||||
} from "../ast.js";
|
||||
import { make_node, noop, HOP } from "../utils/index.js";
|
||||
import { make_node_from_constant } from "./common.js";
|
||||
import { is_lhs } from "./inference.js";
|
||||
|
||||
(function(def_find_defs) {
|
||||
function to_node(value, orig) {
|
||||
if (value instanceof AST_Node) {
|
||||
if (!(value instanceof AST_Constant)) {
|
||||
// Value may be a function, an array including functions and even a complex assign / block expression,
|
||||
// so it should never be shared in different places.
|
||||
// Otherwise wrong information may be used in the compression phase
|
||||
value = value.clone(true);
|
||||
}
|
||||
return make_node(value.CTOR, orig, value);
|
||||
}
|
||||
if (Array.isArray(value)) return make_node(AST_Array, orig, {
|
||||
elements: value.map(function(value) {
|
||||
return to_node(value, orig);
|
||||
})
|
||||
});
|
||||
if (value && typeof value == "object") {
|
||||
var props = [];
|
||||
for (var key in value) if (HOP(value, key)) {
|
||||
props.push(make_node(AST_ObjectKeyVal, orig, {
|
||||
key: key,
|
||||
value: to_node(value[key], orig)
|
||||
}));
|
||||
}
|
||||
return make_node(AST_Object, orig, {
|
||||
properties: props
|
||||
});
|
||||
}
|
||||
return make_node_from_constant(value, orig);
|
||||
}
|
||||
|
||||
AST_Toplevel.DEFMETHOD("resolve_defines", function(compressor) {
|
||||
if (!compressor.option("global_defs")) return this;
|
||||
this.figure_out_scope({ ie8: compressor.option("ie8") });
|
||||
return this.transform(new TreeTransformer(function(node) {
|
||||
var def = node._find_defs(compressor, "");
|
||||
if (!def) return;
|
||||
var level = 0, child = node, parent;
|
||||
while (parent = this.parent(level++)) {
|
||||
if (!(parent instanceof AST_PropAccess)) break;
|
||||
if (parent.expression !== child) break;
|
||||
child = parent;
|
||||
}
|
||||
if (is_lhs(child, parent)) {
|
||||
return;
|
||||
}
|
||||
return def;
|
||||
}));
|
||||
});
|
||||
def_find_defs(AST_Node, noop);
|
||||
def_find_defs(AST_Chain, function(compressor, suffix) {
|
||||
return this.expression._find_defs(compressor, suffix);
|
||||
});
|
||||
def_find_defs(AST_Dot, function(compressor, suffix) {
|
||||
return this.expression._find_defs(compressor, "." + this.property + suffix);
|
||||
});
|
||||
def_find_defs(AST_SymbolDeclaration, function() {
|
||||
if (!this.global()) return;
|
||||
});
|
||||
def_find_defs(AST_SymbolRef, function(compressor, suffix) {
|
||||
if (!this.global()) return;
|
||||
var defines = compressor.option("global_defs");
|
||||
var name = this.name + suffix;
|
||||
if (HOP(defines, name)) return to_node(defines[name], this);
|
||||
});
|
||||
def_find_defs(AST_ImportMeta, function(compressor, suffix) {
|
||||
var defines = compressor.option("global_defs");
|
||||
var name = "import.meta" + suffix;
|
||||
if (HOP(defines, name)) return to_node(defines[name], this);
|
||||
});
|
||||
})(function(node, func) {
|
||||
node.DEFMETHOD("_find_defs", func);
|
||||
});
|
3795
my-app/node_modules/terser/lib/compress/index.js
generated
vendored
Executable file
3795
my-app/node_modules/terser/lib/compress/index.js
generated
vendored
Executable file
File diff suppressed because it is too large
Load diff
934
my-app/node_modules/terser/lib/compress/inference.js
generated
vendored
Executable file
934
my-app/node_modules/terser/lib/compress/inference.js
generated
vendored
Executable file
|
@ -0,0 +1,934 @@
|
|||
/***********************************************************************
|
||||
|
||||
A JavaScript tokenizer / parser / beautifier / compressor.
|
||||
https://github.com/mishoo/UglifyJS2
|
||||
|
||||
-------------------------------- (C) ---------------------------------
|
||||
|
||||
Author: Mihai Bazon
|
||||
<mihai.bazon@gmail.com>
|
||||
http://mihai.bazon.net/blog
|
||||
|
||||
Distributed under the BSD license:
|
||||
|
||||
Copyright 2012 (c) Mihai Bazon <mihai.bazon@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials
|
||||
provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
import {
|
||||
AST_Array,
|
||||
AST_Arrow,
|
||||
AST_Assign,
|
||||
AST_BigInt,
|
||||
AST_Binary,
|
||||
AST_Block,
|
||||
AST_BlockStatement,
|
||||
AST_Call,
|
||||
AST_Case,
|
||||
AST_Chain,
|
||||
AST_Class,
|
||||
AST_DefClass,
|
||||
AST_ClassStaticBlock,
|
||||
AST_ClassProperty,
|
||||
AST_ConciseMethod,
|
||||
AST_Conditional,
|
||||
AST_Constant,
|
||||
AST_Definitions,
|
||||
AST_Dot,
|
||||
AST_EmptyStatement,
|
||||
AST_Expansion,
|
||||
AST_False,
|
||||
AST_ForIn,
|
||||
AST_Function,
|
||||
AST_If,
|
||||
AST_Import,
|
||||
AST_ImportMeta,
|
||||
AST_Jump,
|
||||
AST_LabeledStatement,
|
||||
AST_Lambda,
|
||||
AST_New,
|
||||
AST_Node,
|
||||
AST_Null,
|
||||
AST_Number,
|
||||
AST_Object,
|
||||
AST_ObjectGetter,
|
||||
AST_ObjectKeyVal,
|
||||
AST_ObjectProperty,
|
||||
AST_ObjectSetter,
|
||||
AST_PropAccess,
|
||||
AST_RegExp,
|
||||
AST_Return,
|
||||
AST_Scope,
|
||||
AST_Sequence,
|
||||
AST_SimpleStatement,
|
||||
AST_Statement,
|
||||
AST_String,
|
||||
AST_Sub,
|
||||
AST_Switch,
|
||||
AST_SwitchBranch,
|
||||
AST_SymbolClassProperty,
|
||||
AST_SymbolDeclaration,
|
||||
AST_SymbolRef,
|
||||
AST_TemplateSegment,
|
||||
AST_TemplateString,
|
||||
AST_This,
|
||||
AST_True,
|
||||
AST_Try,
|
||||
AST_Unary,
|
||||
AST_UnaryPostfix,
|
||||
AST_UnaryPrefix,
|
||||
AST_Undefined,
|
||||
AST_VarDef,
|
||||
|
||||
walk,
|
||||
walk_abort,
|
||||
|
||||
_PURE
|
||||
} from "../ast.js";
|
||||
import {
|
||||
makePredicate,
|
||||
return_true,
|
||||
return_false,
|
||||
return_null,
|
||||
return_this,
|
||||
make_node,
|
||||
member,
|
||||
has_annotation,
|
||||
} from "../utils/index.js";
|
||||
import { make_sequence, best_of_expression, read_property } from "./common.js";
|
||||
|
||||
import { INLINED, UNDEFINED, has_flag } from "./compressor-flags.js";
|
||||
import { pure_prop_access_globals, is_pure_native_fn, is_pure_native_method } from "./native-objects.js";
|
||||
|
||||
// Functions and methods to infer certain facts about expressions
|
||||
// It's not always possible to be 100% sure about something just by static analysis,
|
||||
// so `true` means yes, and `false` means maybe
|
||||
|
||||
export const is_undeclared_ref = (node) =>
|
||||
node instanceof AST_SymbolRef && node.definition().undeclared;
|
||||
|
||||
export const lazy_op = makePredicate("&& || ??");
|
||||
export const unary_side_effects = makePredicate("delete ++ --");
|
||||
|
||||
// methods to determine whether an expression has a boolean result type
|
||||
(function(def_is_boolean) {
|
||||
const unary_bool = makePredicate("! delete");
|
||||
const binary_bool = makePredicate("in instanceof == != === !== < <= >= >");
|
||||
def_is_boolean(AST_Node, return_false);
|
||||
def_is_boolean(AST_UnaryPrefix, function() {
|
||||
return unary_bool.has(this.operator);
|
||||
});
|
||||
def_is_boolean(AST_Binary, function() {
|
||||
return binary_bool.has(this.operator)
|
||||
|| lazy_op.has(this.operator)
|
||||
&& this.left.is_boolean()
|
||||
&& this.right.is_boolean();
|
||||
});
|
||||
def_is_boolean(AST_Conditional, function() {
|
||||
return this.consequent.is_boolean() && this.alternative.is_boolean();
|
||||
});
|
||||
def_is_boolean(AST_Assign, function() {
|
||||
return this.operator == "=" && this.right.is_boolean();
|
||||
});
|
||||
def_is_boolean(AST_Sequence, function() {
|
||||
return this.tail_node().is_boolean();
|
||||
});
|
||||
def_is_boolean(AST_True, return_true);
|
||||
def_is_boolean(AST_False, return_true);
|
||||
})(function(node, func) {
|
||||
node.DEFMETHOD("is_boolean", func);
|
||||
});
|
||||
|
||||
// methods to determine if an expression has a numeric result type
|
||||
(function(def_is_number) {
|
||||
def_is_number(AST_Node, return_false);
|
||||
def_is_number(AST_Number, return_true);
|
||||
const unary = makePredicate("+ - ~ ++ --");
|
||||
def_is_number(AST_Unary, function() {
|
||||
return unary.has(this.operator) && !(this.expression instanceof AST_BigInt);
|
||||
});
|
||||
const numeric_ops = makePredicate("- * / % & | ^ << >> >>>");
|
||||
def_is_number(AST_Binary, function(compressor) {
|
||||
return numeric_ops.has(this.operator) || this.operator == "+"
|
||||
&& this.left.is_number(compressor)
|
||||
&& this.right.is_number(compressor);
|
||||
});
|
||||
def_is_number(AST_Assign, function(compressor) {
|
||||
return numeric_ops.has(this.operator.slice(0, -1))
|
||||
|| this.operator == "=" && this.right.is_number(compressor);
|
||||
});
|
||||
def_is_number(AST_Sequence, function(compressor) {
|
||||
return this.tail_node().is_number(compressor);
|
||||
});
|
||||
def_is_number(AST_Conditional, function(compressor) {
|
||||
return this.consequent.is_number(compressor) && this.alternative.is_number(compressor);
|
||||
});
|
||||
})(function(node, func) {
|
||||
node.DEFMETHOD("is_number", func);
|
||||
});
|
||||
|
||||
// methods to determine if an expression has a string result type
|
||||
(function(def_is_string) {
|
||||
def_is_string(AST_Node, return_false);
|
||||
def_is_string(AST_String, return_true);
|
||||
def_is_string(AST_TemplateString, return_true);
|
||||
def_is_string(AST_UnaryPrefix, function() {
|
||||
return this.operator == "typeof";
|
||||
});
|
||||
def_is_string(AST_Binary, function(compressor) {
|
||||
return this.operator == "+" &&
|
||||
(this.left.is_string(compressor) || this.right.is_string(compressor));
|
||||
});
|
||||
def_is_string(AST_Assign, function(compressor) {
|
||||
return (this.operator == "=" || this.operator == "+=") && this.right.is_string(compressor);
|
||||
});
|
||||
def_is_string(AST_Sequence, function(compressor) {
|
||||
return this.tail_node().is_string(compressor);
|
||||
});
|
||||
def_is_string(AST_Conditional, function(compressor) {
|
||||
return this.consequent.is_string(compressor) && this.alternative.is_string(compressor);
|
||||
});
|
||||
})(function(node, func) {
|
||||
node.DEFMETHOD("is_string", func);
|
||||
});
|
||||
|
||||
export function is_undefined(node, compressor) {
|
||||
return (
|
||||
has_flag(node, UNDEFINED)
|
||||
|| node instanceof AST_Undefined
|
||||
|| node instanceof AST_UnaryPrefix
|
||||
&& node.operator == "void"
|
||||
&& !node.expression.has_side_effects(compressor)
|
||||
);
|
||||
}
|
||||
|
||||
// Is the node explicitly null or undefined.
|
||||
function is_null_or_undefined(node, compressor) {
|
||||
let fixed;
|
||||
return (
|
||||
node instanceof AST_Null
|
||||
|| is_undefined(node, compressor)
|
||||
|| (
|
||||
node instanceof AST_SymbolRef
|
||||
&& (fixed = node.definition().fixed) instanceof AST_Node
|
||||
&& is_nullish(fixed, compressor)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// Find out if this expression is optionally chained from a base-point that we
|
||||
// can statically analyze as null or undefined.
|
||||
export function is_nullish_shortcircuited(node, compressor) {
|
||||
if (node instanceof AST_PropAccess || node instanceof AST_Call) {
|
||||
return (
|
||||
(node.optional && is_null_or_undefined(node.expression, compressor))
|
||||
|| is_nullish_shortcircuited(node.expression, compressor)
|
||||
);
|
||||
}
|
||||
if (node instanceof AST_Chain) return is_nullish_shortcircuited(node.expression, compressor);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Find out if something is == null, or can short circuit into nullish.
|
||||
// Used to optimize ?. and ??
|
||||
export function is_nullish(node, compressor) {
|
||||
if (is_null_or_undefined(node, compressor)) return true;
|
||||
return is_nullish_shortcircuited(node, compressor);
|
||||
}
|
||||
|
||||
// Determine if expression might cause side effects
|
||||
// If there's a possibility that a node may change something when it's executed, this returns true
|
||||
(function(def_has_side_effects) {
|
||||
def_has_side_effects(AST_Node, return_true);
|
||||
|
||||
def_has_side_effects(AST_EmptyStatement, return_false);
|
||||
def_has_side_effects(AST_Constant, return_false);
|
||||
def_has_side_effects(AST_This, return_false);
|
||||
|
||||
function any(list, compressor) {
|
||||
for (var i = list.length; --i >= 0;)
|
||||
if (list[i].has_side_effects(compressor))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
def_has_side_effects(AST_Block, function(compressor) {
|
||||
return any(this.body, compressor);
|
||||
});
|
||||
def_has_side_effects(AST_Call, function(compressor) {
|
||||
if (
|
||||
!this.is_callee_pure(compressor)
|
||||
&& (!this.expression.is_call_pure(compressor)
|
||||
|| this.expression.has_side_effects(compressor))
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
return any(this.args, compressor);
|
||||
});
|
||||
def_has_side_effects(AST_Switch, function(compressor) {
|
||||
return this.expression.has_side_effects(compressor)
|
||||
|| any(this.body, compressor);
|
||||
});
|
||||
def_has_side_effects(AST_Case, function(compressor) {
|
||||
return this.expression.has_side_effects(compressor)
|
||||
|| any(this.body, compressor);
|
||||
});
|
||||
def_has_side_effects(AST_Try, function(compressor) {
|
||||
return this.body.has_side_effects(compressor)
|
||||
|| this.bcatch && this.bcatch.has_side_effects(compressor)
|
||||
|| this.bfinally && this.bfinally.has_side_effects(compressor);
|
||||
});
|
||||
def_has_side_effects(AST_If, function(compressor) {
|
||||
return this.condition.has_side_effects(compressor)
|
||||
|| this.body && this.body.has_side_effects(compressor)
|
||||
|| this.alternative && this.alternative.has_side_effects(compressor);
|
||||
});
|
||||
def_has_side_effects(AST_ImportMeta, return_false);
|
||||
def_has_side_effects(AST_LabeledStatement, function(compressor) {
|
||||
return this.body.has_side_effects(compressor);
|
||||
});
|
||||
def_has_side_effects(AST_SimpleStatement, function(compressor) {
|
||||
return this.body.has_side_effects(compressor);
|
||||
});
|
||||
def_has_side_effects(AST_Lambda, return_false);
|
||||
def_has_side_effects(AST_Class, function (compressor) {
|
||||
if (this.extends && this.extends.has_side_effects(compressor)) {
|
||||
return true;
|
||||
}
|
||||
return any(this.properties, compressor);
|
||||
});
|
||||
def_has_side_effects(AST_ClassStaticBlock, function(compressor) {
|
||||
return any(this.body, compressor);
|
||||
});
|
||||
def_has_side_effects(AST_Binary, function(compressor) {
|
||||
return this.left.has_side_effects(compressor)
|
||||
|| this.right.has_side_effects(compressor);
|
||||
});
|
||||
def_has_side_effects(AST_Assign, return_true);
|
||||
def_has_side_effects(AST_Conditional, function(compressor) {
|
||||
return this.condition.has_side_effects(compressor)
|
||||
|| this.consequent.has_side_effects(compressor)
|
||||
|| this.alternative.has_side_effects(compressor);
|
||||
});
|
||||
def_has_side_effects(AST_Unary, function(compressor) {
|
||||
return unary_side_effects.has(this.operator)
|
||||
|| this.expression.has_side_effects(compressor);
|
||||
});
|
||||
def_has_side_effects(AST_SymbolRef, function(compressor) {
|
||||
return !this.is_declared(compressor) && !pure_prop_access_globals.has(this.name);
|
||||
});
|
||||
def_has_side_effects(AST_SymbolClassProperty, return_false);
|
||||
def_has_side_effects(AST_SymbolDeclaration, return_false);
|
||||
def_has_side_effects(AST_Object, function(compressor) {
|
||||
return any(this.properties, compressor);
|
||||
});
|
||||
def_has_side_effects(AST_ObjectProperty, function(compressor) {
|
||||
return (
|
||||
this.computed_key() && this.key.has_side_effects(compressor)
|
||||
|| this.value && this.value.has_side_effects(compressor)
|
||||
);
|
||||
});
|
||||
def_has_side_effects(AST_ClassProperty, function(compressor) {
|
||||
return (
|
||||
this.computed_key() && this.key.has_side_effects(compressor)
|
||||
|| this.static && this.value && this.value.has_side_effects(compressor)
|
||||
);
|
||||
});
|
||||
def_has_side_effects(AST_ConciseMethod, function(compressor) {
|
||||
return this.computed_key() && this.key.has_side_effects(compressor);
|
||||
});
|
||||
def_has_side_effects(AST_ObjectGetter, function(compressor) {
|
||||
return this.computed_key() && this.key.has_side_effects(compressor);
|
||||
});
|
||||
def_has_side_effects(AST_ObjectSetter, function(compressor) {
|
||||
return this.computed_key() && this.key.has_side_effects(compressor);
|
||||
});
|
||||
def_has_side_effects(AST_Array, function(compressor) {
|
||||
return any(this.elements, compressor);
|
||||
});
|
||||
def_has_side_effects(AST_Dot, function(compressor) {
|
||||
if (is_nullish(this, compressor)) {
|
||||
return this.expression.has_side_effects(compressor);
|
||||
}
|
||||
if (!this.optional && this.expression.may_throw_on_access(compressor)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return this.expression.has_side_effects(compressor);
|
||||
});
|
||||
def_has_side_effects(AST_Sub, function(compressor) {
|
||||
if (is_nullish(this, compressor)) {
|
||||
return this.expression.has_side_effects(compressor);
|
||||
}
|
||||
if (!this.optional && this.expression.may_throw_on_access(compressor)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
var property = this.property.has_side_effects(compressor);
|
||||
if (property && this.optional) return true; // "?." is a condition
|
||||
|
||||
return property || this.expression.has_side_effects(compressor);
|
||||
});
|
||||
def_has_side_effects(AST_Chain, function (compressor) {
|
||||
return this.expression.has_side_effects(compressor);
|
||||
});
|
||||
def_has_side_effects(AST_Sequence, function(compressor) {
|
||||
return any(this.expressions, compressor);
|
||||
});
|
||||
def_has_side_effects(AST_Definitions, function(compressor) {
|
||||
return any(this.definitions, compressor);
|
||||
});
|
||||
def_has_side_effects(AST_VarDef, function() {
|
||||
return this.value;
|
||||
});
|
||||
def_has_side_effects(AST_TemplateSegment, return_false);
|
||||
def_has_side_effects(AST_TemplateString, function(compressor) {
|
||||
return any(this.segments, compressor);
|
||||
});
|
||||
})(function(node, func) {
|
||||
node.DEFMETHOD("has_side_effects", func);
|
||||
});
|
||||
|
||||
// determine if expression may throw
|
||||
(function(def_may_throw) {
|
||||
def_may_throw(AST_Node, return_true);
|
||||
|
||||
def_may_throw(AST_Constant, return_false);
|
||||
def_may_throw(AST_EmptyStatement, return_false);
|
||||
def_may_throw(AST_Lambda, return_false);
|
||||
def_may_throw(AST_SymbolDeclaration, return_false);
|
||||
def_may_throw(AST_This, return_false);
|
||||
def_may_throw(AST_ImportMeta, return_false);
|
||||
|
||||
function any(list, compressor) {
|
||||
for (var i = list.length; --i >= 0;)
|
||||
if (list[i].may_throw(compressor))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
def_may_throw(AST_Class, function(compressor) {
|
||||
if (this.extends && this.extends.may_throw(compressor)) return true;
|
||||
return any(this.properties, compressor);
|
||||
});
|
||||
def_may_throw(AST_ClassStaticBlock, function (compressor) {
|
||||
return any(this.body, compressor);
|
||||
});
|
||||
|
||||
def_may_throw(AST_Array, function(compressor) {
|
||||
return any(this.elements, compressor);
|
||||
});
|
||||
def_may_throw(AST_Assign, function(compressor) {
|
||||
if (this.right.may_throw(compressor)) return true;
|
||||
if (!compressor.has_directive("use strict")
|
||||
&& this.operator == "="
|
||||
&& this.left instanceof AST_SymbolRef) {
|
||||
return false;
|
||||
}
|
||||
return this.left.may_throw(compressor);
|
||||
});
|
||||
def_may_throw(AST_Binary, function(compressor) {
|
||||
return this.left.may_throw(compressor)
|
||||
|| this.right.may_throw(compressor);
|
||||
});
|
||||
def_may_throw(AST_Block, function(compressor) {
|
||||
return any(this.body, compressor);
|
||||
});
|
||||
def_may_throw(AST_Call, function(compressor) {
|
||||
if (is_nullish(this, compressor)) return false;
|
||||
if (any(this.args, compressor)) return true;
|
||||
if (this.is_callee_pure(compressor)) return false;
|
||||
if (this.expression.may_throw(compressor)) return true;
|
||||
return !(this.expression instanceof AST_Lambda)
|
||||
|| any(this.expression.body, compressor);
|
||||
});
|
||||
def_may_throw(AST_Case, function(compressor) {
|
||||
return this.expression.may_throw(compressor)
|
||||
|| any(this.body, compressor);
|
||||
});
|
||||
def_may_throw(AST_Conditional, function(compressor) {
|
||||
return this.condition.may_throw(compressor)
|
||||
|| this.consequent.may_throw(compressor)
|
||||
|| this.alternative.may_throw(compressor);
|
||||
});
|
||||
def_may_throw(AST_Definitions, function(compressor) {
|
||||
return any(this.definitions, compressor);
|
||||
});
|
||||
def_may_throw(AST_If, function(compressor) {
|
||||
return this.condition.may_throw(compressor)
|
||||
|| this.body && this.body.may_throw(compressor)
|
||||
|| this.alternative && this.alternative.may_throw(compressor);
|
||||
});
|
||||
def_may_throw(AST_LabeledStatement, function(compressor) {
|
||||
return this.body.may_throw(compressor);
|
||||
});
|
||||
def_may_throw(AST_Object, function(compressor) {
|
||||
return any(this.properties, compressor);
|
||||
});
|
||||
def_may_throw(AST_ObjectProperty, function(compressor) {
|
||||
// TODO key may throw too
|
||||
return this.value ? this.value.may_throw(compressor) : false;
|
||||
});
|
||||
def_may_throw(AST_ClassProperty, function(compressor) {
|
||||
return (
|
||||
this.computed_key() && this.key.may_throw(compressor)
|
||||
|| this.static && this.value && this.value.may_throw(compressor)
|
||||
);
|
||||
});
|
||||
def_may_throw(AST_ConciseMethod, function(compressor) {
|
||||
return this.computed_key() && this.key.may_throw(compressor);
|
||||
});
|
||||
def_may_throw(AST_ObjectGetter, function(compressor) {
|
||||
return this.computed_key() && this.key.may_throw(compressor);
|
||||
});
|
||||
def_may_throw(AST_ObjectSetter, function(compressor) {
|
||||
return this.computed_key() && this.key.may_throw(compressor);
|
||||
});
|
||||
def_may_throw(AST_Return, function(compressor) {
|
||||
return this.value && this.value.may_throw(compressor);
|
||||
});
|
||||
def_may_throw(AST_Sequence, function(compressor) {
|
||||
return any(this.expressions, compressor);
|
||||
});
|
||||
def_may_throw(AST_SimpleStatement, function(compressor) {
|
||||
return this.body.may_throw(compressor);
|
||||
});
|
||||
def_may_throw(AST_Dot, function(compressor) {
|
||||
if (is_nullish(this, compressor)) return false;
|
||||
return !this.optional && this.expression.may_throw_on_access(compressor)
|
||||
|| this.expression.may_throw(compressor);
|
||||
});
|
||||
def_may_throw(AST_Sub, function(compressor) {
|
||||
if (is_nullish(this, compressor)) return false;
|
||||
return !this.optional && this.expression.may_throw_on_access(compressor)
|
||||
|| this.expression.may_throw(compressor)
|
||||
|| this.property.may_throw(compressor);
|
||||
});
|
||||
def_may_throw(AST_Chain, function(compressor) {
|
||||
return this.expression.may_throw(compressor);
|
||||
});
|
||||
def_may_throw(AST_Switch, function(compressor) {
|
||||
return this.expression.may_throw(compressor)
|
||||
|| any(this.body, compressor);
|
||||
});
|
||||
def_may_throw(AST_SymbolRef, function(compressor) {
|
||||
return !this.is_declared(compressor) && !pure_prop_access_globals.has(this.name);
|
||||
});
|
||||
def_may_throw(AST_SymbolClassProperty, return_false);
|
||||
def_may_throw(AST_Try, function(compressor) {
|
||||
return this.bcatch ? this.bcatch.may_throw(compressor) : this.body.may_throw(compressor)
|
||||
|| this.bfinally && this.bfinally.may_throw(compressor);
|
||||
});
|
||||
def_may_throw(AST_Unary, function(compressor) {
|
||||
if (this.operator == "typeof" && this.expression instanceof AST_SymbolRef)
|
||||
return false;
|
||||
return this.expression.may_throw(compressor);
|
||||
});
|
||||
def_may_throw(AST_VarDef, function(compressor) {
|
||||
if (!this.value) return false;
|
||||
return this.value.may_throw(compressor);
|
||||
});
|
||||
})(function(node, func) {
|
||||
node.DEFMETHOD("may_throw", func);
|
||||
});
|
||||
|
||||
// determine if expression is constant
|
||||
(function(def_is_constant_expression) {
|
||||
function all_refs_local(scope) {
|
||||
let result = true;
|
||||
walk(this, node => {
|
||||
if (node instanceof AST_SymbolRef) {
|
||||
if (has_flag(this, INLINED)) {
|
||||
result = false;
|
||||
return walk_abort;
|
||||
}
|
||||
var def = node.definition();
|
||||
if (
|
||||
member(def, this.enclosed)
|
||||
&& !this.variables.has(def.name)
|
||||
) {
|
||||
if (scope) {
|
||||
var scope_def = scope.find_variable(node);
|
||||
if (def.undeclared ? !scope_def : scope_def === def) {
|
||||
result = "f";
|
||||
return true;
|
||||
}
|
||||
}
|
||||
result = false;
|
||||
return walk_abort;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (node instanceof AST_This && this instanceof AST_Arrow) {
|
||||
result = false;
|
||||
return walk_abort;
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
def_is_constant_expression(AST_Node, return_false);
|
||||
def_is_constant_expression(AST_Constant, return_true);
|
||||
def_is_constant_expression(AST_Class, function(scope) {
|
||||
if (this.extends && !this.extends.is_constant_expression(scope)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (const prop of this.properties) {
|
||||
if (prop.computed_key() && !prop.key.is_constant_expression(scope)) {
|
||||
return false;
|
||||
}
|
||||
if (prop.static && prop.value && !prop.value.is_constant_expression(scope)) {
|
||||
return false;
|
||||
}
|
||||
if (prop instanceof AST_ClassStaticBlock) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return all_refs_local.call(this, scope);
|
||||
});
|
||||
def_is_constant_expression(AST_Lambda, all_refs_local);
|
||||
def_is_constant_expression(AST_Unary, function() {
|
||||
return this.expression.is_constant_expression();
|
||||
});
|
||||
def_is_constant_expression(AST_Binary, function() {
|
||||
return this.left.is_constant_expression()
|
||||
&& this.right.is_constant_expression();
|
||||
});
|
||||
def_is_constant_expression(AST_Array, function() {
|
||||
return this.elements.every((l) => l.is_constant_expression());
|
||||
});
|
||||
def_is_constant_expression(AST_Object, function() {
|
||||
return this.properties.every((l) => l.is_constant_expression());
|
||||
});
|
||||
def_is_constant_expression(AST_ObjectProperty, function() {
|
||||
return !!(!(this.key instanceof AST_Node) && this.value && this.value.is_constant_expression());
|
||||
});
|
||||
})(function(node, func) {
|
||||
node.DEFMETHOD("is_constant_expression", func);
|
||||
});
|
||||
|
||||
|
||||
// may_throw_on_access()
|
||||
// returns true if this node may be null, undefined or contain `AST_Accessor`
|
||||
(function(def_may_throw_on_access) {
|
||||
AST_Node.DEFMETHOD("may_throw_on_access", function(compressor) {
|
||||
return !compressor.option("pure_getters")
|
||||
|| this._dot_throw(compressor);
|
||||
});
|
||||
|
||||
function is_strict(compressor) {
|
||||
return /strict/.test(compressor.option("pure_getters"));
|
||||
}
|
||||
|
||||
def_may_throw_on_access(AST_Node, is_strict);
|
||||
def_may_throw_on_access(AST_Null, return_true);
|
||||
def_may_throw_on_access(AST_Undefined, return_true);
|
||||
def_may_throw_on_access(AST_Constant, return_false);
|
||||
def_may_throw_on_access(AST_Array, return_false);
|
||||
def_may_throw_on_access(AST_Object, function(compressor) {
|
||||
if (!is_strict(compressor)) return false;
|
||||
for (var i = this.properties.length; --i >=0;)
|
||||
if (this.properties[i]._dot_throw(compressor)) return true;
|
||||
return false;
|
||||
});
|
||||
// Do not be as strict with classes as we are with objects.
|
||||
// Hopefully the community is not going to abuse static getters and setters.
|
||||
// https://github.com/terser/terser/issues/724#issuecomment-643655656
|
||||
def_may_throw_on_access(AST_Class, return_false);
|
||||
def_may_throw_on_access(AST_ObjectProperty, return_false);
|
||||
def_may_throw_on_access(AST_ObjectGetter, return_true);
|
||||
def_may_throw_on_access(AST_Expansion, function(compressor) {
|
||||
return this.expression._dot_throw(compressor);
|
||||
});
|
||||
def_may_throw_on_access(AST_Function, return_false);
|
||||
def_may_throw_on_access(AST_Arrow, return_false);
|
||||
def_may_throw_on_access(AST_UnaryPostfix, return_false);
|
||||
def_may_throw_on_access(AST_UnaryPrefix, function() {
|
||||
return this.operator == "void";
|
||||
});
|
||||
def_may_throw_on_access(AST_Binary, function(compressor) {
|
||||
return (this.operator == "&&" || this.operator == "||" || this.operator == "??")
|
||||
&& (this.left._dot_throw(compressor) || this.right._dot_throw(compressor));
|
||||
});
|
||||
def_may_throw_on_access(AST_Assign, function(compressor) {
|
||||
if (this.logical) return true;
|
||||
|
||||
return this.operator == "="
|
||||
&& this.right._dot_throw(compressor);
|
||||
});
|
||||
def_may_throw_on_access(AST_Conditional, function(compressor) {
|
||||
return this.consequent._dot_throw(compressor)
|
||||
|| this.alternative._dot_throw(compressor);
|
||||
});
|
||||
def_may_throw_on_access(AST_Dot, function(compressor) {
|
||||
if (!is_strict(compressor)) return false;
|
||||
|
||||
if (this.property == "prototype") {
|
||||
return !(
|
||||
this.expression instanceof AST_Function
|
||||
|| this.expression instanceof AST_Class
|
||||
);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
def_may_throw_on_access(AST_Chain, function(compressor) {
|
||||
return this.expression._dot_throw(compressor);
|
||||
});
|
||||
def_may_throw_on_access(AST_Sequence, function(compressor) {
|
||||
return this.tail_node()._dot_throw(compressor);
|
||||
});
|
||||
def_may_throw_on_access(AST_SymbolRef, function(compressor) {
|
||||
if (this.name === "arguments" && this.scope instanceof AST_Lambda) return false;
|
||||
if (has_flag(this, UNDEFINED)) return true;
|
||||
if (!is_strict(compressor)) return false;
|
||||
if (is_undeclared_ref(this) && this.is_declared(compressor)) return false;
|
||||
if (this.is_immutable()) return false;
|
||||
var fixed = this.fixed_value();
|
||||
return !fixed || fixed._dot_throw(compressor);
|
||||
});
|
||||
})(function(node, func) {
|
||||
node.DEFMETHOD("_dot_throw", func);
|
||||
});
|
||||
|
||||
export function is_lhs(node, parent) {
|
||||
if (parent instanceof AST_Unary && unary_side_effects.has(parent.operator)) return parent.expression;
|
||||
if (parent instanceof AST_Assign && parent.left === node) return node;
|
||||
if (parent instanceof AST_ForIn && parent.init === node) return node;
|
||||
}
|
||||
|
||||
// method to negate an expression
|
||||
(function(def_negate) {
|
||||
function basic_negation(exp) {
|
||||
return make_node(AST_UnaryPrefix, exp, {
|
||||
operator: "!",
|
||||
expression: exp
|
||||
});
|
||||
}
|
||||
function best(orig, alt, first_in_statement) {
|
||||
var negated = basic_negation(orig);
|
||||
if (first_in_statement) {
|
||||
var stat = make_node(AST_SimpleStatement, alt, {
|
||||
body: alt
|
||||
});
|
||||
return best_of_expression(negated, stat) === stat ? alt : negated;
|
||||
}
|
||||
return best_of_expression(negated, alt);
|
||||
}
|
||||
def_negate(AST_Node, function() {
|
||||
return basic_negation(this);
|
||||
});
|
||||
def_negate(AST_Statement, function() {
|
||||
throw new Error("Cannot negate a statement");
|
||||
});
|
||||
def_negate(AST_Function, function() {
|
||||
return basic_negation(this);
|
||||
});
|
||||
def_negate(AST_Class, function() {
|
||||
return basic_negation(this);
|
||||
});
|
||||
def_negate(AST_Arrow, function() {
|
||||
return basic_negation(this);
|
||||
});
|
||||
def_negate(AST_UnaryPrefix, function() {
|
||||
if (this.operator == "!")
|
||||
return this.expression;
|
||||
return basic_negation(this);
|
||||
});
|
||||
def_negate(AST_Sequence, function(compressor) {
|
||||
var expressions = this.expressions.slice();
|
||||
expressions.push(expressions.pop().negate(compressor));
|
||||
return make_sequence(this, expressions);
|
||||
});
|
||||
def_negate(AST_Conditional, function(compressor, first_in_statement) {
|
||||
var self = this.clone();
|
||||
self.consequent = self.consequent.negate(compressor);
|
||||
self.alternative = self.alternative.negate(compressor);
|
||||
return best(this, self, first_in_statement);
|
||||
});
|
||||
def_negate(AST_Binary, function(compressor, first_in_statement) {
|
||||
var self = this.clone(), op = this.operator;
|
||||
if (compressor.option("unsafe_comps")) {
|
||||
switch (op) {
|
||||
case "<=" : self.operator = ">" ; return self;
|
||||
case "<" : self.operator = ">=" ; return self;
|
||||
case ">=" : self.operator = "<" ; return self;
|
||||
case ">" : self.operator = "<=" ; return self;
|
||||
}
|
||||
}
|
||||
switch (op) {
|
||||
case "==" : self.operator = "!="; return self;
|
||||
case "!=" : self.operator = "=="; return self;
|
||||
case "===": self.operator = "!=="; return self;
|
||||
case "!==": self.operator = "==="; return self;
|
||||
case "&&":
|
||||
self.operator = "||";
|
||||
self.left = self.left.negate(compressor, first_in_statement);
|
||||
self.right = self.right.negate(compressor);
|
||||
return best(this, self, first_in_statement);
|
||||
case "||":
|
||||
self.operator = "&&";
|
||||
self.left = self.left.negate(compressor, first_in_statement);
|
||||
self.right = self.right.negate(compressor);
|
||||
return best(this, self, first_in_statement);
|
||||
}
|
||||
return basic_negation(this);
|
||||
});
|
||||
})(function(node, func) {
|
||||
node.DEFMETHOD("negate", function(compressor, first_in_statement) {
|
||||
return func.call(this, compressor, first_in_statement);
|
||||
});
|
||||
});
|
||||
|
||||
// Is the callee of this function pure?
|
||||
var global_pure_fns = makePredicate("Boolean decodeURI decodeURIComponent Date encodeURI encodeURIComponent Error escape EvalError isFinite isNaN Number Object parseFloat parseInt RangeError ReferenceError String SyntaxError TypeError unescape URIError");
|
||||
AST_Call.DEFMETHOD("is_callee_pure", function(compressor) {
|
||||
if (compressor.option("unsafe")) {
|
||||
var expr = this.expression;
|
||||
var first_arg = (this.args && this.args[0] && this.args[0].evaluate(compressor));
|
||||
if (
|
||||
expr.expression && expr.expression.name === "hasOwnProperty" &&
|
||||
(first_arg == null || first_arg.thedef && first_arg.thedef.undeclared)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
if (is_undeclared_ref(expr) && global_pure_fns.has(expr.name)) return true;
|
||||
if (
|
||||
expr instanceof AST_Dot
|
||||
&& is_undeclared_ref(expr.expression)
|
||||
&& is_pure_native_fn(expr.expression.name, expr.property)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if ((this instanceof AST_New) && compressor.option("pure_new")) {
|
||||
return true;
|
||||
}
|
||||
if (compressor.option("side_effects") && has_annotation(this, _PURE)) {
|
||||
return true;
|
||||
}
|
||||
return !compressor.pure_funcs(this);
|
||||
});
|
||||
|
||||
// If I call this, is it a pure function?
|
||||
AST_Node.DEFMETHOD("is_call_pure", return_false);
|
||||
AST_Dot.DEFMETHOD("is_call_pure", function(compressor) {
|
||||
if (!compressor.option("unsafe")) return;
|
||||
const expr = this.expression;
|
||||
|
||||
let native_obj;
|
||||
if (expr instanceof AST_Array) {
|
||||
native_obj = "Array";
|
||||
} else if (expr.is_boolean()) {
|
||||
native_obj = "Boolean";
|
||||
} else if (expr.is_number(compressor)) {
|
||||
native_obj = "Number";
|
||||
} else if (expr instanceof AST_RegExp) {
|
||||
native_obj = "RegExp";
|
||||
} else if (expr.is_string(compressor)) {
|
||||
native_obj = "String";
|
||||
} else if (!this.may_throw_on_access(compressor)) {
|
||||
native_obj = "Object";
|
||||
}
|
||||
return native_obj != null && is_pure_native_method(native_obj, this.property);
|
||||
});
|
||||
|
||||
// tell me if a statement aborts
|
||||
export const aborts = (thing) => thing && thing.aborts();
|
||||
|
||||
(function(def_aborts) {
|
||||
def_aborts(AST_Statement, return_null);
|
||||
def_aborts(AST_Jump, return_this);
|
||||
function block_aborts() {
|
||||
for (var i = 0; i < this.body.length; i++) {
|
||||
if (aborts(this.body[i])) {
|
||||
return this.body[i];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
def_aborts(AST_Import, return_null);
|
||||
def_aborts(AST_BlockStatement, block_aborts);
|
||||
def_aborts(AST_SwitchBranch, block_aborts);
|
||||
def_aborts(AST_DefClass, function () {
|
||||
for (const prop of this.properties) {
|
||||
if (prop instanceof AST_ClassStaticBlock) {
|
||||
if (prop.aborts()) return prop;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
});
|
||||
def_aborts(AST_ClassStaticBlock, block_aborts);
|
||||
def_aborts(AST_If, function() {
|
||||
return this.alternative && aborts(this.body) && aborts(this.alternative) && this;
|
||||
});
|
||||
})(function(node, func) {
|
||||
node.DEFMETHOD("aborts", func);
|
||||
});
|
||||
|
||||
AST_Node.DEFMETHOD("contains_this", function() {
|
||||
return walk(this, node => {
|
||||
if (node instanceof AST_This) return walk_abort;
|
||||
if (
|
||||
node !== this
|
||||
&& node instanceof AST_Scope
|
||||
&& !(node instanceof AST_Arrow)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
export function is_modified(compressor, tw, node, value, level, immutable) {
|
||||
var parent = tw.parent(level);
|
||||
var lhs = is_lhs(node, parent);
|
||||
if (lhs) return lhs;
|
||||
if (!immutable
|
||||
&& parent instanceof AST_Call
|
||||
&& parent.expression === node
|
||||
&& !(value instanceof AST_Arrow)
|
||||
&& !(value instanceof AST_Class)
|
||||
&& !parent.is_callee_pure(compressor)
|
||||
&& (!(value instanceof AST_Function)
|
||||
|| !(parent instanceof AST_New) && value.contains_this())) {
|
||||
return true;
|
||||
}
|
||||
if (parent instanceof AST_Array) {
|
||||
return is_modified(compressor, tw, parent, parent, level + 1);
|
||||
}
|
||||
if (parent instanceof AST_ObjectKeyVal && node === parent.value) {
|
||||
var obj = tw.parent(level + 1);
|
||||
return is_modified(compressor, tw, obj, obj, level + 2);
|
||||
}
|
||||
if (parent instanceof AST_PropAccess && parent.expression === node) {
|
||||
var prop = read_property(value, parent.property);
|
||||
return !immutable && is_modified(compressor, tw, parent, prop, level + 1);
|
||||
}
|
||||
}
|
665
my-app/node_modules/terser/lib/compress/inline.js
generated
vendored
Executable file
665
my-app/node_modules/terser/lib/compress/inline.js
generated
vendored
Executable file
|
@ -0,0 +1,665 @@
|
|||
/***********************************************************************
|
||||
|
||||
A JavaScript tokenizer / parser / beautifier / compressor.
|
||||
https://github.com/mishoo/UglifyJS2
|
||||
|
||||
-------------------------------- (C) ---------------------------------
|
||||
|
||||
Author: Mihai Bazon
|
||||
<mihai.bazon@gmail.com>
|
||||
http://mihai.bazon.net/blog
|
||||
|
||||
Distributed under the BSD license:
|
||||
|
||||
Copyright 2012 (c) Mihai Bazon <mihai.bazon@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials
|
||||
provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
import {
|
||||
AST_Array,
|
||||
AST_Assign,
|
||||
AST_Block,
|
||||
AST_Call,
|
||||
AST_Catch,
|
||||
AST_Class,
|
||||
AST_ClassExpression,
|
||||
AST_DefaultAssign,
|
||||
AST_DefClass,
|
||||
AST_Defun,
|
||||
AST_Destructuring,
|
||||
AST_EmptyStatement,
|
||||
AST_Expansion,
|
||||
AST_Export,
|
||||
AST_Function,
|
||||
AST_IterationStatement,
|
||||
AST_Lambda,
|
||||
AST_Node,
|
||||
AST_Number,
|
||||
AST_Object,
|
||||
AST_ObjectKeyVal,
|
||||
AST_PropAccess,
|
||||
AST_Return,
|
||||
AST_Scope,
|
||||
AST_SimpleStatement,
|
||||
AST_Statement,
|
||||
AST_SymbolDefun,
|
||||
AST_SymbolFunarg,
|
||||
AST_SymbolLambda,
|
||||
AST_SymbolRef,
|
||||
AST_SymbolVar,
|
||||
AST_This,
|
||||
AST_Toplevel,
|
||||
AST_UnaryPrefix,
|
||||
AST_Undefined,
|
||||
AST_Var,
|
||||
AST_VarDef,
|
||||
|
||||
walk,
|
||||
|
||||
_INLINE,
|
||||
_NOINLINE,
|
||||
_PURE,
|
||||
} from "../ast.js";
|
||||
import { make_node, has_annotation } from "../utils/index.js";
|
||||
import "../size.js";
|
||||
|
||||
import "./evaluate.js";
|
||||
import "./drop-side-effect-free.js";
|
||||
import "./reduce-vars.js";
|
||||
import {
|
||||
SQUEEZED,
|
||||
INLINED,
|
||||
UNUSED,
|
||||
|
||||
has_flag,
|
||||
set_flag,
|
||||
} from "./compressor-flags.js";
|
||||
import {
|
||||
make_sequence,
|
||||
best_of,
|
||||
make_node_from_constant,
|
||||
identifier_atom,
|
||||
is_empty,
|
||||
is_func_expr,
|
||||
is_iife_call,
|
||||
is_reachable,
|
||||
is_recursive_ref,
|
||||
retain_top_func,
|
||||
} from "./common.js";
|
||||
|
||||
/**
|
||||
* Module that contains the inlining logic.
|
||||
*
|
||||
* @module
|
||||
*
|
||||
* The stars of the show are `inline_into_symbolref` and `inline_into_call`.
|
||||
*/
|
||||
|
||||
function within_array_or_object_literal(compressor) {
|
||||
var node, level = 0;
|
||||
while (node = compressor.parent(level++)) {
|
||||
if (node instanceof AST_Statement) return false;
|
||||
if (node instanceof AST_Array
|
||||
|| node instanceof AST_ObjectKeyVal
|
||||
|| node instanceof AST_Object) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function scope_encloses_variables_in_this_scope(scope, pulled_scope) {
|
||||
for (const enclosed of pulled_scope.enclosed) {
|
||||
if (pulled_scope.variables.has(enclosed.name)) {
|
||||
continue;
|
||||
}
|
||||
const looked_up = scope.find_variable(enclosed.name);
|
||||
if (looked_up) {
|
||||
if (looked_up === enclosed) continue;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* An extra check function for `top_retain` option, compare the length of const identifier
|
||||
* and init value length and return true if init value is longer than identifier. for example:
|
||||
* ```
|
||||
* // top_retain: ["example"]
|
||||
* const example = 100
|
||||
* ```
|
||||
* it will return false because length of "100" is short than identifier "example".
|
||||
*/
|
||||
function is_const_symbol_short_than_init_value(def, fixed_value) {
|
||||
if (def.orig.length === 1 && fixed_value) {
|
||||
const init_value_length = fixed_value.size();
|
||||
const identifer_length = def.name.length;
|
||||
return init_value_length > identifer_length;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
export function inline_into_symbolref(self, compressor) {
|
||||
const parent = compressor.parent();
|
||||
const def = self.definition();
|
||||
const nearest_scope = compressor.find_scope();
|
||||
let fixed = self.fixed_value();
|
||||
if (
|
||||
compressor.top_retain &&
|
||||
def.global &&
|
||||
compressor.top_retain(def) &&
|
||||
// when identifier is in top_retain option dose not mean we can always inline it.
|
||||
// if identifier name is longer then init value, we can replace it.
|
||||
is_const_symbol_short_than_init_value(def, fixed)
|
||||
) {
|
||||
// keep it
|
||||
def.fixed = false;
|
||||
def.single_use = false;
|
||||
return self;
|
||||
}
|
||||
|
||||
let single_use = def.single_use
|
||||
&& !(parent instanceof AST_Call
|
||||
&& (parent.is_callee_pure(compressor))
|
||||
|| has_annotation(parent, _NOINLINE))
|
||||
&& !(parent instanceof AST_Export
|
||||
&& fixed instanceof AST_Lambda
|
||||
&& fixed.name);
|
||||
|
||||
if (single_use && fixed instanceof AST_Node) {
|
||||
single_use =
|
||||
!fixed.has_side_effects(compressor)
|
||||
&& !fixed.may_throw(compressor);
|
||||
}
|
||||
|
||||
if (fixed instanceof AST_Class && def.scope !== self.scope) {
|
||||
return self;
|
||||
}
|
||||
|
||||
if (single_use && (fixed instanceof AST_Lambda || fixed instanceof AST_Class)) {
|
||||
if (retain_top_func(fixed, compressor)) {
|
||||
single_use = false;
|
||||
} else if (def.scope !== self.scope
|
||||
&& (def.escaped == 1
|
||||
|| has_flag(fixed, INLINED)
|
||||
|| within_array_or_object_literal(compressor)
|
||||
|| !compressor.option("reduce_funcs"))) {
|
||||
single_use = false;
|
||||
} else if (is_recursive_ref(compressor, def)) {
|
||||
single_use = false;
|
||||
} else if (def.scope !== self.scope || def.orig[0] instanceof AST_SymbolFunarg) {
|
||||
single_use = fixed.is_constant_expression(self.scope);
|
||||
if (single_use == "f") {
|
||||
var scope = self.scope;
|
||||
do {
|
||||
if (scope instanceof AST_Defun || is_func_expr(scope)) {
|
||||
set_flag(scope, INLINED);
|
||||
}
|
||||
} while (scope = scope.parent_scope);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (single_use && (fixed instanceof AST_Lambda || fixed instanceof AST_Class)) {
|
||||
single_use =
|
||||
def.scope === self.scope
|
||||
&& !scope_encloses_variables_in_this_scope(nearest_scope, fixed)
|
||||
|| parent instanceof AST_Call
|
||||
&& parent.expression === self
|
||||
&& !scope_encloses_variables_in_this_scope(nearest_scope, fixed)
|
||||
&& !(fixed.name && fixed.name.definition().recursive_refs > 0);
|
||||
}
|
||||
|
||||
if (single_use && fixed) {
|
||||
if (fixed instanceof AST_DefClass) {
|
||||
set_flag(fixed, SQUEEZED);
|
||||
fixed = make_node(AST_ClassExpression, fixed, fixed);
|
||||
}
|
||||
if (fixed instanceof AST_Defun) {
|
||||
set_flag(fixed, SQUEEZED);
|
||||
fixed = make_node(AST_Function, fixed, fixed);
|
||||
}
|
||||
if (def.recursive_refs > 0 && fixed.name instanceof AST_SymbolDefun) {
|
||||
const defun_def = fixed.name.definition();
|
||||
let lambda_def = fixed.variables.get(fixed.name.name);
|
||||
let name = lambda_def && lambda_def.orig[0];
|
||||
if (!(name instanceof AST_SymbolLambda)) {
|
||||
name = make_node(AST_SymbolLambda, fixed.name, fixed.name);
|
||||
name.scope = fixed;
|
||||
fixed.name = name;
|
||||
lambda_def = fixed.def_function(name);
|
||||
}
|
||||
walk(fixed, node => {
|
||||
if (node instanceof AST_SymbolRef && node.definition() === defun_def) {
|
||||
node.thedef = lambda_def;
|
||||
lambda_def.references.push(node);
|
||||
}
|
||||
});
|
||||
}
|
||||
if (
|
||||
(fixed instanceof AST_Lambda || fixed instanceof AST_Class)
|
||||
&& fixed.parent_scope !== nearest_scope
|
||||
) {
|
||||
fixed = fixed.clone(true, compressor.get_toplevel());
|
||||
|
||||
nearest_scope.add_child_scope(fixed);
|
||||
}
|
||||
return fixed.optimize(compressor);
|
||||
}
|
||||
|
||||
// multiple uses
|
||||
if (fixed) {
|
||||
let replace;
|
||||
|
||||
if (fixed instanceof AST_This) {
|
||||
if (!(def.orig[0] instanceof AST_SymbolFunarg)
|
||||
&& def.references.every((ref) =>
|
||||
def.scope === ref.scope
|
||||
)) {
|
||||
replace = fixed;
|
||||
}
|
||||
} else {
|
||||
var ev = fixed.evaluate(compressor);
|
||||
if (
|
||||
ev !== fixed
|
||||
&& (compressor.option("unsafe_regexp") || !(ev instanceof RegExp))
|
||||
) {
|
||||
replace = make_node_from_constant(ev, fixed);
|
||||
}
|
||||
}
|
||||
|
||||
if (replace) {
|
||||
const name_length = self.size(compressor);
|
||||
const replace_size = replace.size(compressor);
|
||||
|
||||
let overhead = 0;
|
||||
if (compressor.option("unused") && !compressor.exposed(def)) {
|
||||
overhead =
|
||||
(name_length + 2 + replace_size) /
|
||||
(def.references.length - def.assignments);
|
||||
}
|
||||
|
||||
if (replace_size <= name_length + overhead) {
|
||||
return replace;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
export function inline_into_call(self, compressor) {
|
||||
var exp = self.expression;
|
||||
var fn = exp;
|
||||
var simple_args = self.args.every((arg) => !(arg instanceof AST_Expansion));
|
||||
|
||||
if (compressor.option("reduce_vars")
|
||||
&& fn instanceof AST_SymbolRef
|
||||
&& !has_annotation(self, _NOINLINE)
|
||||
) {
|
||||
const fixed = fn.fixed_value();
|
||||
|
||||
if (
|
||||
retain_top_func(fixed, compressor)
|
||||
|| !compressor.toplevel.funcs && exp.definition().global
|
||||
) {
|
||||
return self;
|
||||
}
|
||||
|
||||
fn = fixed;
|
||||
}
|
||||
|
||||
var is_func = fn instanceof AST_Lambda;
|
||||
|
||||
var stat = is_func && fn.body[0];
|
||||
var is_regular_func = is_func && !fn.is_generator && !fn.async;
|
||||
var can_inline = is_regular_func && compressor.option("inline") && !self.is_callee_pure(compressor);
|
||||
if (can_inline && stat instanceof AST_Return) {
|
||||
let returned = stat.value;
|
||||
if (!returned || returned.is_constant_expression()) {
|
||||
if (returned) {
|
||||
returned = returned.clone(true);
|
||||
} else {
|
||||
returned = make_node(AST_Undefined, self);
|
||||
}
|
||||
const args = self.args.concat(returned);
|
||||
return make_sequence(self, args).optimize(compressor);
|
||||
}
|
||||
|
||||
// optimize identity function
|
||||
if (
|
||||
fn.argnames.length === 1
|
||||
&& (fn.argnames[0] instanceof AST_SymbolFunarg)
|
||||
&& self.args.length < 2
|
||||
&& !(self.args[0] instanceof AST_Expansion)
|
||||
&& returned instanceof AST_SymbolRef
|
||||
&& returned.name === fn.argnames[0].name
|
||||
) {
|
||||
const replacement =
|
||||
(self.args[0] || make_node(AST_Undefined)).optimize(compressor);
|
||||
|
||||
let parent;
|
||||
if (
|
||||
replacement instanceof AST_PropAccess
|
||||
&& (parent = compressor.parent()) instanceof AST_Call
|
||||
&& parent.expression === self
|
||||
) {
|
||||
// identity function was being used to remove `this`, like in
|
||||
//
|
||||
// id(bag.no_this)(...)
|
||||
//
|
||||
// Replace with a larger but more effish (0, bag.no_this) wrapper.
|
||||
|
||||
return make_sequence(self, [
|
||||
make_node(AST_Number, self, { value: 0 }),
|
||||
replacement
|
||||
]);
|
||||
}
|
||||
// replace call with first argument or undefined if none passed
|
||||
return replacement;
|
||||
}
|
||||
}
|
||||
|
||||
if (can_inline) {
|
||||
var scope, in_loop, level = -1;
|
||||
let def;
|
||||
let returned_value;
|
||||
let nearest_scope;
|
||||
if (simple_args
|
||||
&& !fn.uses_arguments
|
||||
&& !(compressor.parent() instanceof AST_Class)
|
||||
&& !(fn.name && fn instanceof AST_Function)
|
||||
&& (returned_value = can_flatten_body(stat))
|
||||
&& (exp === fn
|
||||
|| has_annotation(self, _INLINE)
|
||||
|| compressor.option("unused")
|
||||
&& (def = exp.definition()).references.length == 1
|
||||
&& !is_recursive_ref(compressor, def)
|
||||
&& fn.is_constant_expression(exp.scope))
|
||||
&& !has_annotation(self, _PURE | _NOINLINE)
|
||||
&& !fn.contains_this()
|
||||
&& can_inject_symbols()
|
||||
&& (nearest_scope = compressor.find_scope())
|
||||
&& !scope_encloses_variables_in_this_scope(nearest_scope, fn)
|
||||
&& !(function in_default_assign() {
|
||||
// Due to the fact function parameters have their own scope
|
||||
// which can't use `var something` in the function body within,
|
||||
// we simply don't inline into DefaultAssign.
|
||||
let i = 0;
|
||||
let p;
|
||||
while ((p = compressor.parent(i++))) {
|
||||
if (p instanceof AST_DefaultAssign) return true;
|
||||
if (p instanceof AST_Block) break;
|
||||
}
|
||||
return false;
|
||||
})()
|
||||
&& !(scope instanceof AST_Class)
|
||||
) {
|
||||
set_flag(fn, SQUEEZED);
|
||||
nearest_scope.add_child_scope(fn);
|
||||
return make_sequence(self, flatten_fn(returned_value)).optimize(compressor);
|
||||
}
|
||||
}
|
||||
|
||||
if (can_inline && has_annotation(self, _INLINE)) {
|
||||
set_flag(fn, SQUEEZED);
|
||||
fn = make_node(fn.CTOR === AST_Defun ? AST_Function : fn.CTOR, fn, fn);
|
||||
fn = fn.clone(true);
|
||||
fn.figure_out_scope({}, {
|
||||
parent_scope: compressor.find_scope(),
|
||||
toplevel: compressor.get_toplevel()
|
||||
});
|
||||
|
||||
return make_node(AST_Call, self, {
|
||||
expression: fn,
|
||||
args: self.args,
|
||||
}).optimize(compressor);
|
||||
}
|
||||
|
||||
const can_drop_this_call = is_regular_func && compressor.option("side_effects") && fn.body.every(is_empty);
|
||||
if (can_drop_this_call) {
|
||||
var args = self.args.concat(make_node(AST_Undefined, self));
|
||||
return make_sequence(self, args).optimize(compressor);
|
||||
}
|
||||
|
||||
if (compressor.option("negate_iife")
|
||||
&& compressor.parent() instanceof AST_SimpleStatement
|
||||
&& is_iife_call(self)) {
|
||||
return self.negate(compressor, true);
|
||||
}
|
||||
|
||||
var ev = self.evaluate(compressor);
|
||||
if (ev !== self) {
|
||||
ev = make_node_from_constant(ev, self).optimize(compressor);
|
||||
return best_of(compressor, ev, self);
|
||||
}
|
||||
|
||||
return self;
|
||||
|
||||
function return_value(stat) {
|
||||
if (!stat) return make_node(AST_Undefined, self);
|
||||
if (stat instanceof AST_Return) {
|
||||
if (!stat.value) return make_node(AST_Undefined, self);
|
||||
return stat.value.clone(true);
|
||||
}
|
||||
if (stat instanceof AST_SimpleStatement) {
|
||||
return make_node(AST_UnaryPrefix, stat, {
|
||||
operator: "void",
|
||||
expression: stat.body.clone(true)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function can_flatten_body(stat) {
|
||||
var body = fn.body;
|
||||
var len = body.length;
|
||||
if (compressor.option("inline") < 3) {
|
||||
return len == 1 && return_value(stat);
|
||||
}
|
||||
stat = null;
|
||||
for (var i = 0; i < len; i++) {
|
||||
var line = body[i];
|
||||
if (line instanceof AST_Var) {
|
||||
if (stat && !line.definitions.every((var_def) =>
|
||||
!var_def.value
|
||||
)) {
|
||||
return false;
|
||||
}
|
||||
} else if (stat) {
|
||||
return false;
|
||||
} else if (!(line instanceof AST_EmptyStatement)) {
|
||||
stat = line;
|
||||
}
|
||||
}
|
||||
return return_value(stat);
|
||||
}
|
||||
|
||||
function can_inject_args(block_scoped, safe_to_inject) {
|
||||
for (var i = 0, len = fn.argnames.length; i < len; i++) {
|
||||
var arg = fn.argnames[i];
|
||||
if (arg instanceof AST_DefaultAssign) {
|
||||
if (has_flag(arg.left, UNUSED)) continue;
|
||||
return false;
|
||||
}
|
||||
if (arg instanceof AST_Destructuring) return false;
|
||||
if (arg instanceof AST_Expansion) {
|
||||
if (has_flag(arg.expression, UNUSED)) continue;
|
||||
return false;
|
||||
}
|
||||
if (has_flag(arg, UNUSED)) continue;
|
||||
if (!safe_to_inject
|
||||
|| block_scoped.has(arg.name)
|
||||
|| identifier_atom.has(arg.name)
|
||||
|| scope.conflicting_def(arg.name)) {
|
||||
return false;
|
||||
}
|
||||
if (in_loop) in_loop.push(arg.definition());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function can_inject_vars(block_scoped, safe_to_inject) {
|
||||
var len = fn.body.length;
|
||||
for (var i = 0; i < len; i++) {
|
||||
var stat = fn.body[i];
|
||||
if (!(stat instanceof AST_Var)) continue;
|
||||
if (!safe_to_inject) return false;
|
||||
for (var j = stat.definitions.length; --j >= 0;) {
|
||||
var name = stat.definitions[j].name;
|
||||
if (name instanceof AST_Destructuring
|
||||
|| block_scoped.has(name.name)
|
||||
|| identifier_atom.has(name.name)
|
||||
|| scope.conflicting_def(name.name)) {
|
||||
return false;
|
||||
}
|
||||
if (in_loop) in_loop.push(name.definition());
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function can_inject_symbols() {
|
||||
var block_scoped = new Set();
|
||||
do {
|
||||
scope = compressor.parent(++level);
|
||||
if (scope.is_block_scope() && scope.block_scope) {
|
||||
// TODO this is sometimes undefined during compression.
|
||||
// But it should always have a value!
|
||||
scope.block_scope.variables.forEach(function (variable) {
|
||||
block_scoped.add(variable.name);
|
||||
});
|
||||
}
|
||||
if (scope instanceof AST_Catch) {
|
||||
// TODO can we delete? AST_Catch is a block scope.
|
||||
if (scope.argname) {
|
||||
block_scoped.add(scope.argname.name);
|
||||
}
|
||||
} else if (scope instanceof AST_IterationStatement) {
|
||||
in_loop = [];
|
||||
} else if (scope instanceof AST_SymbolRef) {
|
||||
if (scope.fixed_value() instanceof AST_Scope) return false;
|
||||
}
|
||||
} while (!(scope instanceof AST_Scope));
|
||||
|
||||
var safe_to_inject = !(scope instanceof AST_Toplevel) || compressor.toplevel.vars;
|
||||
var inline = compressor.option("inline");
|
||||
if (!can_inject_vars(block_scoped, inline >= 3 && safe_to_inject)) return false;
|
||||
if (!can_inject_args(block_scoped, inline >= 2 && safe_to_inject)) return false;
|
||||
return !in_loop || in_loop.length == 0 || !is_reachable(fn, in_loop);
|
||||
}
|
||||
|
||||
function append_var(decls, expressions, name, value) {
|
||||
var def = name.definition();
|
||||
|
||||
// Name already exists, only when a function argument had the same name
|
||||
const already_appended = scope.variables.has(name.name);
|
||||
if (!already_appended) {
|
||||
scope.variables.set(name.name, def);
|
||||
scope.enclosed.push(def);
|
||||
decls.push(make_node(AST_VarDef, name, {
|
||||
name: name,
|
||||
value: null
|
||||
}));
|
||||
}
|
||||
|
||||
var sym = make_node(AST_SymbolRef, name, name);
|
||||
def.references.push(sym);
|
||||
if (value) expressions.push(make_node(AST_Assign, self, {
|
||||
operator: "=",
|
||||
logical: false,
|
||||
left: sym,
|
||||
right: value.clone()
|
||||
}));
|
||||
}
|
||||
|
||||
function flatten_args(decls, expressions) {
|
||||
var len = fn.argnames.length;
|
||||
for (var i = self.args.length; --i >= len;) {
|
||||
expressions.push(self.args[i]);
|
||||
}
|
||||
for (i = len; --i >= 0;) {
|
||||
var name = fn.argnames[i];
|
||||
var value = self.args[i];
|
||||
if (has_flag(name, UNUSED) || !name.name || scope.conflicting_def(name.name)) {
|
||||
if (value) expressions.push(value);
|
||||
} else {
|
||||
var symbol = make_node(AST_SymbolVar, name, name);
|
||||
name.definition().orig.push(symbol);
|
||||
if (!value && in_loop) value = make_node(AST_Undefined, self);
|
||||
append_var(decls, expressions, symbol, value);
|
||||
}
|
||||
}
|
||||
decls.reverse();
|
||||
expressions.reverse();
|
||||
}
|
||||
|
||||
function flatten_vars(decls, expressions) {
|
||||
var pos = expressions.length;
|
||||
for (var i = 0, lines = fn.body.length; i < lines; i++) {
|
||||
var stat = fn.body[i];
|
||||
if (!(stat instanceof AST_Var)) continue;
|
||||
for (var j = 0, defs = stat.definitions.length; j < defs; j++) {
|
||||
var var_def = stat.definitions[j];
|
||||
var name = var_def.name;
|
||||
append_var(decls, expressions, name, var_def.value);
|
||||
if (in_loop && fn.argnames.every((argname) =>
|
||||
argname.name != name.name
|
||||
)) {
|
||||
var def = fn.variables.get(name.name);
|
||||
var sym = make_node(AST_SymbolRef, name, name);
|
||||
def.references.push(sym);
|
||||
expressions.splice(pos++, 0, make_node(AST_Assign, var_def, {
|
||||
operator: "=",
|
||||
logical: false,
|
||||
left: sym,
|
||||
right: make_node(AST_Undefined, name)
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function flatten_fn(returned_value) {
|
||||
var decls = [];
|
||||
var expressions = [];
|
||||
flatten_args(decls, expressions);
|
||||
flatten_vars(decls, expressions);
|
||||
expressions.push(returned_value);
|
||||
|
||||
if (decls.length) {
|
||||
const i = scope.body.indexOf(compressor.parent(level - 1)) + 1;
|
||||
scope.body.splice(i, 0, make_node(AST_Var, fn, {
|
||||
definitions: decls
|
||||
}));
|
||||
}
|
||||
|
||||
return expressions.map(exp => exp.clone(true));
|
||||
}
|
||||
}
|
206
my-app/node_modules/terser/lib/compress/native-objects.js
generated
vendored
Executable file
206
my-app/node_modules/terser/lib/compress/native-objects.js
generated
vendored
Executable file
|
@ -0,0 +1,206 @@
|
|||
/***********************************************************************
|
||||
|
||||
A JavaScript tokenizer / parser / beautifier / compressor.
|
||||
https://github.com/mishoo/UglifyJS2
|
||||
|
||||
-------------------------------- (C) ---------------------------------
|
||||
|
||||
Author: Mihai Bazon
|
||||
<mihai.bazon@gmail.com>
|
||||
http://mihai.bazon.net/blog
|
||||
|
||||
Distributed under the BSD license:
|
||||
|
||||
Copyright 2012 (c) Mihai Bazon <mihai.bazon@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials
|
||||
provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
import { makePredicate } from "../utils/index.js";
|
||||
|
||||
// Lists of native methods, useful for `unsafe` option which assumes they exist.
|
||||
// Note: Lots of methods and functions are missing here, in case they aren't pure
|
||||
// or not available in all JS environments.
|
||||
|
||||
function make_nested_lookup(obj) {
|
||||
const out = new Map();
|
||||
for (var key of Object.keys(obj)) {
|
||||
out.set(key, makePredicate(obj[key]));
|
||||
}
|
||||
|
||||
const does_have = (global_name, fname) => {
|
||||
const inner_map = out.get(global_name);
|
||||
return inner_map != null && inner_map.has(fname);
|
||||
};
|
||||
return does_have;
|
||||
}
|
||||
|
||||
// Objects which are safe to access without throwing or causing a side effect.
|
||||
// Usually we'd check the `unsafe` option first but these are way too common for that
|
||||
export const pure_prop_access_globals = new Set([
|
||||
"Number",
|
||||
"String",
|
||||
"Array",
|
||||
"Object",
|
||||
"Function",
|
||||
"Promise",
|
||||
]);
|
||||
|
||||
const object_methods = [
|
||||
"constructor",
|
||||
"toString",
|
||||
"valueOf",
|
||||
];
|
||||
|
||||
export const is_pure_native_method = make_nested_lookup({
|
||||
Array: [
|
||||
"at",
|
||||
"flat",
|
||||
"includes",
|
||||
"indexOf",
|
||||
"join",
|
||||
"lastIndexOf",
|
||||
"slice",
|
||||
...object_methods,
|
||||
],
|
||||
Boolean: object_methods,
|
||||
Function: object_methods,
|
||||
Number: [
|
||||
"toExponential",
|
||||
"toFixed",
|
||||
"toPrecision",
|
||||
...object_methods,
|
||||
],
|
||||
Object: object_methods,
|
||||
RegExp: [
|
||||
"test",
|
||||
...object_methods,
|
||||
],
|
||||
String: [
|
||||
"at",
|
||||
"charAt",
|
||||
"charCodeAt",
|
||||
"charPointAt",
|
||||
"concat",
|
||||
"endsWith",
|
||||
"fromCharCode",
|
||||
"fromCodePoint",
|
||||
"includes",
|
||||
"indexOf",
|
||||
"italics",
|
||||
"lastIndexOf",
|
||||
"localeCompare",
|
||||
"match",
|
||||
"matchAll",
|
||||
"normalize",
|
||||
"padStart",
|
||||
"padEnd",
|
||||
"repeat",
|
||||
"replace",
|
||||
"replaceAll",
|
||||
"search",
|
||||
"slice",
|
||||
"split",
|
||||
"startsWith",
|
||||
"substr",
|
||||
"substring",
|
||||
"repeat",
|
||||
"toLocaleLowerCase",
|
||||
"toLocaleUpperCase",
|
||||
"toLowerCase",
|
||||
"toUpperCase",
|
||||
"trim",
|
||||
"trimEnd",
|
||||
"trimStart",
|
||||
...object_methods,
|
||||
],
|
||||
});
|
||||
|
||||
export const is_pure_native_fn = make_nested_lookup({
|
||||
Array: [
|
||||
"isArray",
|
||||
],
|
||||
Math: [
|
||||
"abs",
|
||||
"acos",
|
||||
"asin",
|
||||
"atan",
|
||||
"ceil",
|
||||
"cos",
|
||||
"exp",
|
||||
"floor",
|
||||
"log",
|
||||
"round",
|
||||
"sin",
|
||||
"sqrt",
|
||||
"tan",
|
||||
"atan2",
|
||||
"pow",
|
||||
"max",
|
||||
"min",
|
||||
],
|
||||
Number: [
|
||||
"isFinite",
|
||||
"isNaN",
|
||||
],
|
||||
Object: [
|
||||
"create",
|
||||
"getOwnPropertyDescriptor",
|
||||
"getOwnPropertyNames",
|
||||
"getPrototypeOf",
|
||||
"isExtensible",
|
||||
"isFrozen",
|
||||
"isSealed",
|
||||
"hasOwn",
|
||||
"keys",
|
||||
],
|
||||
String: [
|
||||
"fromCharCode",
|
||||
],
|
||||
});
|
||||
|
||||
// Known numeric values which come with JS environments
|
||||
export const is_pure_native_value = make_nested_lookup({
|
||||
Math: [
|
||||
"E",
|
||||
"LN10",
|
||||
"LN2",
|
||||
"LOG2E",
|
||||
"LOG10E",
|
||||
"PI",
|
||||
"SQRT1_2",
|
||||
"SQRT2",
|
||||
],
|
||||
Number: [
|
||||
"MAX_VALUE",
|
||||
"MIN_VALUE",
|
||||
"NaN",
|
||||
"NEGATIVE_INFINITY",
|
||||
"POSITIVE_INFINITY",
|
||||
],
|
||||
});
|
824
my-app/node_modules/terser/lib/compress/reduce-vars.js
generated
vendored
Executable file
824
my-app/node_modules/terser/lib/compress/reduce-vars.js
generated
vendored
Executable file
|
@ -0,0 +1,824 @@
|
|||
/***********************************************************************
|
||||
|
||||
A JavaScript tokenizer / parser / beautifier / compressor.
|
||||
https://github.com/mishoo/UglifyJS2
|
||||
|
||||
-------------------------------- (C) ---------------------------------
|
||||
|
||||
Author: Mihai Bazon
|
||||
<mihai.bazon@gmail.com>
|
||||
http://mihai.bazon.net/blog
|
||||
|
||||
Distributed under the BSD license:
|
||||
|
||||
Copyright 2012 (c) Mihai Bazon <mihai.bazon@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials
|
||||
provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
import {
|
||||
AST_Accessor,
|
||||
AST_Array,
|
||||
AST_Assign,
|
||||
AST_Await,
|
||||
AST_Binary,
|
||||
AST_Block,
|
||||
AST_Call,
|
||||
AST_Case,
|
||||
AST_Chain,
|
||||
AST_Class,
|
||||
AST_ClassStaticBlock,
|
||||
AST_ClassExpression,
|
||||
AST_Conditional,
|
||||
AST_Default,
|
||||
AST_Defun,
|
||||
AST_Destructuring,
|
||||
AST_Do,
|
||||
AST_Exit,
|
||||
AST_Expansion,
|
||||
AST_For,
|
||||
AST_ForIn,
|
||||
AST_If,
|
||||
AST_LabeledStatement,
|
||||
AST_Lambda,
|
||||
AST_New,
|
||||
AST_Node,
|
||||
AST_Number,
|
||||
AST_ObjectKeyVal,
|
||||
AST_PropAccess,
|
||||
AST_Scope,
|
||||
AST_Sequence,
|
||||
AST_SimpleStatement,
|
||||
AST_Symbol,
|
||||
AST_SymbolCatch,
|
||||
AST_SymbolConst,
|
||||
AST_SymbolDeclaration,
|
||||
AST_SymbolDefun,
|
||||
AST_SymbolFunarg,
|
||||
AST_SymbolLambda,
|
||||
AST_SymbolRef,
|
||||
AST_This,
|
||||
AST_Toplevel,
|
||||
AST_Try,
|
||||
AST_Unary,
|
||||
AST_UnaryPrefix,
|
||||
AST_Undefined,
|
||||
AST_VarDef,
|
||||
AST_While,
|
||||
AST_Yield,
|
||||
|
||||
walk,
|
||||
walk_body,
|
||||
|
||||
TreeWalker,
|
||||
} from "../ast.js";
|
||||
import { HOP, make_node, noop } from "../utils/index.js";
|
||||
|
||||
import { lazy_op, is_modified, is_lhs } from "./inference.js";
|
||||
import { INLINED, clear_flag } from "./compressor-flags.js";
|
||||
import { read_property, has_break_or_continue, is_recursive_ref } from "./common.js";
|
||||
|
||||
/**
|
||||
* Define the method AST_Node#reduce_vars, which goes through the AST in
|
||||
* execution order to perform basic flow analysis
|
||||
*/
|
||||
function def_reduce_vars(node, func) {
|
||||
node.DEFMETHOD("reduce_vars", func);
|
||||
}
|
||||
|
||||
def_reduce_vars(AST_Node, noop);
|
||||
|
||||
/** Clear definition properties */
|
||||
function reset_def(compressor, def) {
|
||||
def.assignments = 0;
|
||||
def.chained = false;
|
||||
def.direct_access = false;
|
||||
def.escaped = 0;
|
||||
def.recursive_refs = 0;
|
||||
def.references = [];
|
||||
def.single_use = undefined;
|
||||
if (
|
||||
def.scope.pinned()
|
||||
|| (def.orig[0] instanceof AST_SymbolFunarg && def.scope.uses_arguments)
|
||||
) {
|
||||
def.fixed = false;
|
||||
} else if (def.orig[0] instanceof AST_SymbolConst || !compressor.exposed(def)) {
|
||||
def.fixed = def.init;
|
||||
} else {
|
||||
def.fixed = false;
|
||||
}
|
||||
}
|
||||
|
||||
function reset_variables(tw, compressor, node) {
|
||||
node.variables.forEach(function(def) {
|
||||
reset_def(compressor, def);
|
||||
if (def.fixed === null) {
|
||||
tw.defs_to_safe_ids.set(def.id, tw.safe_ids);
|
||||
mark(tw, def, true);
|
||||
} else if (def.fixed) {
|
||||
tw.loop_ids.set(def.id, tw.in_loop);
|
||||
mark(tw, def, true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function reset_block_variables(compressor, node) {
|
||||
if (node.block_scope) node.block_scope.variables.forEach((def) => {
|
||||
reset_def(compressor, def);
|
||||
});
|
||||
}
|
||||
|
||||
function push(tw) {
|
||||
tw.safe_ids = Object.create(tw.safe_ids);
|
||||
}
|
||||
|
||||
function pop(tw) {
|
||||
tw.safe_ids = Object.getPrototypeOf(tw.safe_ids);
|
||||
}
|
||||
|
||||
function mark(tw, def, safe) {
|
||||
tw.safe_ids[def.id] = safe;
|
||||
}
|
||||
|
||||
function safe_to_read(tw, def) {
|
||||
if (def.single_use == "m") return false;
|
||||
if (tw.safe_ids[def.id]) {
|
||||
if (def.fixed == null) {
|
||||
var orig = def.orig[0];
|
||||
if (orig instanceof AST_SymbolFunarg || orig.name == "arguments") return false;
|
||||
def.fixed = make_node(AST_Undefined, orig);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return def.fixed instanceof AST_Defun;
|
||||
}
|
||||
|
||||
function safe_to_assign(tw, def, scope, value) {
|
||||
if (def.fixed === undefined) return true;
|
||||
let def_safe_ids;
|
||||
if (def.fixed === null
|
||||
&& (def_safe_ids = tw.defs_to_safe_ids.get(def.id))
|
||||
) {
|
||||
def_safe_ids[def.id] = false;
|
||||
tw.defs_to_safe_ids.delete(def.id);
|
||||
return true;
|
||||
}
|
||||
if (!HOP(tw.safe_ids, def.id)) return false;
|
||||
if (!safe_to_read(tw, def)) return false;
|
||||
if (def.fixed === false) return false;
|
||||
if (def.fixed != null && (!value || def.references.length > def.assignments)) return false;
|
||||
if (def.fixed instanceof AST_Defun) {
|
||||
return value instanceof AST_Node && def.fixed.parent_scope === scope;
|
||||
}
|
||||
return def.orig.every((sym) => {
|
||||
return !(sym instanceof AST_SymbolConst
|
||||
|| sym instanceof AST_SymbolDefun
|
||||
|| sym instanceof AST_SymbolLambda);
|
||||
});
|
||||
}
|
||||
|
||||
function ref_once(tw, compressor, def) {
|
||||
return compressor.option("unused")
|
||||
&& !def.scope.pinned()
|
||||
&& def.references.length - def.recursive_refs == 1
|
||||
&& tw.loop_ids.get(def.id) === tw.in_loop;
|
||||
}
|
||||
|
||||
function is_immutable(value) {
|
||||
if (!value) return false;
|
||||
return value.is_constant()
|
||||
|| value instanceof AST_Lambda
|
||||
|| value instanceof AST_This;
|
||||
}
|
||||
|
||||
// A definition "escapes" when its value can leave the point of use.
|
||||
// Example: `a = b || c`
|
||||
// In this example, "b" and "c" are escaping, because they're going into "a"
|
||||
//
|
||||
// def.escaped is != 0 when it escapes.
|
||||
//
|
||||
// When greater than 1, it means that N chained properties will be read off
|
||||
// of that def before an escape occurs. This is useful for evaluating
|
||||
// property accesses, where you need to know when to stop.
|
||||
function mark_escaped(tw, d, scope, node, value, level = 0, depth = 1) {
|
||||
var parent = tw.parent(level);
|
||||
if (value) {
|
||||
if (value.is_constant()) return;
|
||||
if (value instanceof AST_ClassExpression) return;
|
||||
}
|
||||
|
||||
if (
|
||||
parent instanceof AST_Assign && (parent.operator === "=" || parent.logical) && node === parent.right
|
||||
|| parent instanceof AST_Call && (node !== parent.expression || parent instanceof AST_New)
|
||||
|| parent instanceof AST_Exit && node === parent.value && node.scope !== d.scope
|
||||
|| parent instanceof AST_VarDef && node === parent.value
|
||||
|| parent instanceof AST_Yield && node === parent.value && node.scope !== d.scope
|
||||
) {
|
||||
if (depth > 1 && !(value && value.is_constant_expression(scope))) depth = 1;
|
||||
if (!d.escaped || d.escaped > depth) d.escaped = depth;
|
||||
return;
|
||||
} else if (
|
||||
parent instanceof AST_Array
|
||||
|| parent instanceof AST_Await
|
||||
|| parent instanceof AST_Binary && lazy_op.has(parent.operator)
|
||||
|| parent instanceof AST_Conditional && node !== parent.condition
|
||||
|| parent instanceof AST_Expansion
|
||||
|| parent instanceof AST_Sequence && node === parent.tail_node()
|
||||
) {
|
||||
mark_escaped(tw, d, scope, parent, parent, level + 1, depth);
|
||||
} else if (parent instanceof AST_ObjectKeyVal && node === parent.value) {
|
||||
var obj = tw.parent(level + 1);
|
||||
|
||||
mark_escaped(tw, d, scope, obj, obj, level + 2, depth);
|
||||
} else if (parent instanceof AST_PropAccess && node === parent.expression) {
|
||||
value = read_property(value, parent.property);
|
||||
|
||||
mark_escaped(tw, d, scope, parent, value, level + 1, depth + 1);
|
||||
if (value) return;
|
||||
}
|
||||
|
||||
if (level > 0) return;
|
||||
if (parent instanceof AST_Sequence && node !== parent.tail_node()) return;
|
||||
if (parent instanceof AST_SimpleStatement) return;
|
||||
|
||||
d.direct_access = true;
|
||||
}
|
||||
|
||||
const suppress = node => walk(node, node => {
|
||||
if (!(node instanceof AST_Symbol)) return;
|
||||
var d = node.definition();
|
||||
if (!d) return;
|
||||
if (node instanceof AST_SymbolRef) d.references.push(node);
|
||||
d.fixed = false;
|
||||
});
|
||||
|
||||
def_reduce_vars(AST_Accessor, function(tw, descend, compressor) {
|
||||
push(tw);
|
||||
reset_variables(tw, compressor, this);
|
||||
descend();
|
||||
pop(tw);
|
||||
return true;
|
||||
});
|
||||
|
||||
def_reduce_vars(AST_Assign, function(tw, descend, compressor) {
|
||||
var node = this;
|
||||
if (node.left instanceof AST_Destructuring) {
|
||||
suppress(node.left);
|
||||
return;
|
||||
}
|
||||
|
||||
const finish_walk = () => {
|
||||
if (node.logical) {
|
||||
node.left.walk(tw);
|
||||
|
||||
push(tw);
|
||||
node.right.walk(tw);
|
||||
pop(tw);
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
var sym = node.left;
|
||||
if (!(sym instanceof AST_SymbolRef)) return finish_walk();
|
||||
|
||||
var def = sym.definition();
|
||||
var safe = safe_to_assign(tw, def, sym.scope, node.right);
|
||||
def.assignments++;
|
||||
if (!safe) return finish_walk();
|
||||
|
||||
var fixed = def.fixed;
|
||||
if (!fixed && node.operator != "=" && !node.logical) return finish_walk();
|
||||
|
||||
var eq = node.operator == "=";
|
||||
var value = eq ? node.right : node;
|
||||
if (is_modified(compressor, tw, node, value, 0)) return finish_walk();
|
||||
|
||||
def.references.push(sym);
|
||||
|
||||
if (!node.logical) {
|
||||
if (!eq) def.chained = true;
|
||||
|
||||
def.fixed = eq ? function() {
|
||||
return node.right;
|
||||
} : function() {
|
||||
return make_node(AST_Binary, node, {
|
||||
operator: node.operator.slice(0, -1),
|
||||
left: fixed instanceof AST_Node ? fixed : fixed(),
|
||||
right: node.right
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
if (node.logical) {
|
||||
mark(tw, def, false);
|
||||
push(tw);
|
||||
node.right.walk(tw);
|
||||
pop(tw);
|
||||
return true;
|
||||
}
|
||||
|
||||
mark(tw, def, false);
|
||||
node.right.walk(tw);
|
||||
mark(tw, def, true);
|
||||
|
||||
mark_escaped(tw, def, sym.scope, node, value, 0, 1);
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
def_reduce_vars(AST_Binary, function(tw) {
|
||||
if (!lazy_op.has(this.operator)) return;
|
||||
this.left.walk(tw);
|
||||
push(tw);
|
||||
this.right.walk(tw);
|
||||
pop(tw);
|
||||
return true;
|
||||
});
|
||||
|
||||
def_reduce_vars(AST_Block, function(tw, descend, compressor) {
|
||||
reset_block_variables(compressor, this);
|
||||
});
|
||||
|
||||
def_reduce_vars(AST_Case, function(tw) {
|
||||
push(tw);
|
||||
this.expression.walk(tw);
|
||||
pop(tw);
|
||||
push(tw);
|
||||
walk_body(this, tw);
|
||||
pop(tw);
|
||||
return true;
|
||||
});
|
||||
|
||||
def_reduce_vars(AST_Class, function(tw, descend) {
|
||||
clear_flag(this, INLINED);
|
||||
push(tw);
|
||||
descend();
|
||||
pop(tw);
|
||||
return true;
|
||||
});
|
||||
|
||||
def_reduce_vars(AST_ClassStaticBlock, function(tw, descend, compressor) {
|
||||
reset_block_variables(compressor, this);
|
||||
});
|
||||
|
||||
def_reduce_vars(AST_Conditional, function(tw) {
|
||||
this.condition.walk(tw);
|
||||
push(tw);
|
||||
this.consequent.walk(tw);
|
||||
pop(tw);
|
||||
push(tw);
|
||||
this.alternative.walk(tw);
|
||||
pop(tw);
|
||||
return true;
|
||||
});
|
||||
|
||||
def_reduce_vars(AST_Chain, function(tw, descend) {
|
||||
// Chains' conditions apply left-to-right, cumulatively.
|
||||
// If we walk normally we don't go in that order because we would pop before pushing again
|
||||
// Solution: AST_PropAccess and AST_Call push when they are optional, and never pop.
|
||||
// Then we pop everything when they are done being walked.
|
||||
const safe_ids = tw.safe_ids;
|
||||
|
||||
descend();
|
||||
|
||||
// Unroll back to start
|
||||
tw.safe_ids = safe_ids;
|
||||
return true;
|
||||
});
|
||||
|
||||
def_reduce_vars(AST_Call, function (tw) {
|
||||
this.expression.walk(tw);
|
||||
|
||||
if (this.optional) {
|
||||
// Never pop -- it's popped at AST_Chain above
|
||||
push(tw);
|
||||
}
|
||||
|
||||
for (const arg of this.args) arg.walk(tw);
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
def_reduce_vars(AST_PropAccess, function (tw) {
|
||||
if (!this.optional) return;
|
||||
|
||||
this.expression.walk(tw);
|
||||
|
||||
// Never pop -- it's popped at AST_Chain above
|
||||
push(tw);
|
||||
|
||||
if (this.property instanceof AST_Node) this.property.walk(tw);
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
def_reduce_vars(AST_Default, function(tw, descend) {
|
||||
push(tw);
|
||||
descend();
|
||||
pop(tw);
|
||||
return true;
|
||||
});
|
||||
|
||||
function mark_lambda(tw, descend, compressor) {
|
||||
clear_flag(this, INLINED);
|
||||
push(tw);
|
||||
reset_variables(tw, compressor, this);
|
||||
|
||||
var iife;
|
||||
if (!this.name
|
||||
&& !this.uses_arguments
|
||||
&& !this.pinned()
|
||||
&& (iife = tw.parent()) instanceof AST_Call
|
||||
&& iife.expression === this
|
||||
&& !iife.args.some(arg => arg instanceof AST_Expansion)
|
||||
&& this.argnames.every(arg_name => arg_name instanceof AST_Symbol)
|
||||
) {
|
||||
// Virtually turn IIFE parameters into variable definitions:
|
||||
// (function(a,b) {...})(c,d) => (function() {var a=c,b=d; ...})()
|
||||
// So existing transformation rules can work on them.
|
||||
this.argnames.forEach((arg, i) => {
|
||||
if (!arg.definition) return;
|
||||
var d = arg.definition();
|
||||
// Avoid setting fixed when there's more than one origin for a variable value
|
||||
if (d.orig.length > 1) return;
|
||||
if (d.fixed === undefined && (!this.uses_arguments || tw.has_directive("use strict"))) {
|
||||
d.fixed = function() {
|
||||
return iife.args[i] || make_node(AST_Undefined, iife);
|
||||
};
|
||||
tw.loop_ids.set(d.id, tw.in_loop);
|
||||
mark(tw, d, true);
|
||||
} else {
|
||||
d.fixed = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
descend();
|
||||
pop(tw);
|
||||
|
||||
handle_defined_after_hoist(this);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* It's possible for a hoisted function to use something that's not defined yet. Example:
|
||||
*
|
||||
* hoisted();
|
||||
* var defined_after = true;
|
||||
* function hoisted() {
|
||||
* // use defined_after
|
||||
* }
|
||||
*
|
||||
* This function is called on the parent to handle this issue.
|
||||
*/
|
||||
function handle_defined_after_hoist(parent) {
|
||||
const defuns = [];
|
||||
walk(parent, node => {
|
||||
if (node === parent) return;
|
||||
if (node instanceof AST_Defun) defuns.push(node);
|
||||
if (
|
||||
node instanceof AST_Scope
|
||||
|| node instanceof AST_SimpleStatement
|
||||
) return true;
|
||||
});
|
||||
|
||||
const symbols_of_interest = new Set();
|
||||
const defuns_of_interest = new Set();
|
||||
const potential_conflicts = [];
|
||||
|
||||
for (const defun of defuns) {
|
||||
const fname_def = defun.name.definition();
|
||||
const found_self_ref_in_other_defuns = defuns.some(
|
||||
d => d !== defun && d.enclosed.indexOf(fname_def) !== -1
|
||||
);
|
||||
|
||||
for (const def of defun.enclosed) {
|
||||
if (
|
||||
def.fixed === false
|
||||
|| def === fname_def
|
||||
|| def.scope.get_defun_scope() !== parent
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// defun is hoisted, so always safe
|
||||
if (
|
||||
def.assignments === 0
|
||||
&& def.orig.length === 1
|
||||
&& def.orig[0] instanceof AST_SymbolDefun
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (found_self_ref_in_other_defuns) {
|
||||
def.fixed = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
// for the slower checks below this loop
|
||||
potential_conflicts.push({ defun, def, fname_def });
|
||||
symbols_of_interest.add(def.id);
|
||||
symbols_of_interest.add(fname_def.id);
|
||||
defuns_of_interest.add(defun);
|
||||
}
|
||||
}
|
||||
|
||||
// linearize all symbols, and locate defs that are read after the defun
|
||||
if (potential_conflicts.length) {
|
||||
// All "symbols of interest", that is, defuns or defs, that we found.
|
||||
// These are placed in order so we can check which is after which.
|
||||
const found_symbols = [];
|
||||
// Indices of `found_symbols` which are writes
|
||||
const found_symbol_writes = new Set();
|
||||
// Defun ranges are recorded because we don't care if a function uses the def internally
|
||||
const defun_ranges = new Map();
|
||||
|
||||
let tw;
|
||||
parent.walk((tw = new TreeWalker((node, descend) => {
|
||||
if (node instanceof AST_Defun && defuns_of_interest.has(node)) {
|
||||
const start = found_symbols.length;
|
||||
descend();
|
||||
const end = found_symbols.length;
|
||||
|
||||
defun_ranges.set(node, { start, end });
|
||||
return true;
|
||||
}
|
||||
// if we found a defun on the list, mark IN_DEFUN=id and descend
|
||||
|
||||
if (node instanceof AST_Symbol && node.thedef) {
|
||||
const id = node.definition().id;
|
||||
if (symbols_of_interest.has(id)) {
|
||||
if (node instanceof AST_SymbolDeclaration || is_lhs(node, tw)) {
|
||||
found_symbol_writes.add(found_symbols.length);
|
||||
}
|
||||
found_symbols.push(id);
|
||||
}
|
||||
}
|
||||
})));
|
||||
|
||||
for (const { def, defun, fname_def } of potential_conflicts) {
|
||||
const defun_range = defun_ranges.get(defun);
|
||||
|
||||
// find the index in `found_symbols`, with some special rules:
|
||||
const find = (sym_id, starting_at = 0, must_be_write = false) => {
|
||||
let index = starting_at;
|
||||
|
||||
for (;;) {
|
||||
index = found_symbols.indexOf(sym_id, index);
|
||||
|
||||
if (index === -1) {
|
||||
break;
|
||||
} else if (index >= defun_range.start && index < defun_range.end) {
|
||||
index = defun_range.end;
|
||||
continue;
|
||||
} else if (must_be_write && !found_symbol_writes.has(index)) {
|
||||
index++;
|
||||
continue;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return index;
|
||||
};
|
||||
|
||||
const read_defun_at = find(fname_def.id);
|
||||
const wrote_def_at = find(def.id, read_defun_at + 1, true);
|
||||
|
||||
const wrote_def_after_reading_defun = read_defun_at != -1 && wrote_def_at != -1 && wrote_def_at > read_defun_at;
|
||||
|
||||
if (wrote_def_after_reading_defun) {
|
||||
def.fixed = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def_reduce_vars(AST_Lambda, mark_lambda);
|
||||
|
||||
def_reduce_vars(AST_Do, function(tw, descend, compressor) {
|
||||
reset_block_variables(compressor, this);
|
||||
const saved_loop = tw.in_loop;
|
||||
tw.in_loop = this;
|
||||
push(tw);
|
||||
this.body.walk(tw);
|
||||
if (has_break_or_continue(this)) {
|
||||
pop(tw);
|
||||
push(tw);
|
||||
}
|
||||
this.condition.walk(tw);
|
||||
pop(tw);
|
||||
tw.in_loop = saved_loop;
|
||||
return true;
|
||||
});
|
||||
|
||||
def_reduce_vars(AST_For, function(tw, descend, compressor) {
|
||||
reset_block_variables(compressor, this);
|
||||
if (this.init) this.init.walk(tw);
|
||||
const saved_loop = tw.in_loop;
|
||||
tw.in_loop = this;
|
||||
push(tw);
|
||||
if (this.condition) this.condition.walk(tw);
|
||||
this.body.walk(tw);
|
||||
if (this.step) {
|
||||
if (has_break_or_continue(this)) {
|
||||
pop(tw);
|
||||
push(tw);
|
||||
}
|
||||
this.step.walk(tw);
|
||||
}
|
||||
pop(tw);
|
||||
tw.in_loop = saved_loop;
|
||||
return true;
|
||||
});
|
||||
|
||||
def_reduce_vars(AST_ForIn, function(tw, descend, compressor) {
|
||||
reset_block_variables(compressor, this);
|
||||
suppress(this.init);
|
||||
this.object.walk(tw);
|
||||
const saved_loop = tw.in_loop;
|
||||
tw.in_loop = this;
|
||||
push(tw);
|
||||
this.body.walk(tw);
|
||||
pop(tw);
|
||||
tw.in_loop = saved_loop;
|
||||
return true;
|
||||
});
|
||||
|
||||
def_reduce_vars(AST_If, function(tw) {
|
||||
this.condition.walk(tw);
|
||||
push(tw);
|
||||
this.body.walk(tw);
|
||||
pop(tw);
|
||||
if (this.alternative) {
|
||||
push(tw);
|
||||
this.alternative.walk(tw);
|
||||
pop(tw);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
def_reduce_vars(AST_LabeledStatement, function(tw) {
|
||||
push(tw);
|
||||
this.body.walk(tw);
|
||||
pop(tw);
|
||||
return true;
|
||||
});
|
||||
|
||||
def_reduce_vars(AST_SymbolCatch, function() {
|
||||
this.definition().fixed = false;
|
||||
});
|
||||
|
||||
def_reduce_vars(AST_SymbolRef, function(tw, descend, compressor) {
|
||||
var d = this.definition();
|
||||
d.references.push(this);
|
||||
if (d.references.length == 1
|
||||
&& !d.fixed
|
||||
&& d.orig[0] instanceof AST_SymbolDefun) {
|
||||
tw.loop_ids.set(d.id, tw.in_loop);
|
||||
}
|
||||
var fixed_value;
|
||||
if (d.fixed === undefined || !safe_to_read(tw, d)) {
|
||||
d.fixed = false;
|
||||
} else if (d.fixed) {
|
||||
fixed_value = this.fixed_value();
|
||||
if (
|
||||
fixed_value instanceof AST_Lambda
|
||||
&& is_recursive_ref(tw, d)
|
||||
) {
|
||||
d.recursive_refs++;
|
||||
} else if (fixed_value
|
||||
&& !compressor.exposed(d)
|
||||
&& ref_once(tw, compressor, d)
|
||||
) {
|
||||
d.single_use =
|
||||
fixed_value instanceof AST_Lambda && !fixed_value.pinned()
|
||||
|| fixed_value instanceof AST_Class
|
||||
|| d.scope === this.scope && fixed_value.is_constant_expression();
|
||||
} else {
|
||||
d.single_use = false;
|
||||
}
|
||||
if (is_modified(compressor, tw, this, fixed_value, 0, is_immutable(fixed_value))) {
|
||||
if (d.single_use) {
|
||||
d.single_use = "m";
|
||||
} else {
|
||||
d.fixed = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
mark_escaped(tw, d, this.scope, this, fixed_value, 0, 1);
|
||||
});
|
||||
|
||||
def_reduce_vars(AST_Toplevel, function(tw, descend, compressor) {
|
||||
this.globals.forEach(function(def) {
|
||||
reset_def(compressor, def);
|
||||
});
|
||||
reset_variables(tw, compressor, this);
|
||||
descend();
|
||||
handle_defined_after_hoist(this);
|
||||
return true;
|
||||
});
|
||||
|
||||
def_reduce_vars(AST_Try, function(tw, descend, compressor) {
|
||||
reset_block_variables(compressor, this);
|
||||
push(tw);
|
||||
this.body.walk(tw);
|
||||
pop(tw);
|
||||
if (this.bcatch) {
|
||||
push(tw);
|
||||
this.bcatch.walk(tw);
|
||||
pop(tw);
|
||||
}
|
||||
if (this.bfinally) this.bfinally.walk(tw);
|
||||
return true;
|
||||
});
|
||||
|
||||
def_reduce_vars(AST_Unary, function(tw) {
|
||||
var node = this;
|
||||
if (node.operator !== "++" && node.operator !== "--") return;
|
||||
var exp = node.expression;
|
||||
if (!(exp instanceof AST_SymbolRef)) return;
|
||||
var def = exp.definition();
|
||||
var safe = safe_to_assign(tw, def, exp.scope, true);
|
||||
def.assignments++;
|
||||
if (!safe) return;
|
||||
var fixed = def.fixed;
|
||||
if (!fixed) return;
|
||||
def.references.push(exp);
|
||||
def.chained = true;
|
||||
def.fixed = function() {
|
||||
return make_node(AST_Binary, node, {
|
||||
operator: node.operator.slice(0, -1),
|
||||
left: make_node(AST_UnaryPrefix, node, {
|
||||
operator: "+",
|
||||
expression: fixed instanceof AST_Node ? fixed : fixed()
|
||||
}),
|
||||
right: make_node(AST_Number, node, {
|
||||
value: 1
|
||||
})
|
||||
});
|
||||
};
|
||||
mark(tw, def, true);
|
||||
return true;
|
||||
});
|
||||
|
||||
def_reduce_vars(AST_VarDef, function(tw, descend) {
|
||||
var node = this;
|
||||
if (node.name instanceof AST_Destructuring) {
|
||||
suppress(node.name);
|
||||
return;
|
||||
}
|
||||
var d = node.name.definition();
|
||||
if (node.value) {
|
||||
if (safe_to_assign(tw, d, node.name.scope, node.value)) {
|
||||
d.fixed = function() {
|
||||
return node.value;
|
||||
};
|
||||
tw.loop_ids.set(d.id, tw.in_loop);
|
||||
mark(tw, d, false);
|
||||
descend();
|
||||
mark(tw, d, true);
|
||||
return true;
|
||||
} else {
|
||||
d.fixed = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
def_reduce_vars(AST_While, function(tw, descend, compressor) {
|
||||
reset_block_variables(compressor, this);
|
||||
const saved_loop = tw.in_loop;
|
||||
tw.in_loop = this;
|
||||
push(tw);
|
||||
descend();
|
||||
pop(tw);
|
||||
tw.in_loop = saved_loop;
|
||||
return true;
|
||||
});
|
1505
my-app/node_modules/terser/lib/compress/tighten-body.js
generated
vendored
Executable file
1505
my-app/node_modules/terser/lib/compress/tighten-body.js
generated
vendored
Executable file
File diff suppressed because it is too large
Load diff
287
my-app/node_modules/terser/lib/equivalent-to.js
generated
vendored
Executable file
287
my-app/node_modules/terser/lib/equivalent-to.js
generated
vendored
Executable file
|
@ -0,0 +1,287 @@
|
|||
import {
|
||||
AST_Array,
|
||||
AST_Atom,
|
||||
AST_Await,
|
||||
AST_BigInt,
|
||||
AST_Binary,
|
||||
AST_Block,
|
||||
AST_Call,
|
||||
AST_Catch,
|
||||
AST_Chain,
|
||||
AST_Class,
|
||||
AST_ClassProperty,
|
||||
AST_ConciseMethod,
|
||||
AST_Conditional,
|
||||
AST_Debugger,
|
||||
AST_Definitions,
|
||||
AST_Destructuring,
|
||||
AST_Directive,
|
||||
AST_Do,
|
||||
AST_Dot,
|
||||
AST_DotHash,
|
||||
AST_EmptyStatement,
|
||||
AST_Expansion,
|
||||
AST_Export,
|
||||
AST_Finally,
|
||||
AST_For,
|
||||
AST_ForIn,
|
||||
AST_ForOf,
|
||||
AST_If,
|
||||
AST_Import,
|
||||
AST_ImportMeta,
|
||||
AST_Jump,
|
||||
AST_LabeledStatement,
|
||||
AST_Lambda,
|
||||
AST_LoopControl,
|
||||
AST_NameMapping,
|
||||
AST_NewTarget,
|
||||
AST_Node,
|
||||
AST_Number,
|
||||
AST_Object,
|
||||
AST_ObjectGetter,
|
||||
AST_ObjectKeyVal,
|
||||
AST_ObjectProperty,
|
||||
AST_ObjectSetter,
|
||||
AST_PrefixedTemplateString,
|
||||
AST_PropAccess,
|
||||
AST_RegExp,
|
||||
AST_Sequence,
|
||||
AST_SimpleStatement,
|
||||
AST_String,
|
||||
AST_Super,
|
||||
AST_Switch,
|
||||
AST_SwitchBranch,
|
||||
AST_Symbol,
|
||||
AST_TemplateSegment,
|
||||
AST_TemplateString,
|
||||
AST_This,
|
||||
AST_Toplevel,
|
||||
AST_Try,
|
||||
AST_Unary,
|
||||
AST_VarDef,
|
||||
AST_While,
|
||||
AST_With,
|
||||
AST_Yield
|
||||
} from "./ast.js";
|
||||
|
||||
const shallow_cmp = (node1, node2) => {
|
||||
return (
|
||||
node1 === null && node2 === null
|
||||
|| node1.TYPE === node2.TYPE && node1.shallow_cmp(node2)
|
||||
);
|
||||
};
|
||||
|
||||
export const equivalent_to = (tree1, tree2) => {
|
||||
if (!shallow_cmp(tree1, tree2)) return false;
|
||||
const walk_1_state = [tree1];
|
||||
const walk_2_state = [tree2];
|
||||
|
||||
const walk_1_push = walk_1_state.push.bind(walk_1_state);
|
||||
const walk_2_push = walk_2_state.push.bind(walk_2_state);
|
||||
|
||||
while (walk_1_state.length && walk_2_state.length) {
|
||||
const node_1 = walk_1_state.pop();
|
||||
const node_2 = walk_2_state.pop();
|
||||
|
||||
if (!shallow_cmp(node_1, node_2)) return false;
|
||||
|
||||
node_1._children_backwards(walk_1_push);
|
||||
node_2._children_backwards(walk_2_push);
|
||||
|
||||
if (walk_1_state.length !== walk_2_state.length) {
|
||||
// Different number of children
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return walk_1_state.length == 0 && walk_2_state.length == 0;
|
||||
};
|
||||
|
||||
const pass_through = () => true;
|
||||
|
||||
AST_Node.prototype.shallow_cmp = function () {
|
||||
throw new Error("did not find a shallow_cmp function for " + this.constructor.name);
|
||||
};
|
||||
|
||||
AST_Debugger.prototype.shallow_cmp = pass_through;
|
||||
|
||||
AST_Directive.prototype.shallow_cmp = function(other) {
|
||||
return this.value === other.value;
|
||||
};
|
||||
|
||||
AST_SimpleStatement.prototype.shallow_cmp = pass_through;
|
||||
|
||||
AST_Block.prototype.shallow_cmp = pass_through;
|
||||
|
||||
AST_EmptyStatement.prototype.shallow_cmp = pass_through;
|
||||
|
||||
AST_LabeledStatement.prototype.shallow_cmp = function(other) {
|
||||
return this.label.name === other.label.name;
|
||||
};
|
||||
|
||||
AST_Do.prototype.shallow_cmp = pass_through;
|
||||
|
||||
AST_While.prototype.shallow_cmp = pass_through;
|
||||
|
||||
AST_For.prototype.shallow_cmp = function(other) {
|
||||
return (this.init == null ? other.init == null : this.init === other.init) && (this.condition == null ? other.condition == null : this.condition === other.condition) && (this.step == null ? other.step == null : this.step === other.step);
|
||||
};
|
||||
|
||||
AST_ForIn.prototype.shallow_cmp = pass_through;
|
||||
|
||||
AST_ForOf.prototype.shallow_cmp = pass_through;
|
||||
|
||||
AST_With.prototype.shallow_cmp = pass_through;
|
||||
|
||||
AST_Toplevel.prototype.shallow_cmp = pass_through;
|
||||
|
||||
AST_Expansion.prototype.shallow_cmp = pass_through;
|
||||
|
||||
AST_Lambda.prototype.shallow_cmp = function(other) {
|
||||
return this.is_generator === other.is_generator && this.async === other.async;
|
||||
};
|
||||
|
||||
AST_Destructuring.prototype.shallow_cmp = function(other) {
|
||||
return this.is_array === other.is_array;
|
||||
};
|
||||
|
||||
AST_PrefixedTemplateString.prototype.shallow_cmp = pass_through;
|
||||
|
||||
AST_TemplateString.prototype.shallow_cmp = pass_through;
|
||||
|
||||
AST_TemplateSegment.prototype.shallow_cmp = function(other) {
|
||||
return this.value === other.value;
|
||||
};
|
||||
|
||||
AST_Jump.prototype.shallow_cmp = pass_through;
|
||||
|
||||
AST_LoopControl.prototype.shallow_cmp = pass_through;
|
||||
|
||||
AST_Await.prototype.shallow_cmp = pass_through;
|
||||
|
||||
AST_Yield.prototype.shallow_cmp = function(other) {
|
||||
return this.is_star === other.is_star;
|
||||
};
|
||||
|
||||
AST_If.prototype.shallow_cmp = function(other) {
|
||||
return this.alternative == null ? other.alternative == null : this.alternative === other.alternative;
|
||||
};
|
||||
|
||||
AST_Switch.prototype.shallow_cmp = pass_through;
|
||||
|
||||
AST_SwitchBranch.prototype.shallow_cmp = pass_through;
|
||||
|
||||
AST_Try.prototype.shallow_cmp = function(other) {
|
||||
return (this.body === other.body) && (this.bcatch == null ? other.bcatch == null : this.bcatch === other.bcatch) && (this.bfinally == null ? other.bfinally == null : this.bfinally === other.bfinally);
|
||||
};
|
||||
|
||||
AST_Catch.prototype.shallow_cmp = function(other) {
|
||||
return this.argname == null ? other.argname == null : this.argname === other.argname;
|
||||
};
|
||||
|
||||
AST_Finally.prototype.shallow_cmp = pass_through;
|
||||
|
||||
AST_Definitions.prototype.shallow_cmp = pass_through;
|
||||
|
||||
AST_VarDef.prototype.shallow_cmp = function(other) {
|
||||
return this.value == null ? other.value == null : this.value === other.value;
|
||||
};
|
||||
|
||||
AST_NameMapping.prototype.shallow_cmp = pass_through;
|
||||
|
||||
AST_Import.prototype.shallow_cmp = function(other) {
|
||||
return (this.imported_name == null ? other.imported_name == null : this.imported_name === other.imported_name) && (this.imported_names == null ? other.imported_names == null : this.imported_names === other.imported_names);
|
||||
};
|
||||
|
||||
AST_ImportMeta.prototype.shallow_cmp = pass_through;
|
||||
|
||||
AST_Export.prototype.shallow_cmp = function(other) {
|
||||
return (this.exported_definition == null ? other.exported_definition == null : this.exported_definition === other.exported_definition) && (this.exported_value == null ? other.exported_value == null : this.exported_value === other.exported_value) && (this.exported_names == null ? other.exported_names == null : this.exported_names === other.exported_names) && this.module_name === other.module_name && this.is_default === other.is_default;
|
||||
};
|
||||
|
||||
AST_Call.prototype.shallow_cmp = pass_through;
|
||||
|
||||
AST_Sequence.prototype.shallow_cmp = pass_through;
|
||||
|
||||
AST_PropAccess.prototype.shallow_cmp = pass_through;
|
||||
|
||||
AST_Chain.prototype.shallow_cmp = pass_through;
|
||||
|
||||
AST_Dot.prototype.shallow_cmp = function(other) {
|
||||
return this.property === other.property;
|
||||
};
|
||||
|
||||
AST_DotHash.prototype.shallow_cmp = function(other) {
|
||||
return this.property === other.property;
|
||||
};
|
||||
|
||||
AST_Unary.prototype.shallow_cmp = function(other) {
|
||||
return this.operator === other.operator;
|
||||
};
|
||||
|
||||
AST_Binary.prototype.shallow_cmp = function(other) {
|
||||
return this.operator === other.operator;
|
||||
};
|
||||
|
||||
AST_Conditional.prototype.shallow_cmp = pass_through;
|
||||
|
||||
AST_Array.prototype.shallow_cmp = pass_through;
|
||||
|
||||
AST_Object.prototype.shallow_cmp = pass_through;
|
||||
|
||||
AST_ObjectProperty.prototype.shallow_cmp = pass_through;
|
||||
|
||||
AST_ObjectKeyVal.prototype.shallow_cmp = function(other) {
|
||||
return this.key === other.key;
|
||||
};
|
||||
|
||||
AST_ObjectSetter.prototype.shallow_cmp = function(other) {
|
||||
return this.static === other.static;
|
||||
};
|
||||
|
||||
AST_ObjectGetter.prototype.shallow_cmp = function(other) {
|
||||
return this.static === other.static;
|
||||
};
|
||||
|
||||
AST_ConciseMethod.prototype.shallow_cmp = function(other) {
|
||||
return this.static === other.static && this.is_generator === other.is_generator && this.async === other.async;
|
||||
};
|
||||
|
||||
AST_Class.prototype.shallow_cmp = function(other) {
|
||||
return (this.name == null ? other.name == null : this.name === other.name) && (this.extends == null ? other.extends == null : this.extends === other.extends);
|
||||
};
|
||||
|
||||
AST_ClassProperty.prototype.shallow_cmp = function(other) {
|
||||
return this.static === other.static;
|
||||
};
|
||||
|
||||
AST_Symbol.prototype.shallow_cmp = function(other) {
|
||||
return this.name === other.name;
|
||||
};
|
||||
|
||||
AST_NewTarget.prototype.shallow_cmp = pass_through;
|
||||
|
||||
AST_This.prototype.shallow_cmp = pass_through;
|
||||
|
||||
AST_Super.prototype.shallow_cmp = pass_through;
|
||||
|
||||
AST_String.prototype.shallow_cmp = function(other) {
|
||||
return this.value === other.value;
|
||||
};
|
||||
|
||||
AST_Number.prototype.shallow_cmp = function(other) {
|
||||
return this.value === other.value;
|
||||
};
|
||||
|
||||
AST_BigInt.prototype.shallow_cmp = function(other) {
|
||||
return this.value === other.value;
|
||||
};
|
||||
|
||||
AST_RegExp.prototype.shallow_cmp = function (other) {
|
||||
return (
|
||||
this.value.flags === other.value.flags
|
||||
&& this.value.source === other.value.source
|
||||
);
|
||||
};
|
||||
|
||||
AST_Atom.prototype.shallow_cmp = pass_through;
|
382
my-app/node_modules/terser/lib/minify.js
generated
vendored
Executable file
382
my-app/node_modules/terser/lib/minify.js
generated
vendored
Executable file
|
@ -0,0 +1,382 @@
|
|||
"use strict";
|
||||
/* eslint-env browser, es6, node */
|
||||
|
||||
import {
|
||||
defaults,
|
||||
map_from_object,
|
||||
map_to_object,
|
||||
HOP,
|
||||
} from "./utils/index.js";
|
||||
import { AST_Toplevel, AST_Node, walk, AST_Scope } from "./ast.js";
|
||||
import { parse } from "./parse.js";
|
||||
import { OutputStream } from "./output.js";
|
||||
import { Compressor } from "./compress/index.js";
|
||||
import { base54 } from "./scope.js";
|
||||
import { SourceMap } from "./sourcemap.js";
|
||||
import {
|
||||
mangle_properties,
|
||||
mangle_private_properties,
|
||||
reserve_quoted_keys,
|
||||
find_annotated_props,
|
||||
} from "./propmangle.js";
|
||||
|
||||
// to/from base64 functions
|
||||
// Prefer built-in Buffer, if available, then use hack
|
||||
// https://developer.mozilla.org/en-US/docs/Glossary/Base64#The_Unicode_Problem
|
||||
var to_ascii = typeof Buffer !== "undefined"
|
||||
? (b64) => Buffer.from(b64, "base64").toString()
|
||||
: (b64) => decodeURIComponent(escape(atob(b64)));
|
||||
var to_base64 = typeof Buffer !== "undefined"
|
||||
? (str) => Buffer.from(str).toString("base64")
|
||||
: (str) => btoa(unescape(encodeURIComponent(str)));
|
||||
|
||||
function read_source_map(code) {
|
||||
var match = /(?:^|[^.])\/\/# sourceMappingURL=data:application\/json(;[\w=-]*)?;base64,([+/0-9A-Za-z]*=*)\s*$/.exec(code);
|
||||
if (!match) {
|
||||
console.warn("inline source map not found");
|
||||
return null;
|
||||
}
|
||||
return to_ascii(match[2]);
|
||||
}
|
||||
|
||||
function set_shorthand(name, options, keys) {
|
||||
if (options[name]) {
|
||||
keys.forEach(function(key) {
|
||||
if (options[key]) {
|
||||
if (typeof options[key] != "object") options[key] = {};
|
||||
if (!(name in options[key])) options[key][name] = options[name];
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function init_cache(cache) {
|
||||
if (!cache) return;
|
||||
if (!("props" in cache)) {
|
||||
cache.props = new Map();
|
||||
} else if (!(cache.props instanceof Map)) {
|
||||
cache.props = map_from_object(cache.props);
|
||||
}
|
||||
}
|
||||
|
||||
function cache_to_json(cache) {
|
||||
return {
|
||||
props: map_to_object(cache.props)
|
||||
};
|
||||
}
|
||||
|
||||
function log_input(files, options, fs, debug_folder) {
|
||||
if (!(fs && fs.writeFileSync && fs.mkdirSync)) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
fs.mkdirSync(debug_folder);
|
||||
} catch (e) {
|
||||
if (e.code !== "EEXIST") throw e;
|
||||
}
|
||||
|
||||
const log_path = `${debug_folder}/terser-debug-${(Math.random() * 9999999) | 0}.log`;
|
||||
|
||||
options = options || {};
|
||||
|
||||
const options_str = JSON.stringify(options, (_key, thing) => {
|
||||
if (typeof thing === "function") return "[Function " + thing.toString() + "]";
|
||||
if (thing instanceof RegExp) return "[RegExp " + thing.toString() + "]";
|
||||
return thing;
|
||||
}, 4);
|
||||
|
||||
const files_str = (file) => {
|
||||
if (typeof file === "object" && options.parse && options.parse.spidermonkey) {
|
||||
return JSON.stringify(file, null, 2);
|
||||
} else if (typeof file === "object") {
|
||||
return Object.keys(file)
|
||||
.map((key) => key + ": " + files_str(file[key]))
|
||||
.join("\n\n");
|
||||
} else if (typeof file === "string") {
|
||||
return "```\n" + file + "\n```";
|
||||
} else {
|
||||
return file; // What do?
|
||||
}
|
||||
};
|
||||
|
||||
fs.writeFileSync(log_path, "Options: \n" + options_str + "\n\nInput files:\n\n" + files_str(files) + "\n");
|
||||
}
|
||||
|
||||
async function minify(files, options, _fs_module) {
|
||||
if (
|
||||
_fs_module
|
||||
&& typeof process === "object"
|
||||
&& process.env
|
||||
&& typeof process.env.TERSER_DEBUG_DIR === "string"
|
||||
) {
|
||||
log_input(files, options, _fs_module, process.env.TERSER_DEBUG_DIR);
|
||||
}
|
||||
|
||||
options = defaults(options, {
|
||||
compress: {},
|
||||
ecma: undefined,
|
||||
enclose: false,
|
||||
ie8: false,
|
||||
keep_classnames: undefined,
|
||||
keep_fnames: false,
|
||||
mangle: {},
|
||||
module: false,
|
||||
nameCache: null,
|
||||
output: null,
|
||||
format: null,
|
||||
parse: {},
|
||||
rename: undefined,
|
||||
safari10: false,
|
||||
sourceMap: false,
|
||||
spidermonkey: false,
|
||||
timings: false,
|
||||
toplevel: false,
|
||||
warnings: false,
|
||||
wrap: false,
|
||||
}, true);
|
||||
|
||||
var timings = options.timings && {
|
||||
start: Date.now()
|
||||
};
|
||||
if (options.keep_classnames === undefined) {
|
||||
options.keep_classnames = options.keep_fnames;
|
||||
}
|
||||
if (options.rename === undefined) {
|
||||
options.rename = options.compress && options.mangle;
|
||||
}
|
||||
if (options.output && options.format) {
|
||||
throw new Error("Please only specify either output or format option, preferrably format.");
|
||||
}
|
||||
options.format = options.format || options.output || {};
|
||||
set_shorthand("ecma", options, [ "parse", "compress", "format" ]);
|
||||
set_shorthand("ie8", options, [ "compress", "mangle", "format" ]);
|
||||
set_shorthand("keep_classnames", options, [ "compress", "mangle" ]);
|
||||
set_shorthand("keep_fnames", options, [ "compress", "mangle" ]);
|
||||
set_shorthand("module", options, [ "parse", "compress", "mangle" ]);
|
||||
set_shorthand("safari10", options, [ "mangle", "format" ]);
|
||||
set_shorthand("toplevel", options, [ "compress", "mangle" ]);
|
||||
set_shorthand("warnings", options, [ "compress" ]); // legacy
|
||||
var quoted_props;
|
||||
if (options.mangle) {
|
||||
options.mangle = defaults(options.mangle, {
|
||||
cache: options.nameCache && (options.nameCache.vars || {}),
|
||||
eval: false,
|
||||
ie8: false,
|
||||
keep_classnames: false,
|
||||
keep_fnames: false,
|
||||
module: false,
|
||||
nth_identifier: base54,
|
||||
properties: false,
|
||||
reserved: [],
|
||||
safari10: false,
|
||||
toplevel: false,
|
||||
}, true);
|
||||
if (options.mangle.properties) {
|
||||
if (typeof options.mangle.properties != "object") {
|
||||
options.mangle.properties = {};
|
||||
}
|
||||
if (options.mangle.properties.keep_quoted) {
|
||||
quoted_props = options.mangle.properties.reserved;
|
||||
if (!Array.isArray(quoted_props)) quoted_props = [];
|
||||
options.mangle.properties.reserved = quoted_props;
|
||||
}
|
||||
if (options.nameCache && !("cache" in options.mangle.properties)) {
|
||||
options.mangle.properties.cache = options.nameCache.props || {};
|
||||
}
|
||||
}
|
||||
init_cache(options.mangle.cache);
|
||||
init_cache(options.mangle.properties.cache);
|
||||
}
|
||||
if (options.sourceMap) {
|
||||
options.sourceMap = defaults(options.sourceMap, {
|
||||
asObject: false,
|
||||
content: null,
|
||||
filename: null,
|
||||
includeSources: false,
|
||||
root: null,
|
||||
url: null,
|
||||
}, true);
|
||||
}
|
||||
|
||||
// -- Parse phase --
|
||||
if (timings) timings.parse = Date.now();
|
||||
var toplevel;
|
||||
if (files instanceof AST_Toplevel) {
|
||||
toplevel = files;
|
||||
} else {
|
||||
if (typeof files == "string" || (options.parse.spidermonkey && !Array.isArray(files))) {
|
||||
files = [ files ];
|
||||
}
|
||||
options.parse = options.parse || {};
|
||||
options.parse.toplevel = null;
|
||||
|
||||
if (options.parse.spidermonkey) {
|
||||
options.parse.toplevel = AST_Node.from_mozilla_ast(Object.keys(files).reduce(function(toplevel, name) {
|
||||
if (!toplevel) return files[name];
|
||||
toplevel.body = toplevel.body.concat(files[name].body);
|
||||
return toplevel;
|
||||
}, null));
|
||||
} else {
|
||||
delete options.parse.spidermonkey;
|
||||
|
||||
for (var name in files) if (HOP(files, name)) {
|
||||
options.parse.filename = name;
|
||||
options.parse.toplevel = parse(files[name], options.parse);
|
||||
if (options.sourceMap && options.sourceMap.content == "inline") {
|
||||
if (Object.keys(files).length > 1)
|
||||
throw new Error("inline source map only works with singular input");
|
||||
options.sourceMap.content = read_source_map(files[name]);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (options.parse.toplevel === null) {
|
||||
throw new Error("no source file given");
|
||||
}
|
||||
|
||||
toplevel = options.parse.toplevel;
|
||||
}
|
||||
if (quoted_props && options.mangle.properties.keep_quoted !== "strict") {
|
||||
reserve_quoted_keys(toplevel, quoted_props);
|
||||
}
|
||||
var annotated_props;
|
||||
if (options.mangle && options.mangle.properties) {
|
||||
annotated_props = find_annotated_props(toplevel);
|
||||
}
|
||||
if (options.wrap) {
|
||||
toplevel = toplevel.wrap_commonjs(options.wrap);
|
||||
}
|
||||
if (options.enclose) {
|
||||
toplevel = toplevel.wrap_enclose(options.enclose);
|
||||
}
|
||||
if (timings) timings.rename = Date.now();
|
||||
// disable rename on harmony due to expand_names bug in for-of loops
|
||||
// https://github.com/mishoo/UglifyJS2/issues/2794
|
||||
if (0 && options.rename) {
|
||||
toplevel.figure_out_scope(options.mangle);
|
||||
toplevel.expand_names(options.mangle);
|
||||
}
|
||||
|
||||
// -- Compress phase --
|
||||
if (timings) timings.compress = Date.now();
|
||||
if (options.compress) {
|
||||
toplevel = new Compressor(options.compress, {
|
||||
mangle_options: options.mangle
|
||||
}).compress(toplevel);
|
||||
}
|
||||
|
||||
// -- Mangle phase --
|
||||
if (timings) timings.scope = Date.now();
|
||||
if (options.mangle) toplevel.figure_out_scope(options.mangle);
|
||||
if (timings) timings.mangle = Date.now();
|
||||
if (options.mangle) {
|
||||
toplevel.compute_char_frequency(options.mangle);
|
||||
toplevel.mangle_names(options.mangle);
|
||||
toplevel = mangle_private_properties(toplevel, options.mangle);
|
||||
}
|
||||
if (timings) timings.properties = Date.now();
|
||||
if (options.mangle && options.mangle.properties) {
|
||||
toplevel = mangle_properties(toplevel, options.mangle.properties, annotated_props);
|
||||
}
|
||||
|
||||
// Format phase
|
||||
if (timings) timings.format = Date.now();
|
||||
var result = {};
|
||||
if (options.format.ast) {
|
||||
result.ast = toplevel;
|
||||
}
|
||||
if (options.format.spidermonkey) {
|
||||
result.ast = toplevel.to_mozilla_ast();
|
||||
}
|
||||
let format_options;
|
||||
if (!HOP(options.format, "code") || options.format.code) {
|
||||
// Make a shallow copy so that we can modify without mutating the user's input.
|
||||
format_options = {...options.format};
|
||||
if (!format_options.ast) {
|
||||
// Destroy stuff to save RAM. (unless the deprecated `ast` option is on)
|
||||
format_options._destroy_ast = true;
|
||||
|
||||
walk(toplevel, node => {
|
||||
if (node instanceof AST_Scope) {
|
||||
node.variables = undefined;
|
||||
node.enclosed = undefined;
|
||||
node.parent_scope = undefined;
|
||||
}
|
||||
if (node.block_scope) {
|
||||
node.block_scope.variables = undefined;
|
||||
node.block_scope.enclosed = undefined;
|
||||
node.parent_scope = undefined;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (options.sourceMap) {
|
||||
if (options.sourceMap.includeSources && files instanceof AST_Toplevel) {
|
||||
throw new Error("original source content unavailable");
|
||||
}
|
||||
format_options.source_map = await SourceMap({
|
||||
file: options.sourceMap.filename,
|
||||
orig: options.sourceMap.content,
|
||||
root: options.sourceMap.root,
|
||||
files: options.sourceMap.includeSources ? files : null,
|
||||
});
|
||||
}
|
||||
delete format_options.ast;
|
||||
delete format_options.code;
|
||||
delete format_options.spidermonkey;
|
||||
var stream = OutputStream(format_options);
|
||||
toplevel.print(stream);
|
||||
result.code = stream.get();
|
||||
if (options.sourceMap) {
|
||||
Object.defineProperty(result, "map", {
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
get() {
|
||||
const map = format_options.source_map.getEncoded();
|
||||
return (result.map = options.sourceMap.asObject ? map : JSON.stringify(map));
|
||||
},
|
||||
set(value) {
|
||||
Object.defineProperty(result, "map", {
|
||||
value,
|
||||
writable: true,
|
||||
});
|
||||
}
|
||||
});
|
||||
result.decoded_map = format_options.source_map.getDecoded();
|
||||
if (options.sourceMap.url == "inline") {
|
||||
var sourceMap = typeof result.map === "object" ? JSON.stringify(result.map) : result.map;
|
||||
result.code += "\n//# sourceMappingURL=data:application/json;charset=utf-8;base64," + to_base64(sourceMap);
|
||||
} else if (options.sourceMap.url) {
|
||||
result.code += "\n//# sourceMappingURL=" + options.sourceMap.url;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (options.nameCache && options.mangle) {
|
||||
if (options.mangle.cache) options.nameCache.vars = cache_to_json(options.mangle.cache);
|
||||
if (options.mangle.properties && options.mangle.properties.cache) {
|
||||
options.nameCache.props = cache_to_json(options.mangle.properties.cache);
|
||||
}
|
||||
}
|
||||
if (format_options && format_options.source_map) {
|
||||
format_options.source_map.destroy();
|
||||
}
|
||||
if (timings) {
|
||||
timings.end = Date.now();
|
||||
result.timings = {
|
||||
parse: 1e-3 * (timings.rename - timings.parse),
|
||||
rename: 1e-3 * (timings.compress - timings.rename),
|
||||
compress: 1e-3 * (timings.scope - timings.compress),
|
||||
scope: 1e-3 * (timings.mangle - timings.scope),
|
||||
mangle: 1e-3 * (timings.properties - timings.mangle),
|
||||
properties: 1e-3 * (timings.format - timings.properties),
|
||||
format: 1e-3 * (timings.end - timings.format),
|
||||
total: 1e-3 * (timings.end - timings.start)
|
||||
};
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
export {
|
||||
minify,
|
||||
to_ascii,
|
||||
};
|
1886
my-app/node_modules/terser/lib/mozilla-ast.js
generated
vendored
Executable file
1886
my-app/node_modules/terser/lib/mozilla-ast.js
generated
vendored
Executable file
File diff suppressed because it is too large
Load diff
2485
my-app/node_modules/terser/lib/output.js
generated
vendored
Executable file
2485
my-app/node_modules/terser/lib/output.js
generated
vendored
Executable file
File diff suppressed because it is too large
Load diff
3500
my-app/node_modules/terser/lib/parse.js
generated
vendored
Executable file
3500
my-app/node_modules/terser/lib/parse.js
generated
vendored
Executable file
File diff suppressed because one or more lines are too long
432
my-app/node_modules/terser/lib/propmangle.js
generated
vendored
Executable file
432
my-app/node_modules/terser/lib/propmangle.js
generated
vendored
Executable file
|
@ -0,0 +1,432 @@
|
|||
/***********************************************************************
|
||||
|
||||
A JavaScript tokenizer / parser / beautifier / compressor.
|
||||
https://github.com/mishoo/UglifyJS2
|
||||
|
||||
-------------------------------- (C) ---------------------------------
|
||||
|
||||
Author: Mihai Bazon
|
||||
<mihai.bazon@gmail.com>
|
||||
http://mihai.bazon.net/blog
|
||||
|
||||
Distributed under the BSD license:
|
||||
|
||||
Copyright 2012 (c) Mihai Bazon <mihai.bazon@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials
|
||||
provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
"use strict";
|
||||
/* global global, self */
|
||||
|
||||
import {
|
||||
defaults,
|
||||
push_uniq,
|
||||
has_annotation,
|
||||
clear_annotation,
|
||||
} from "./utils/index.js";
|
||||
import { base54 } from "./scope.js";
|
||||
import {
|
||||
AST_Binary,
|
||||
AST_Call,
|
||||
AST_ClassPrivateProperty,
|
||||
AST_Conditional,
|
||||
AST_Dot,
|
||||
AST_DotHash,
|
||||
AST_ObjectKeyVal,
|
||||
AST_ObjectProperty,
|
||||
AST_PrivateMethod,
|
||||
AST_PrivateGetter,
|
||||
AST_PrivateSetter,
|
||||
AST_PrivateIn,
|
||||
AST_Sequence,
|
||||
AST_String,
|
||||
AST_Sub,
|
||||
TreeTransformer,
|
||||
TreeWalker,
|
||||
_KEY,
|
||||
_MANGLEPROP,
|
||||
|
||||
walk,
|
||||
} from "./ast.js";
|
||||
import { domprops } from "../tools/domprops.js";
|
||||
|
||||
function find_builtins(reserved) {
|
||||
domprops.forEach(add);
|
||||
|
||||
// Compatibility fix for some standard defined globals not defined on every js environment
|
||||
var new_globals = ["Symbol", "Map", "Promise", "Proxy", "Reflect", "Set", "WeakMap", "WeakSet"];
|
||||
var objects = {};
|
||||
var global_ref = typeof global === "object" ? global : self;
|
||||
|
||||
new_globals.forEach(function (new_global) {
|
||||
objects[new_global] = global_ref[new_global] || function() {};
|
||||
});
|
||||
|
||||
[
|
||||
"null",
|
||||
"true",
|
||||
"false",
|
||||
"NaN",
|
||||
"Infinity",
|
||||
"-Infinity",
|
||||
"undefined",
|
||||
].forEach(add);
|
||||
[ Object, Array, Function, Number,
|
||||
String, Boolean, Error, Math,
|
||||
Date, RegExp, objects.Symbol, ArrayBuffer,
|
||||
DataView, decodeURI, decodeURIComponent,
|
||||
encodeURI, encodeURIComponent, eval, EvalError,
|
||||
Float32Array, Float64Array, Int8Array, Int16Array,
|
||||
Int32Array, isFinite, isNaN, JSON, objects.Map, parseFloat,
|
||||
parseInt, objects.Promise, objects.Proxy, RangeError, ReferenceError,
|
||||
objects.Reflect, objects.Set, SyntaxError, TypeError, Uint8Array,
|
||||
Uint8ClampedArray, Uint16Array, Uint32Array, URIError,
|
||||
objects.WeakMap, objects.WeakSet
|
||||
].forEach(function(ctor) {
|
||||
Object.getOwnPropertyNames(ctor).map(add);
|
||||
if (ctor.prototype) {
|
||||
Object.getOwnPropertyNames(ctor.prototype).map(add);
|
||||
}
|
||||
});
|
||||
function add(name) {
|
||||
reserved.add(name);
|
||||
}
|
||||
}
|
||||
|
||||
function reserve_quoted_keys(ast, reserved) {
|
||||
function add(name) {
|
||||
push_uniq(reserved, name);
|
||||
}
|
||||
|
||||
ast.walk(new TreeWalker(function(node) {
|
||||
if (node instanceof AST_ObjectKeyVal && node.quote) {
|
||||
add(node.key);
|
||||
} else if (node instanceof AST_ObjectProperty && node.quote) {
|
||||
add(node.key.name);
|
||||
} else if (node instanceof AST_Sub) {
|
||||
addStrings(node.property, add);
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
function addStrings(node, add) {
|
||||
node.walk(new TreeWalker(function(node) {
|
||||
if (node instanceof AST_Sequence) {
|
||||
addStrings(node.tail_node(), add);
|
||||
} else if (node instanceof AST_String) {
|
||||
add(node.value);
|
||||
} else if (node instanceof AST_Conditional) {
|
||||
addStrings(node.consequent, add);
|
||||
addStrings(node.alternative, add);
|
||||
}
|
||||
return true;
|
||||
}));
|
||||
}
|
||||
|
||||
function mangle_private_properties(ast, options) {
|
||||
var cprivate = -1;
|
||||
var private_cache = new Map();
|
||||
var nth_identifier = options.nth_identifier || base54;
|
||||
|
||||
ast = ast.transform(new TreeTransformer(function(node) {
|
||||
if (
|
||||
node instanceof AST_ClassPrivateProperty
|
||||
|| node instanceof AST_PrivateMethod
|
||||
|| node instanceof AST_PrivateGetter
|
||||
|| node instanceof AST_PrivateSetter
|
||||
|| node instanceof AST_PrivateIn
|
||||
) {
|
||||
node.key.name = mangle_private(node.key.name);
|
||||
} else if (node instanceof AST_DotHash) {
|
||||
node.property = mangle_private(node.property);
|
||||
}
|
||||
}));
|
||||
return ast;
|
||||
|
||||
function mangle_private(name) {
|
||||
let mangled = private_cache.get(name);
|
||||
if (!mangled) {
|
||||
mangled = nth_identifier.get(++cprivate);
|
||||
private_cache.set(name, mangled);
|
||||
}
|
||||
|
||||
return mangled;
|
||||
}
|
||||
}
|
||||
|
||||
function find_annotated_props(ast) {
|
||||
var annotated_props = new Set();
|
||||
walk(ast, node => {
|
||||
if (
|
||||
node instanceof AST_ClassPrivateProperty
|
||||
|| node instanceof AST_PrivateMethod
|
||||
|| node instanceof AST_PrivateGetter
|
||||
|| node instanceof AST_PrivateSetter
|
||||
|| node instanceof AST_DotHash
|
||||
) {
|
||||
// handled by mangle_private_properties
|
||||
} else if (node instanceof AST_ObjectKeyVal) {
|
||||
if (typeof node.key == "string" && has_annotation(node, _MANGLEPROP)) {
|
||||
annotated_props.add(node.key);
|
||||
}
|
||||
} else if (node instanceof AST_ObjectProperty) {
|
||||
// setter or getter, since KeyVal is handled above
|
||||
if (has_annotation(node, _MANGLEPROP)) {
|
||||
annotated_props.add(node.key.name);
|
||||
}
|
||||
} else if (node instanceof AST_Dot) {
|
||||
if (has_annotation(node, _MANGLEPROP)) {
|
||||
annotated_props.add(node.property);
|
||||
}
|
||||
} else if (node instanceof AST_Sub) {
|
||||
if (node.property instanceof AST_String && has_annotation(node, _MANGLEPROP)) {
|
||||
annotated_props.add(node.property.value);
|
||||
}
|
||||
}
|
||||
});
|
||||
return annotated_props;
|
||||
}
|
||||
|
||||
function mangle_properties(ast, options, annotated_props = find_annotated_props(ast)) {
|
||||
options = defaults(options, {
|
||||
builtins: false,
|
||||
cache: null,
|
||||
debug: false,
|
||||
keep_quoted: false,
|
||||
nth_identifier: base54,
|
||||
only_cache: false,
|
||||
regex: null,
|
||||
reserved: null,
|
||||
undeclared: false,
|
||||
only_annotated: false,
|
||||
}, true);
|
||||
|
||||
var nth_identifier = options.nth_identifier;
|
||||
|
||||
var reserved_option = options.reserved;
|
||||
if (!Array.isArray(reserved_option)) reserved_option = [reserved_option];
|
||||
var reserved = new Set(reserved_option);
|
||||
if (!options.builtins) find_builtins(reserved);
|
||||
|
||||
var cname = -1;
|
||||
|
||||
var cache;
|
||||
if (options.cache) {
|
||||
cache = options.cache.props;
|
||||
} else {
|
||||
cache = new Map();
|
||||
}
|
||||
|
||||
var only_annotated = options.only_annotated;
|
||||
var regex = options.regex && new RegExp(options.regex);
|
||||
|
||||
// note debug is either false (disabled), or a string of the debug suffix to use (enabled).
|
||||
// note debug may be enabled as an empty string, which is falsey. Also treat passing 'true'
|
||||
// the same as passing an empty string.
|
||||
var debug = options.debug !== false;
|
||||
var debug_name_suffix;
|
||||
if (debug) {
|
||||
debug_name_suffix = (options.debug === true ? "" : options.debug);
|
||||
}
|
||||
|
||||
var names_to_mangle = new Set();
|
||||
var unmangleable = new Set();
|
||||
// Track each already-mangled name to prevent nth_identifier from generating
|
||||
// the same name.
|
||||
cache.forEach((mangled_name) => unmangleable.add(mangled_name));
|
||||
|
||||
var keep_quoted = !!options.keep_quoted;
|
||||
|
||||
// step 1: find candidates to mangle
|
||||
ast.walk(new TreeWalker(function(node) {
|
||||
if (
|
||||
node instanceof AST_ClassPrivateProperty
|
||||
|| node instanceof AST_PrivateMethod
|
||||
|| node instanceof AST_PrivateGetter
|
||||
|| node instanceof AST_PrivateSetter
|
||||
|| node instanceof AST_DotHash
|
||||
) {
|
||||
// handled by mangle_private_properties
|
||||
} else if (node instanceof AST_ObjectKeyVal) {
|
||||
if (typeof node.key == "string" && (!keep_quoted || !node.quote)) {
|
||||
add(node.key);
|
||||
}
|
||||
} else if (node instanceof AST_ObjectProperty) {
|
||||
// setter or getter, since KeyVal is handled above
|
||||
if (!keep_quoted || !node.quote) {
|
||||
add(node.key.name);
|
||||
}
|
||||
} else if (node instanceof AST_Dot) {
|
||||
var declared = !!options.undeclared;
|
||||
if (!declared) {
|
||||
var root = node;
|
||||
while (root.expression) {
|
||||
root = root.expression;
|
||||
}
|
||||
declared = !(root.thedef && root.thedef.undeclared);
|
||||
}
|
||||
if (declared &&
|
||||
(!keep_quoted || !node.quote)) {
|
||||
add(node.property);
|
||||
}
|
||||
} else if (node instanceof AST_Sub) {
|
||||
if (!keep_quoted) {
|
||||
addStrings(node.property, add);
|
||||
}
|
||||
} else if (node instanceof AST_Call
|
||||
&& node.expression.print_to_string() == "Object.defineProperty") {
|
||||
addStrings(node.args[1], add);
|
||||
} else if (node instanceof AST_Binary && node.operator === "in") {
|
||||
addStrings(node.left, add);
|
||||
} else if (node instanceof AST_String && has_annotation(node, _KEY)) {
|
||||
add(node.value);
|
||||
}
|
||||
}));
|
||||
|
||||
// step 2: transform the tree, renaming properties
|
||||
return ast.transform(new TreeTransformer(function(node) {
|
||||
if (
|
||||
node instanceof AST_ClassPrivateProperty
|
||||
|| node instanceof AST_PrivateMethod
|
||||
|| node instanceof AST_PrivateGetter
|
||||
|| node instanceof AST_PrivateSetter
|
||||
|| node instanceof AST_DotHash
|
||||
) {
|
||||
// handled by mangle_private_properties
|
||||
} else if (node instanceof AST_ObjectKeyVal) {
|
||||
if (typeof node.key == "string" && (!keep_quoted || !node.quote)) {
|
||||
node.key = mangle(node.key);
|
||||
}
|
||||
} else if (node instanceof AST_ObjectProperty) {
|
||||
// setter, getter, method or class field
|
||||
if (!keep_quoted || !node.quote) {
|
||||
node.key.name = mangle(node.key.name);
|
||||
}
|
||||
} else if (node instanceof AST_Dot) {
|
||||
if (!keep_quoted || !node.quote) {
|
||||
node.property = mangle(node.property);
|
||||
}
|
||||
} else if (!keep_quoted && node instanceof AST_Sub) {
|
||||
node.property = mangleStrings(node.property);
|
||||
} else if (node instanceof AST_Call
|
||||
&& node.expression.print_to_string() == "Object.defineProperty") {
|
||||
node.args[1] = mangleStrings(node.args[1]);
|
||||
} else if (node instanceof AST_Binary && node.operator === "in") {
|
||||
node.left = mangleStrings(node.left);
|
||||
} else if (node instanceof AST_String && has_annotation(node, _KEY)) {
|
||||
// Clear _KEY annotation to prevent double mangling
|
||||
clear_annotation(node, _KEY);
|
||||
node.value = mangle(node.value);
|
||||
}
|
||||
}));
|
||||
|
||||
// only function declarations after this line
|
||||
|
||||
function can_mangle(name) {
|
||||
if (unmangleable.has(name)) return false;
|
||||
if (reserved.has(name)) return false;
|
||||
if (options.only_cache) {
|
||||
return cache.has(name);
|
||||
}
|
||||
if (/^-?[0-9]+(\.[0-9]+)?(e[+-][0-9]+)?$/.test(name)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
function should_mangle(name) {
|
||||
if (only_annotated && !annotated_props.has(name)) return false;
|
||||
if (regex && !regex.test(name)) {
|
||||
return annotated_props.has(name);
|
||||
}
|
||||
if (reserved.has(name)) return false;
|
||||
return cache.has(name)
|
||||
|| names_to_mangle.has(name);
|
||||
}
|
||||
|
||||
function add(name) {
|
||||
if (can_mangle(name)) {
|
||||
names_to_mangle.add(name);
|
||||
}
|
||||
|
||||
if (!should_mangle(name)) {
|
||||
unmangleable.add(name);
|
||||
}
|
||||
}
|
||||
|
||||
function mangle(name) {
|
||||
if (!should_mangle(name)) {
|
||||
return name;
|
||||
}
|
||||
|
||||
var mangled = cache.get(name);
|
||||
if (!mangled) {
|
||||
if (debug) {
|
||||
// debug mode: use a prefix and suffix to preserve readability, e.g. o.foo -> o._$foo$NNN_.
|
||||
var debug_mangled = "_$" + name + "$" + debug_name_suffix + "_";
|
||||
|
||||
if (can_mangle(debug_mangled)) {
|
||||
mangled = debug_mangled;
|
||||
}
|
||||
}
|
||||
|
||||
// either debug mode is off, or it is on and we could not use the mangled name
|
||||
if (!mangled) {
|
||||
do {
|
||||
mangled = nth_identifier.get(++cname);
|
||||
} while (!can_mangle(mangled));
|
||||
}
|
||||
|
||||
cache.set(name, mangled);
|
||||
}
|
||||
return mangled;
|
||||
}
|
||||
|
||||
function mangleStrings(node) {
|
||||
return node.transform(new TreeTransformer(function(node) {
|
||||
if (node instanceof AST_Sequence) {
|
||||
var last = node.expressions.length - 1;
|
||||
node.expressions[last] = mangleStrings(node.expressions[last]);
|
||||
} else if (node instanceof AST_String) {
|
||||
// Clear _KEY annotation to prevent double mangling
|
||||
clear_annotation(node, _KEY);
|
||||
node.value = mangle(node.value);
|
||||
} else if (node instanceof AST_Conditional) {
|
||||
node.consequent = mangleStrings(node.consequent);
|
||||
node.alternative = mangleStrings(node.alternative);
|
||||
}
|
||||
return node;
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
export {
|
||||
reserve_quoted_keys,
|
||||
mangle_properties,
|
||||
mangle_private_properties,
|
||||
find_annotated_props,
|
||||
};
|
1066
my-app/node_modules/terser/lib/scope.js
generated
vendored
Executable file
1066
my-app/node_modules/terser/lib/scope.js
generated
vendored
Executable file
File diff suppressed because it is too large
Load diff
495
my-app/node_modules/terser/lib/size.js
generated
vendored
Executable file
495
my-app/node_modules/terser/lib/size.js
generated
vendored
Executable file
|
@ -0,0 +1,495 @@
|
|||
import {
|
||||
AST_Accessor,
|
||||
AST_Array,
|
||||
AST_Arrow,
|
||||
AST_Await,
|
||||
AST_BigInt,
|
||||
AST_Binary,
|
||||
AST_Block,
|
||||
AST_Break,
|
||||
AST_Call,
|
||||
AST_Case,
|
||||
AST_Class,
|
||||
AST_ClassStaticBlock,
|
||||
AST_ClassPrivateProperty,
|
||||
AST_ClassProperty,
|
||||
AST_ConciseMethod,
|
||||
AST_Conditional,
|
||||
AST_Const,
|
||||
AST_Continue,
|
||||
AST_Debugger,
|
||||
AST_Default,
|
||||
AST_Defun,
|
||||
AST_Destructuring,
|
||||
AST_Directive,
|
||||
AST_Do,
|
||||
AST_Dot,
|
||||
AST_DotHash,
|
||||
AST_EmptyStatement,
|
||||
AST_Expansion,
|
||||
AST_Export,
|
||||
AST_False,
|
||||
AST_For,
|
||||
AST_ForIn,
|
||||
AST_Function,
|
||||
AST_Hole,
|
||||
AST_If,
|
||||
AST_Import,
|
||||
AST_ImportMeta,
|
||||
AST_Infinity,
|
||||
AST_LabeledStatement,
|
||||
AST_Let,
|
||||
AST_NameMapping,
|
||||
AST_NaN,
|
||||
AST_New,
|
||||
AST_NewTarget,
|
||||
AST_Node,
|
||||
AST_Null,
|
||||
AST_Number,
|
||||
AST_Object,
|
||||
AST_ObjectKeyVal,
|
||||
AST_ObjectGetter,
|
||||
AST_ObjectSetter,
|
||||
AST_PrivateGetter,
|
||||
AST_PrivateMethod,
|
||||
AST_PrivateSetter,
|
||||
AST_PrivateIn,
|
||||
AST_RegExp,
|
||||
AST_Return,
|
||||
AST_Sequence,
|
||||
AST_String,
|
||||
AST_Sub,
|
||||
AST_Super,
|
||||
AST_Switch,
|
||||
AST_Symbol,
|
||||
AST_SymbolClassProperty,
|
||||
AST_SymbolExportForeign,
|
||||
AST_SymbolImportForeign,
|
||||
AST_SymbolRef,
|
||||
AST_SymbolDeclaration,
|
||||
AST_TemplateSegment,
|
||||
AST_TemplateString,
|
||||
AST_This,
|
||||
AST_Throw,
|
||||
AST_Toplevel,
|
||||
AST_True,
|
||||
AST_Try,
|
||||
AST_Catch,
|
||||
AST_Finally,
|
||||
AST_Unary,
|
||||
AST_Undefined,
|
||||
AST_Var,
|
||||
AST_VarDef,
|
||||
AST_While,
|
||||
AST_With,
|
||||
AST_Yield,
|
||||
walk_parent
|
||||
} from "./ast.js";
|
||||
import { first_in_statement } from "./utils/first_in_statement.js";
|
||||
|
||||
let mangle_options = undefined;
|
||||
AST_Node.prototype.size = function (compressor, stack) {
|
||||
mangle_options = compressor && compressor._mangle_options;
|
||||
|
||||
let size = 0;
|
||||
walk_parent(this, (node, info) => {
|
||||
size += node._size(info);
|
||||
|
||||
// Braceless arrow functions have fake "return" statements
|
||||
if (node instanceof AST_Arrow && node.is_braceless()) {
|
||||
size += node.body[0].value._size(info);
|
||||
return true;
|
||||
}
|
||||
}, stack || (compressor && compressor.stack));
|
||||
|
||||
// just to save a bit of memory
|
||||
mangle_options = undefined;
|
||||
|
||||
return size;
|
||||
};
|
||||
|
||||
AST_Node.prototype._size = () => 0;
|
||||
|
||||
AST_Debugger.prototype._size = () => 8;
|
||||
|
||||
AST_Directive.prototype._size = function () {
|
||||
// TODO string encoding stuff
|
||||
return 2 + this.value.length;
|
||||
};
|
||||
|
||||
/** Count commas/semicolons necessary to show a list of expressions/statements */
|
||||
const list_overhead = (array) => array.length && array.length - 1;
|
||||
|
||||
AST_Block.prototype._size = function () {
|
||||
return 2 + list_overhead(this.body);
|
||||
};
|
||||
|
||||
AST_Toplevel.prototype._size = function() {
|
||||
return list_overhead(this.body);
|
||||
};
|
||||
|
||||
AST_EmptyStatement.prototype._size = () => 1;
|
||||
|
||||
AST_LabeledStatement.prototype._size = () => 2; // x:
|
||||
|
||||
AST_Do.prototype._size = () => 9;
|
||||
|
||||
AST_While.prototype._size = () => 7;
|
||||
|
||||
AST_For.prototype._size = () => 8;
|
||||
|
||||
AST_ForIn.prototype._size = () => 8;
|
||||
// AST_ForOf inherits ^
|
||||
|
||||
AST_With.prototype._size = () => 6;
|
||||
|
||||
AST_Expansion.prototype._size = () => 3;
|
||||
|
||||
const lambda_modifiers = func =>
|
||||
(func.is_generator ? 1 : 0) + (func.async ? 6 : 0);
|
||||
|
||||
AST_Accessor.prototype._size = function () {
|
||||
return lambda_modifiers(this) + 4 + list_overhead(this.argnames) + list_overhead(this.body);
|
||||
};
|
||||
|
||||
AST_Function.prototype._size = function (info) {
|
||||
const first = !!first_in_statement(info);
|
||||
return (first * 2) + lambda_modifiers(this) + 12 + list_overhead(this.argnames) + list_overhead(this.body);
|
||||
};
|
||||
|
||||
AST_Defun.prototype._size = function () {
|
||||
return lambda_modifiers(this) + 13 + list_overhead(this.argnames) + list_overhead(this.body);
|
||||
};
|
||||
|
||||
AST_Arrow.prototype._size = function () {
|
||||
let args_and_arrow = 2 + list_overhead(this.argnames);
|
||||
|
||||
if (
|
||||
!(
|
||||
this.argnames.length === 1
|
||||
&& this.argnames[0] instanceof AST_Symbol
|
||||
)
|
||||
) {
|
||||
args_and_arrow += 2; // parens around the args
|
||||
}
|
||||
|
||||
const body_overhead = this.is_braceless() ? 0 : list_overhead(this.body) + 2;
|
||||
|
||||
return lambda_modifiers(this) + args_and_arrow + body_overhead;
|
||||
};
|
||||
|
||||
AST_Destructuring.prototype._size = () => 2;
|
||||
|
||||
AST_TemplateString.prototype._size = function () {
|
||||
return 2 + (Math.floor(this.segments.length / 2) * 3); /* "${}" */
|
||||
};
|
||||
|
||||
AST_TemplateSegment.prototype._size = function () {
|
||||
return this.value.length;
|
||||
};
|
||||
|
||||
AST_Return.prototype._size = function () {
|
||||
return this.value ? 7 : 6;
|
||||
};
|
||||
|
||||
AST_Throw.prototype._size = () => 6;
|
||||
|
||||
AST_Break.prototype._size = function () {
|
||||
return this.label ? 6 : 5;
|
||||
};
|
||||
|
||||
AST_Continue.prototype._size = function () {
|
||||
return this.label ? 9 : 8;
|
||||
};
|
||||
|
||||
AST_If.prototype._size = () => 4;
|
||||
|
||||
AST_Switch.prototype._size = function () {
|
||||
return 8 + list_overhead(this.body);
|
||||
};
|
||||
|
||||
AST_Case.prototype._size = function () {
|
||||
return 5 + list_overhead(this.body);
|
||||
};
|
||||
|
||||
AST_Default.prototype._size = function () {
|
||||
return 8 + list_overhead(this.body);
|
||||
};
|
||||
|
||||
AST_Try.prototype._size = () => 3;
|
||||
|
||||
AST_Catch.prototype._size = function () {
|
||||
let size = 7 + list_overhead(this.body);
|
||||
if (this.argname) {
|
||||
size += 2;
|
||||
}
|
||||
return size;
|
||||
};
|
||||
|
||||
AST_Finally.prototype._size = function () {
|
||||
return 7 + list_overhead(this.body);
|
||||
};
|
||||
|
||||
AST_Var.prototype._size = function () {
|
||||
return 4 + list_overhead(this.definitions);
|
||||
};
|
||||
|
||||
AST_Let.prototype._size = function () {
|
||||
return 4 + list_overhead(this.definitions);
|
||||
};
|
||||
|
||||
AST_Const.prototype._size = function () {
|
||||
return 6 + list_overhead(this.definitions);
|
||||
};
|
||||
|
||||
AST_VarDef.prototype._size = function () {
|
||||
return this.value ? 1 : 0;
|
||||
};
|
||||
|
||||
AST_NameMapping.prototype._size = function () {
|
||||
// foreign name isn't mangled
|
||||
return this.name ? 4 : 0;
|
||||
};
|
||||
|
||||
AST_Import.prototype._size = function () {
|
||||
// import
|
||||
let size = 6;
|
||||
|
||||
if (this.imported_name) size += 1;
|
||||
|
||||
// from
|
||||
if (this.imported_name || this.imported_names) size += 5;
|
||||
|
||||
// braces, and the commas
|
||||
if (this.imported_names) {
|
||||
size += 2 + list_overhead(this.imported_names);
|
||||
}
|
||||
|
||||
return size;
|
||||
};
|
||||
|
||||
AST_ImportMeta.prototype._size = () => 11;
|
||||
|
||||
AST_Export.prototype._size = function () {
|
||||
let size = 7 + (this.is_default ? 8 : 0);
|
||||
|
||||
if (this.exported_value) {
|
||||
size += this.exported_value._size();
|
||||
}
|
||||
|
||||
if (this.exported_names) {
|
||||
// Braces and commas
|
||||
size += 2 + list_overhead(this.exported_names);
|
||||
}
|
||||
|
||||
if (this.module_name) {
|
||||
// "from "
|
||||
size += 5;
|
||||
}
|
||||
|
||||
return size;
|
||||
};
|
||||
|
||||
AST_Call.prototype._size = function () {
|
||||
if (this.optional) {
|
||||
return 4 + list_overhead(this.args);
|
||||
}
|
||||
return 2 + list_overhead(this.args);
|
||||
};
|
||||
|
||||
AST_New.prototype._size = function () {
|
||||
return 6 + list_overhead(this.args);
|
||||
};
|
||||
|
||||
AST_Sequence.prototype._size = function () {
|
||||
return list_overhead(this.expressions);
|
||||
};
|
||||
|
||||
AST_Dot.prototype._size = function () {
|
||||
if (this.optional) {
|
||||
return this.property.length + 2;
|
||||
}
|
||||
return this.property.length + 1;
|
||||
};
|
||||
|
||||
AST_DotHash.prototype._size = function () {
|
||||
if (this.optional) {
|
||||
return this.property.length + 3;
|
||||
}
|
||||
return this.property.length + 2;
|
||||
};
|
||||
|
||||
AST_Sub.prototype._size = function () {
|
||||
return this.optional ? 4 : 2;
|
||||
};
|
||||
|
||||
AST_Unary.prototype._size = function () {
|
||||
if (this.operator === "typeof") return 7;
|
||||
if (this.operator === "void") return 5;
|
||||
return this.operator.length;
|
||||
};
|
||||
|
||||
AST_Binary.prototype._size = function (info) {
|
||||
if (this.operator === "in") return 4;
|
||||
|
||||
let size = this.operator.length;
|
||||
|
||||
if (
|
||||
(this.operator === "+" || this.operator === "-")
|
||||
&& this.right instanceof AST_Unary && this.right.operator === this.operator
|
||||
) {
|
||||
// 1+ +a > needs space between the +
|
||||
size += 1;
|
||||
}
|
||||
|
||||
if (this.needs_parens(info)) {
|
||||
size += 2;
|
||||
}
|
||||
|
||||
return size;
|
||||
};
|
||||
|
||||
AST_Conditional.prototype._size = () => 3;
|
||||
|
||||
AST_Array.prototype._size = function () {
|
||||
return 2 + list_overhead(this.elements);
|
||||
};
|
||||
|
||||
AST_Object.prototype._size = function (info) {
|
||||
let base = 2;
|
||||
if (first_in_statement(info)) {
|
||||
base += 2; // parens
|
||||
}
|
||||
return base + list_overhead(this.properties);
|
||||
};
|
||||
|
||||
/*#__INLINE__*/
|
||||
const key_size = key =>
|
||||
typeof key === "string" ? key.length : 0;
|
||||
|
||||
AST_ObjectKeyVal.prototype._size = function () {
|
||||
return key_size(this.key) + 1;
|
||||
};
|
||||
|
||||
/*#__INLINE__*/
|
||||
const static_size = is_static => is_static ? 7 : 0;
|
||||
|
||||
AST_ObjectGetter.prototype._size = function () {
|
||||
return 5 + static_size(this.static) + key_size(this.key);
|
||||
};
|
||||
|
||||
AST_ObjectSetter.prototype._size = function () {
|
||||
return 5 + static_size(this.static) + key_size(this.key);
|
||||
};
|
||||
|
||||
AST_ConciseMethod.prototype._size = function () {
|
||||
return static_size(this.static) + key_size(this.key) + lambda_modifiers(this);
|
||||
};
|
||||
|
||||
AST_PrivateMethod.prototype._size = function () {
|
||||
return AST_ConciseMethod.prototype._size.call(this) + 1;
|
||||
};
|
||||
|
||||
AST_PrivateGetter.prototype._size = AST_PrivateSetter.prototype._size = function () {
|
||||
return AST_ConciseMethod.prototype._size.call(this) + 4;
|
||||
};
|
||||
|
||||
AST_PrivateIn.prototype._size = function () {
|
||||
return 5; // "#", and " in "
|
||||
};
|
||||
|
||||
AST_Class.prototype._size = function () {
|
||||
return (
|
||||
(this.name ? 8 : 7)
|
||||
+ (this.extends ? 8 : 0)
|
||||
);
|
||||
};
|
||||
|
||||
AST_ClassStaticBlock.prototype._size = function () {
|
||||
// "class{}" + semicolons
|
||||
return 7 + list_overhead(this.body);
|
||||
};
|
||||
|
||||
AST_ClassProperty.prototype._size = function () {
|
||||
return (
|
||||
static_size(this.static)
|
||||
+ (typeof this.key === "string" ? this.key.length + 2 : 0)
|
||||
+ (this.value ? 1 : 0)
|
||||
);
|
||||
};
|
||||
|
||||
AST_ClassPrivateProperty.prototype._size = function () {
|
||||
return AST_ClassProperty.prototype._size.call(this) + 1;
|
||||
};
|
||||
|
||||
AST_Symbol.prototype._size = function () {
|
||||
if (!(mangle_options && this.thedef && !this.thedef.unmangleable(mangle_options))) {
|
||||
return this.name.length;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
|
||||
// TODO take propmangle into account
|
||||
AST_SymbolClassProperty.prototype._size = function () {
|
||||
return this.name.length;
|
||||
};
|
||||
|
||||
AST_SymbolRef.prototype._size = AST_SymbolDeclaration.prototype._size = function () {
|
||||
if (this.name === "arguments") return 9;
|
||||
|
||||
return AST_Symbol.prototype._size.call(this);
|
||||
};
|
||||
|
||||
AST_NewTarget.prototype._size = () => 10;
|
||||
|
||||
AST_SymbolImportForeign.prototype._size = function () {
|
||||
return this.name.length;
|
||||
};
|
||||
|
||||
AST_SymbolExportForeign.prototype._size = function () {
|
||||
return this.name.length;
|
||||
};
|
||||
|
||||
AST_This.prototype._size = () => 4;
|
||||
|
||||
AST_Super.prototype._size = () => 5;
|
||||
|
||||
AST_String.prototype._size = function () {
|
||||
return this.value.length + 2;
|
||||
};
|
||||
|
||||
AST_Number.prototype._size = function () {
|
||||
const { value } = this;
|
||||
if (value === 0) return 1;
|
||||
if (value > 0 && Math.floor(value) === value) {
|
||||
return Math.floor(Math.log10(value) + 1);
|
||||
}
|
||||
return value.toString().length;
|
||||
};
|
||||
|
||||
AST_BigInt.prototype._size = function () {
|
||||
return this.value.length;
|
||||
};
|
||||
|
||||
AST_RegExp.prototype._size = function () {
|
||||
return this.value.toString().length;
|
||||
};
|
||||
|
||||
AST_Null.prototype._size = () => 4;
|
||||
|
||||
AST_NaN.prototype._size = () => 3;
|
||||
|
||||
AST_Undefined.prototype._size = () => 6; // "void 0"
|
||||
|
||||
AST_Hole.prototype._size = () => 0; // comma is taken into account by list_overhead()
|
||||
|
||||
AST_Infinity.prototype._size = () => 8;
|
||||
|
||||
AST_True.prototype._size = () => 4;
|
||||
|
||||
AST_False.prototype._size = () => 5;
|
||||
|
||||
AST_Await.prototype._size = () => 6;
|
||||
|
||||
AST_Yield.prototype._size = () => 6;
|
148
my-app/node_modules/terser/lib/sourcemap.js
generated
vendored
Executable file
148
my-app/node_modules/terser/lib/sourcemap.js
generated
vendored
Executable file
|
@ -0,0 +1,148 @@
|
|||
/***********************************************************************
|
||||
|
||||
A JavaScript tokenizer / parser / beautifier / compressor.
|
||||
https://github.com/mishoo/UglifyJS2
|
||||
|
||||
-------------------------------- (C) ---------------------------------
|
||||
|
||||
Author: Mihai Bazon
|
||||
<mihai.bazon@gmail.com>
|
||||
http://mihai.bazon.net/blog
|
||||
|
||||
Distributed under the BSD license:
|
||||
|
||||
Copyright 2012 (c) Mihai Bazon <mihai.bazon@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials
|
||||
provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
"use strict";
|
||||
|
||||
import {SourceMapConsumer, SourceMapGenerator} from "@jridgewell/source-map";
|
||||
import {defaults, HOP} from "./utils/index.js";
|
||||
|
||||
// a small wrapper around source-map and @jridgewell/source-map
|
||||
async function SourceMap(options) {
|
||||
options = defaults(options, {
|
||||
file : null,
|
||||
root : null,
|
||||
orig : null,
|
||||
files: {},
|
||||
});
|
||||
|
||||
var orig_map;
|
||||
var generator = new SourceMapGenerator({
|
||||
file : options.file,
|
||||
sourceRoot : options.root
|
||||
});
|
||||
|
||||
let sourcesContent = {__proto__: null};
|
||||
let files = options.files;
|
||||
for (var name in files) if (HOP(files, name)) {
|
||||
sourcesContent[name] = files[name];
|
||||
}
|
||||
if (options.orig) {
|
||||
// We support both @jridgewell/source-map (which has a sync
|
||||
// SourceMapConsumer) and source-map (which has an async
|
||||
// SourceMapConsumer).
|
||||
orig_map = await new SourceMapConsumer(options.orig);
|
||||
if (orig_map.sourcesContent) {
|
||||
orig_map.sources.forEach(function(source, i) {
|
||||
var content = orig_map.sourcesContent[i];
|
||||
if (content) {
|
||||
sourcesContent[source] = content;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function add(source, gen_line, gen_col, orig_line, orig_col, name) {
|
||||
let generatedPos = { line: gen_line, column: gen_col };
|
||||
|
||||
if (orig_map) {
|
||||
var info = orig_map.originalPositionFor({
|
||||
line: orig_line,
|
||||
column: orig_col
|
||||
});
|
||||
if (info.source === null) {
|
||||
generator.addMapping({
|
||||
generated: generatedPos,
|
||||
original: null,
|
||||
source: null,
|
||||
name: null
|
||||
});
|
||||
return;
|
||||
}
|
||||
source = info.source;
|
||||
orig_line = info.line;
|
||||
orig_col = info.column;
|
||||
name = info.name || name;
|
||||
}
|
||||
generator.addMapping({
|
||||
generated : generatedPos,
|
||||
original : { line: orig_line, column: orig_col },
|
||||
source : source,
|
||||
name : name
|
||||
});
|
||||
generator.setSourceContent(source, sourcesContent[source]);
|
||||
}
|
||||
|
||||
function clean(map) {
|
||||
const allNull = map.sourcesContent && map.sourcesContent.every(c => c == null);
|
||||
if (allNull) delete map.sourcesContent;
|
||||
if (map.file === undefined) delete map.file;
|
||||
if (map.sourceRoot === undefined) delete map.sourceRoot;
|
||||
return map;
|
||||
}
|
||||
|
||||
function getDecoded() {
|
||||
if (!generator.toDecodedMap) return null;
|
||||
return clean(generator.toDecodedMap());
|
||||
}
|
||||
|
||||
function getEncoded() {
|
||||
return clean(generator.toJSON());
|
||||
}
|
||||
|
||||
function destroy() {
|
||||
// @jridgewell/source-map's SourceMapConsumer does not need to be
|
||||
// manually freed.
|
||||
if (orig_map && orig_map.destroy) orig_map.destroy();
|
||||
}
|
||||
|
||||
return {
|
||||
add,
|
||||
getDecoded,
|
||||
getEncoded,
|
||||
destroy,
|
||||
};
|
||||
}
|
||||
|
||||
export {
|
||||
SourceMap,
|
||||
};
|
323
my-app/node_modules/terser/lib/transform.js
generated
vendored
Executable file
323
my-app/node_modules/terser/lib/transform.js
generated
vendored
Executable file
|
@ -0,0 +1,323 @@
|
|||
/***********************************************************************
|
||||
|
||||
A JavaScript tokenizer / parser / beautifier / compressor.
|
||||
https://github.com/mishoo/UglifyJS2
|
||||
|
||||
-------------------------------- (C) ---------------------------------
|
||||
|
||||
Author: Mihai Bazon
|
||||
<mihai.bazon@gmail.com>
|
||||
http://mihai.bazon.net/blog
|
||||
|
||||
Distributed under the BSD license:
|
||||
|
||||
Copyright 2012 (c) Mihai Bazon <mihai.bazon@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials
|
||||
provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
"use strict";
|
||||
|
||||
import {
|
||||
AST_Array,
|
||||
AST_Await,
|
||||
AST_Binary,
|
||||
AST_PrivateIn,
|
||||
AST_Block,
|
||||
AST_Call,
|
||||
AST_Case,
|
||||
AST_Catch,
|
||||
AST_Chain,
|
||||
AST_Class,
|
||||
AST_ClassStaticBlock,
|
||||
AST_Conditional,
|
||||
AST_Definitions,
|
||||
AST_Destructuring,
|
||||
AST_Do,
|
||||
AST_Exit,
|
||||
AST_Expansion,
|
||||
AST_Export,
|
||||
AST_For,
|
||||
AST_ForIn,
|
||||
AST_If,
|
||||
AST_Import,
|
||||
AST_LabeledStatement,
|
||||
AST_Lambda,
|
||||
AST_LoopControl,
|
||||
AST_NameMapping,
|
||||
AST_Node,
|
||||
AST_Number,
|
||||
AST_Object,
|
||||
AST_ObjectProperty,
|
||||
AST_PrefixedTemplateString,
|
||||
AST_PropAccess,
|
||||
AST_Sequence,
|
||||
AST_SimpleStatement,
|
||||
AST_Sub,
|
||||
AST_Switch,
|
||||
AST_TemplateString,
|
||||
AST_Try,
|
||||
AST_Unary,
|
||||
AST_VarDef,
|
||||
AST_While,
|
||||
AST_With,
|
||||
AST_Yield,
|
||||
} from "./ast.js";
|
||||
import {
|
||||
MAP as do_list,
|
||||
noop,
|
||||
} from "./utils/index.js";
|
||||
|
||||
function def_transform(node, descend) {
|
||||
node.DEFMETHOD("transform", function(tw, in_list) {
|
||||
let transformed = undefined;
|
||||
tw.push(this);
|
||||
if (tw.before) transformed = tw.before(this, descend, in_list);
|
||||
if (transformed === undefined) {
|
||||
transformed = this;
|
||||
descend(transformed, tw);
|
||||
if (tw.after) {
|
||||
const after_ret = tw.after(transformed, in_list);
|
||||
if (after_ret !== undefined) transformed = after_ret;
|
||||
}
|
||||
}
|
||||
tw.pop();
|
||||
return transformed;
|
||||
});
|
||||
}
|
||||
|
||||
def_transform(AST_Node, noop);
|
||||
|
||||
def_transform(AST_LabeledStatement, function(self, tw) {
|
||||
self.label = self.label.transform(tw);
|
||||
self.body = self.body.transform(tw);
|
||||
});
|
||||
|
||||
def_transform(AST_SimpleStatement, function(self, tw) {
|
||||
self.body = self.body.transform(tw);
|
||||
});
|
||||
|
||||
def_transform(AST_Block, function(self, tw) {
|
||||
self.body = do_list(self.body, tw);
|
||||
});
|
||||
|
||||
def_transform(AST_Do, function(self, tw) {
|
||||
self.body = self.body.transform(tw);
|
||||
self.condition = self.condition.transform(tw);
|
||||
});
|
||||
|
||||
def_transform(AST_While, function(self, tw) {
|
||||
self.condition = self.condition.transform(tw);
|
||||
self.body = self.body.transform(tw);
|
||||
});
|
||||
|
||||
def_transform(AST_For, function(self, tw) {
|
||||
if (self.init) self.init = self.init.transform(tw);
|
||||
if (self.condition) self.condition = self.condition.transform(tw);
|
||||
if (self.step) self.step = self.step.transform(tw);
|
||||
self.body = self.body.transform(tw);
|
||||
});
|
||||
|
||||
def_transform(AST_ForIn, function(self, tw) {
|
||||
self.init = self.init.transform(tw);
|
||||
self.object = self.object.transform(tw);
|
||||
self.body = self.body.transform(tw);
|
||||
});
|
||||
|
||||
def_transform(AST_With, function(self, tw) {
|
||||
self.expression = self.expression.transform(tw);
|
||||
self.body = self.body.transform(tw);
|
||||
});
|
||||
|
||||
def_transform(AST_Exit, function(self, tw) {
|
||||
if (self.value) self.value = self.value.transform(tw);
|
||||
});
|
||||
|
||||
def_transform(AST_LoopControl, function(self, tw) {
|
||||
if (self.label) self.label = self.label.transform(tw);
|
||||
});
|
||||
|
||||
def_transform(AST_If, function(self, tw) {
|
||||
self.condition = self.condition.transform(tw);
|
||||
self.body = self.body.transform(tw);
|
||||
if (self.alternative) self.alternative = self.alternative.transform(tw);
|
||||
});
|
||||
|
||||
def_transform(AST_Switch, function(self, tw) {
|
||||
self.expression = self.expression.transform(tw);
|
||||
self.body = do_list(self.body, tw);
|
||||
});
|
||||
|
||||
def_transform(AST_Case, function(self, tw) {
|
||||
self.expression = self.expression.transform(tw);
|
||||
self.body = do_list(self.body, tw);
|
||||
});
|
||||
|
||||
def_transform(AST_Try, function(self, tw) {
|
||||
self.body = self.body.transform(tw);
|
||||
if (self.bcatch) self.bcatch = self.bcatch.transform(tw);
|
||||
if (self.bfinally) self.bfinally = self.bfinally.transform(tw);
|
||||
});
|
||||
|
||||
def_transform(AST_Catch, function(self, tw) {
|
||||
if (self.argname) self.argname = self.argname.transform(tw);
|
||||
self.body = do_list(self.body, tw);
|
||||
});
|
||||
|
||||
def_transform(AST_Definitions, function(self, tw) {
|
||||
self.definitions = do_list(self.definitions, tw);
|
||||
});
|
||||
|
||||
def_transform(AST_VarDef, function(self, tw) {
|
||||
self.name = self.name.transform(tw);
|
||||
if (self.value) self.value = self.value.transform(tw);
|
||||
});
|
||||
|
||||
def_transform(AST_Destructuring, function(self, tw) {
|
||||
self.names = do_list(self.names, tw);
|
||||
});
|
||||
|
||||
def_transform(AST_Lambda, function(self, tw) {
|
||||
if (self.name) self.name = self.name.transform(tw);
|
||||
self.argnames = do_list(self.argnames, tw, /* allow_splicing */ false);
|
||||
if (self.body instanceof AST_Node) {
|
||||
self.body = self.body.transform(tw);
|
||||
} else {
|
||||
self.body = do_list(self.body, tw);
|
||||
}
|
||||
});
|
||||
|
||||
def_transform(AST_Call, function(self, tw) {
|
||||
self.expression = self.expression.transform(tw);
|
||||
self.args = do_list(self.args, tw, /* allow_splicing */ false);
|
||||
});
|
||||
|
||||
def_transform(AST_Sequence, function(self, tw) {
|
||||
const result = do_list(self.expressions, tw);
|
||||
self.expressions = result.length
|
||||
? result
|
||||
: [new AST_Number({ value: 0 })];
|
||||
});
|
||||
|
||||
def_transform(AST_PropAccess, function(self, tw) {
|
||||
self.expression = self.expression.transform(tw);
|
||||
});
|
||||
|
||||
def_transform(AST_Sub, function(self, tw) {
|
||||
self.expression = self.expression.transform(tw);
|
||||
self.property = self.property.transform(tw);
|
||||
});
|
||||
|
||||
def_transform(AST_Chain, function(self, tw) {
|
||||
self.expression = self.expression.transform(tw);
|
||||
});
|
||||
|
||||
def_transform(AST_Yield, function(self, tw) {
|
||||
if (self.expression) self.expression = self.expression.transform(tw);
|
||||
});
|
||||
|
||||
def_transform(AST_Await, function(self, tw) {
|
||||
self.expression = self.expression.transform(tw);
|
||||
});
|
||||
|
||||
def_transform(AST_Unary, function(self, tw) {
|
||||
self.expression = self.expression.transform(tw);
|
||||
});
|
||||
|
||||
def_transform(AST_Binary, function(self, tw) {
|
||||
self.left = self.left.transform(tw);
|
||||
self.right = self.right.transform(tw);
|
||||
});
|
||||
|
||||
def_transform(AST_PrivateIn, function(self, tw) {
|
||||
self.key = self.key.transform(tw);
|
||||
self.value = self.value.transform(tw);
|
||||
});
|
||||
|
||||
def_transform(AST_Conditional, function(self, tw) {
|
||||
self.condition = self.condition.transform(tw);
|
||||
self.consequent = self.consequent.transform(tw);
|
||||
self.alternative = self.alternative.transform(tw);
|
||||
});
|
||||
|
||||
def_transform(AST_Array, function(self, tw) {
|
||||
self.elements = do_list(self.elements, tw);
|
||||
});
|
||||
|
||||
def_transform(AST_Object, function(self, tw) {
|
||||
self.properties = do_list(self.properties, tw);
|
||||
});
|
||||
|
||||
def_transform(AST_ObjectProperty, function(self, tw) {
|
||||
if (self.key instanceof AST_Node) {
|
||||
self.key = self.key.transform(tw);
|
||||
}
|
||||
if (self.value) self.value = self.value.transform(tw);
|
||||
});
|
||||
|
||||
def_transform(AST_Class, function(self, tw) {
|
||||
if (self.name) self.name = self.name.transform(tw);
|
||||
if (self.extends) self.extends = self.extends.transform(tw);
|
||||
self.properties = do_list(self.properties, tw);
|
||||
});
|
||||
|
||||
def_transform(AST_ClassStaticBlock, function(self, tw) {
|
||||
self.body = do_list(self.body, tw);
|
||||
});
|
||||
|
||||
def_transform(AST_Expansion, function(self, tw) {
|
||||
self.expression = self.expression.transform(tw);
|
||||
});
|
||||
|
||||
def_transform(AST_NameMapping, function(self, tw) {
|
||||
self.foreign_name = self.foreign_name.transform(tw);
|
||||
self.name = self.name.transform(tw);
|
||||
});
|
||||
|
||||
def_transform(AST_Import, function(self, tw) {
|
||||
if (self.imported_name) self.imported_name = self.imported_name.transform(tw);
|
||||
if (self.imported_names) do_list(self.imported_names, tw);
|
||||
self.module_name = self.module_name.transform(tw);
|
||||
});
|
||||
|
||||
def_transform(AST_Export, function(self, tw) {
|
||||
if (self.exported_definition) self.exported_definition = self.exported_definition.transform(tw);
|
||||
if (self.exported_value) self.exported_value = self.exported_value.transform(tw);
|
||||
if (self.exported_names) do_list(self.exported_names, tw);
|
||||
if (self.module_name) self.module_name = self.module_name.transform(tw);
|
||||
});
|
||||
|
||||
def_transform(AST_TemplateString, function(self, tw) {
|
||||
self.segments = do_list(self.segments, tw);
|
||||
});
|
||||
|
||||
def_transform(AST_PrefixedTemplateString, function(self, tw) {
|
||||
self.prefix = self.prefix.transform(tw);
|
||||
self.template_string = self.template_string.transform(tw);
|
||||
});
|
||||
|
53
my-app/node_modules/terser/lib/utils/first_in_statement.js
generated
vendored
Executable file
53
my-app/node_modules/terser/lib/utils/first_in_statement.js
generated
vendored
Executable file
|
@ -0,0 +1,53 @@
|
|||
import {
|
||||
AST_Binary,
|
||||
AST_Conditional,
|
||||
AST_Chain,
|
||||
AST_Dot,
|
||||
AST_Object,
|
||||
AST_Sequence,
|
||||
AST_Statement,
|
||||
AST_Sub,
|
||||
AST_UnaryPostfix,
|
||||
AST_PrefixedTemplateString
|
||||
} from "../ast.js";
|
||||
|
||||
// return true if the node at the top of the stack (that means the
|
||||
// innermost node in the current output) is lexically the first in
|
||||
// a statement.
|
||||
function first_in_statement(stack) {
|
||||
let node = stack.parent(-1);
|
||||
for (let i = 0, p; p = stack.parent(i); i++) {
|
||||
if (p instanceof AST_Statement && p.body === node)
|
||||
return true;
|
||||
if ((p instanceof AST_Sequence && p.expressions[0] === node) ||
|
||||
(p.TYPE === "Call" && p.expression === node) ||
|
||||
(p instanceof AST_PrefixedTemplateString && p.prefix === node) ||
|
||||
(p instanceof AST_Dot && p.expression === node) ||
|
||||
(p instanceof AST_Sub && p.expression === node) ||
|
||||
(p instanceof AST_Chain && p.expression === node) ||
|
||||
(p instanceof AST_Conditional && p.condition === node) ||
|
||||
(p instanceof AST_Binary && p.left === node) ||
|
||||
(p instanceof AST_UnaryPostfix && p.expression === node)
|
||||
) {
|
||||
node = p;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Returns whether the leftmost item in the expression is an object
|
||||
function left_is_object(node) {
|
||||
if (node instanceof AST_Object) return true;
|
||||
if (node instanceof AST_Sequence) return left_is_object(node.expressions[0]);
|
||||
if (node.TYPE === "Call") return left_is_object(node.expression);
|
||||
if (node instanceof AST_PrefixedTemplateString) return left_is_object(node.prefix);
|
||||
if (node instanceof AST_Dot || node instanceof AST_Sub) return left_is_object(node.expression);
|
||||
if (node instanceof AST_Chain) return left_is_object(node.expression);
|
||||
if (node instanceof AST_Conditional) return left_is_object(node.condition);
|
||||
if (node instanceof AST_Binary) return left_is_object(node.left);
|
||||
if (node instanceof AST_UnaryPostfix) return left_is_object(node.expression);
|
||||
return false;
|
||||
}
|
||||
|
||||
export { first_in_statement, left_is_object };
|
295
my-app/node_modules/terser/lib/utils/index.js
generated
vendored
Executable file
295
my-app/node_modules/terser/lib/utils/index.js
generated
vendored
Executable file
|
@ -0,0 +1,295 @@
|
|||
/***********************************************************************
|
||||
|
||||
A JavaScript tokenizer / parser / beautifier / compressor.
|
||||
https://github.com/mishoo/UglifyJS2
|
||||
|
||||
-------------------------------- (C) ---------------------------------
|
||||
|
||||
Author: Mihai Bazon
|
||||
<mihai.bazon@gmail.com>
|
||||
http://mihai.bazon.net/blog
|
||||
|
||||
Distributed under the BSD license:
|
||||
|
||||
Copyright 2012 (c) Mihai Bazon <mihai.bazon@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials
|
||||
provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
"use strict";
|
||||
|
||||
import { AST_Node } from "../ast.js";
|
||||
|
||||
function characters(str) {
|
||||
return str.split("");
|
||||
}
|
||||
|
||||
function member(name, array) {
|
||||
return array.includes(name);
|
||||
}
|
||||
|
||||
class DefaultsError extends Error {
|
||||
constructor(msg, defs) {
|
||||
super();
|
||||
|
||||
this.name = "DefaultsError";
|
||||
this.message = msg;
|
||||
this.defs = defs;
|
||||
}
|
||||
}
|
||||
|
||||
function defaults(args, defs, croak) {
|
||||
if (args === true) {
|
||||
args = {};
|
||||
} else if (args != null && typeof args === "object") {
|
||||
args = {...args};
|
||||
}
|
||||
|
||||
const ret = args || {};
|
||||
|
||||
if (croak) for (const i in ret) if (HOP(ret, i) && !HOP(defs, i)) {
|
||||
throw new DefaultsError("`" + i + "` is not a supported option", defs);
|
||||
}
|
||||
|
||||
for (const i in defs) if (HOP(defs, i)) {
|
||||
if (!args || !HOP(args, i)) {
|
||||
ret[i] = defs[i];
|
||||
} else if (i === "ecma") {
|
||||
let ecma = args[i] | 0;
|
||||
if (ecma > 5 && ecma < 2015) ecma += 2009;
|
||||
ret[i] = ecma;
|
||||
} else {
|
||||
ret[i] = (args && HOP(args, i)) ? args[i] : defs[i];
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
function noop() {}
|
||||
function return_false() { return false; }
|
||||
function return_true() { return true; }
|
||||
function return_this() { return this; }
|
||||
function return_null() { return null; }
|
||||
|
||||
var MAP = (function() {
|
||||
function MAP(a, tw, allow_splicing = true) {
|
||||
const new_a = [];
|
||||
|
||||
for (let i = 0; i < a.length; ++i) {
|
||||
let item = a[i];
|
||||
let ret = item.transform(tw, allow_splicing);
|
||||
|
||||
if (ret instanceof AST_Node) {
|
||||
new_a.push(ret);
|
||||
} else if (ret instanceof Splice) {
|
||||
new_a.push(...ret.v);
|
||||
}
|
||||
}
|
||||
|
||||
return new_a;
|
||||
}
|
||||
|
||||
MAP.splice = function(val) { return new Splice(val); };
|
||||
MAP.skip = {};
|
||||
function Splice(val) { this.v = val; }
|
||||
return MAP;
|
||||
})();
|
||||
|
||||
function make_node(ctor, orig, props) {
|
||||
if (!props) props = {};
|
||||
if (orig) {
|
||||
if (!props.start) props.start = orig.start;
|
||||
if (!props.end) props.end = orig.end;
|
||||
}
|
||||
return new ctor(props);
|
||||
}
|
||||
|
||||
function push_uniq(array, el) {
|
||||
if (!array.includes(el))
|
||||
array.push(el);
|
||||
}
|
||||
|
||||
function string_template(text, props) {
|
||||
return text.replace(/{(.+?)}/g, function(str, p) {
|
||||
return props && props[p];
|
||||
});
|
||||
}
|
||||
|
||||
function remove(array, el) {
|
||||
for (var i = array.length; --i >= 0;) {
|
||||
if (array[i] === el) array.splice(i, 1);
|
||||
}
|
||||
}
|
||||
|
||||
function mergeSort(array, cmp) {
|
||||
if (array.length < 2) return array.slice();
|
||||
function merge(a, b) {
|
||||
var r = [], ai = 0, bi = 0, i = 0;
|
||||
while (ai < a.length && bi < b.length) {
|
||||
cmp(a[ai], b[bi]) <= 0
|
||||
? r[i++] = a[ai++]
|
||||
: r[i++] = b[bi++];
|
||||
}
|
||||
if (ai < a.length) r.push.apply(r, a.slice(ai));
|
||||
if (bi < b.length) r.push.apply(r, b.slice(bi));
|
||||
return r;
|
||||
}
|
||||
function _ms(a) {
|
||||
if (a.length <= 1)
|
||||
return a;
|
||||
var m = Math.floor(a.length / 2), left = a.slice(0, m), right = a.slice(m);
|
||||
left = _ms(left);
|
||||
right = _ms(right);
|
||||
return merge(left, right);
|
||||
}
|
||||
return _ms(array);
|
||||
}
|
||||
|
||||
function makePredicate(words) {
|
||||
if (!Array.isArray(words)) words = words.split(" ");
|
||||
|
||||
return new Set(words.sort());
|
||||
}
|
||||
|
||||
function map_add(map, key, value) {
|
||||
if (map.has(key)) {
|
||||
map.get(key).push(value);
|
||||
} else {
|
||||
map.set(key, [ value ]);
|
||||
}
|
||||
}
|
||||
|
||||
function map_from_object(obj) {
|
||||
var map = new Map();
|
||||
for (var key in obj) {
|
||||
if (HOP(obj, key) && key.charAt(0) === "$") {
|
||||
map.set(key.substr(1), obj[key]);
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
function map_to_object(map) {
|
||||
var obj = Object.create(null);
|
||||
map.forEach(function (value, key) {
|
||||
obj["$" + key] = value;
|
||||
});
|
||||
return obj;
|
||||
}
|
||||
|
||||
function HOP(obj, prop) {
|
||||
return Object.prototype.hasOwnProperty.call(obj, prop);
|
||||
}
|
||||
|
||||
function keep_name(keep_setting, name) {
|
||||
return keep_setting === true
|
||||
|| (keep_setting instanceof RegExp && keep_setting.test(name));
|
||||
}
|
||||
|
||||
var lineTerminatorEscape = {
|
||||
"\0": "0",
|
||||
"\n": "n",
|
||||
"\r": "r",
|
||||
"\u2028": "u2028",
|
||||
"\u2029": "u2029",
|
||||
};
|
||||
function regexp_source_fix(source) {
|
||||
// V8 does not escape line terminators in regexp patterns in node 12
|
||||
// We'll also remove literal \0
|
||||
return source.replace(/[\0\n\r\u2028\u2029]/g, function (match, offset) {
|
||||
var escaped = source[offset - 1] == "\\"
|
||||
&& (source[offset - 2] != "\\"
|
||||
|| /(?:^|[^\\])(?:\\{2})*$/.test(source.slice(0, offset - 1)));
|
||||
return (escaped ? "" : "\\") + lineTerminatorEscape[match];
|
||||
});
|
||||
}
|
||||
|
||||
// Subset of regexps that is not going to cause regexp based DDOS
|
||||
// https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
|
||||
const re_safe_regexp = /^[\\/|\0\s\w^$.[\]()]*$/;
|
||||
|
||||
/** Check if the regexp is safe for Terser to create without risking a RegExp DOS */
|
||||
export const regexp_is_safe = (source) => re_safe_regexp.test(source);
|
||||
|
||||
const all_flags = "dgimsuyv";
|
||||
function sort_regexp_flags(flags) {
|
||||
const existing_flags = new Set(flags.split(""));
|
||||
let out = "";
|
||||
for (const flag of all_flags) {
|
||||
if (existing_flags.has(flag)) {
|
||||
out += flag;
|
||||
existing_flags.delete(flag);
|
||||
}
|
||||
}
|
||||
if (existing_flags.size) {
|
||||
// Flags Terser doesn't know about
|
||||
existing_flags.forEach(flag => { out += flag; });
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
function has_annotation(node, annotation) {
|
||||
return node._annotations & annotation;
|
||||
}
|
||||
|
||||
function set_annotation(node, annotation) {
|
||||
node._annotations |= annotation;
|
||||
}
|
||||
|
||||
function clear_annotation(node, annotation) {
|
||||
node._annotations &= ~annotation;
|
||||
}
|
||||
|
||||
export {
|
||||
characters,
|
||||
defaults,
|
||||
HOP,
|
||||
keep_name,
|
||||
make_node,
|
||||
makePredicate,
|
||||
map_add,
|
||||
map_from_object,
|
||||
map_to_object,
|
||||
MAP,
|
||||
member,
|
||||
mergeSort,
|
||||
noop,
|
||||
push_uniq,
|
||||
regexp_source_fix,
|
||||
remove,
|
||||
return_false,
|
||||
return_null,
|
||||
return_this,
|
||||
return_true,
|
||||
sort_regexp_flags,
|
||||
string_template,
|
||||
has_annotation,
|
||||
set_annotation,
|
||||
clear_annotation,
|
||||
};
|
27
my-app/node_modules/terser/main.js
generated
vendored
Executable file
27
my-app/node_modules/terser/main.js
generated
vendored
Executable file
|
@ -0,0 +1,27 @@
|
|||
import "./lib/transform.js";
|
||||
import "./lib/mozilla-ast.js";
|
||||
import { minify } from "./lib/minify.js";
|
||||
|
||||
export { minify } from "./lib/minify.js";
|
||||
export { run_cli as _run_cli } from "./lib/cli.js";
|
||||
|
||||
export async function _default_options() {
|
||||
const defs = {};
|
||||
|
||||
Object.keys(infer_options({ 0: 0 })).forEach((component) => {
|
||||
const options = infer_options({
|
||||
[component]: {0: 0}
|
||||
});
|
||||
|
||||
if (options) defs[component] = options;
|
||||
});
|
||||
return defs;
|
||||
}
|
||||
|
||||
async function infer_options(options) {
|
||||
try {
|
||||
await minify("", options);
|
||||
} catch (error) {
|
||||
return error.defs;
|
||||
}
|
||||
}
|
153
my-app/node_modules/terser/package.json
generated
vendored
Executable file
153
my-app/node_modules/terser/package.json
generated
vendored
Executable file
|
@ -0,0 +1,153 @@
|
|||
{
|
||||
"name": "terser",
|
||||
"description": "JavaScript parser, mangler/compressor and beautifier toolkit for ES6+",
|
||||
"homepage": "https://terser.org",
|
||||
"author": "Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)",
|
||||
"license": "BSD-2-Clause",
|
||||
"version": "5.26.0",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"maintainers": [
|
||||
"Fábio Santos <fabiosantosart@gmail.com>"
|
||||
],
|
||||
"repository": "https://github.com/terser/terser",
|
||||
"main": "dist/bundle.min.js",
|
||||
"type": "module",
|
||||
"module": "./main.js",
|
||||
"exports": {
|
||||
".": [
|
||||
{
|
||||
"types": "./tools/terser.d.ts",
|
||||
"import": "./main.js",
|
||||
"require": "./dist/bundle.min.js"
|
||||
},
|
||||
"./dist/bundle.min.js"
|
||||
],
|
||||
"./package": "./package.json",
|
||||
"./package.json": "./package.json",
|
||||
"./bin/terser": "./bin/terser"
|
||||
},
|
||||
"types": "tools/terser.d.ts",
|
||||
"bin": {
|
||||
"terser": "bin/terser"
|
||||
},
|
||||
"files": [
|
||||
"bin",
|
||||
"dist",
|
||||
"lib",
|
||||
"tools",
|
||||
"LICENSE",
|
||||
"README.md",
|
||||
"CHANGELOG.md",
|
||||
"PATRONS.md",
|
||||
"main.js"
|
||||
],
|
||||
"dependencies": {
|
||||
"@jridgewell/source-map": "^0.3.3",
|
||||
"acorn": "^8.8.2",
|
||||
"commander": "^2.20.0",
|
||||
"source-map-support": "~0.5.20"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@ls-lint/ls-lint": "^1.11.2",
|
||||
"astring": "^1.8.5",
|
||||
"eslint": "^7.32.0",
|
||||
"eslump": "^3.0.0",
|
||||
"esm": "^3.2.25",
|
||||
"mocha": "^9.2.0",
|
||||
"pre-commit": "^1.2.2",
|
||||
"rollup": "^2.56.3",
|
||||
"semver": "^7.5.1",
|
||||
"source-map": "~0.8.0-beta.0"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "node test/compress.js && mocha test/mocha",
|
||||
"test:compress": "node test/compress.js",
|
||||
"test:mocha": "mocha test/mocha",
|
||||
"lint": "eslint lib",
|
||||
"lint-fix": "eslint --fix lib",
|
||||
"ls-lint": "ls-lint",
|
||||
"build": "rollup --config --silent",
|
||||
"prepare": "npm run build",
|
||||
"postversion": "echo 'Remember to update the changelog!'"
|
||||
},
|
||||
"keywords": [
|
||||
"uglify",
|
||||
"terser",
|
||||
"uglify-es",
|
||||
"uglify-js",
|
||||
"minify",
|
||||
"minifier",
|
||||
"javascript",
|
||||
"ecmascript",
|
||||
"es5",
|
||||
"es6",
|
||||
"es7",
|
||||
"es8",
|
||||
"es2015",
|
||||
"es2016",
|
||||
"es2017",
|
||||
"async",
|
||||
"await"
|
||||
],
|
||||
"eslintConfig": {
|
||||
"parserOptions": {
|
||||
"sourceType": "module",
|
||||
"ecmaVersion": 2020
|
||||
},
|
||||
"env": {
|
||||
"node": true,
|
||||
"browser": true,
|
||||
"es2020": true
|
||||
},
|
||||
"globals": {
|
||||
"describe": false,
|
||||
"it": false,
|
||||
"require": false,
|
||||
"before": false,
|
||||
"after": false,
|
||||
"global": false,
|
||||
"process": false
|
||||
},
|
||||
"rules": {
|
||||
"brace-style": [
|
||||
"error",
|
||||
"1tbs",
|
||||
{
|
||||
"allowSingleLine": true
|
||||
}
|
||||
],
|
||||
"quotes": [
|
||||
"error",
|
||||
"double",
|
||||
"avoid-escape"
|
||||
],
|
||||
"no-debugger": "error",
|
||||
"no-undef": "error",
|
||||
"no-unused-vars": [
|
||||
"error",
|
||||
{
|
||||
"varsIgnorePattern": "^_"
|
||||
}
|
||||
],
|
||||
"no-tabs": "error",
|
||||
"semi": [
|
||||
"error",
|
||||
"always"
|
||||
],
|
||||
"no-extra-semi": "error",
|
||||
"no-irregular-whitespace": "error",
|
||||
"space-before-blocks": [
|
||||
"error",
|
||||
"always"
|
||||
]
|
||||
}
|
||||
},
|
||||
"pre-commit": [
|
||||
"build",
|
||||
"lint-fix",
|
||||
"ls-lint",
|
||||
"test"
|
||||
]
|
||||
}
|
8022
my-app/node_modules/terser/tools/domprops.js
generated
vendored
Executable file
8022
my-app/node_modules/terser/tools/domprops.js
generated
vendored
Executable file
File diff suppressed because it is too large
Load diff
7
my-app/node_modules/terser/tools/exit.cjs
generated
vendored
Executable file
7
my-app/node_modules/terser/tools/exit.cjs
generated
vendored
Executable file
|
@ -0,0 +1,7 @@
|
|||
// workaround for tty output truncation upon process.exit()
|
||||
// https://github.com/nodejs/node/issues/6456
|
||||
|
||||
[process.stdout, process.stderr].forEach((s) => {
|
||||
s && s.isTTY && s._handle && s._handle.setBlocking &&
|
||||
s._handle.setBlocking(true)
|
||||
});
|
55
my-app/node_modules/terser/tools/props.html
generated
vendored
Executable file
55
my-app/node_modules/terser/tools/props.html
generated
vendored
Executable file
|
@ -0,0 +1,55 @@
|
|||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<script>(function(){
|
||||
var props = {};
|
||||
|
||||
function addObject(obj) {
|
||||
if (obj == null) return;
|
||||
try {
|
||||
Object.getOwnPropertyNames(obj).forEach(add);
|
||||
} catch(ex) {}
|
||||
if (obj.prototype) {
|
||||
Object.getOwnPropertyNames(obj.prototype).forEach(add);
|
||||
}
|
||||
if (typeof obj == "function") {
|
||||
try {
|
||||
Object.getOwnPropertyNames(new obj).forEach(add);
|
||||
} catch(ex) {}
|
||||
}
|
||||
}
|
||||
|
||||
function add(name) {
|
||||
props[name] = true;
|
||||
}
|
||||
|
||||
Object.getOwnPropertyNames(window).forEach(function(thing){
|
||||
addObject(window[thing]);
|
||||
});
|
||||
|
||||
try {
|
||||
addObject(new Event("click"));
|
||||
addObject(new Event("contextmenu"));
|
||||
addObject(new Event("mouseup"));
|
||||
addObject(new Event("mousedown"));
|
||||
addObject(new Event("keydown"));
|
||||
addObject(new Event("keypress"));
|
||||
addObject(new Event("keyup"));
|
||||
} catch(ex) {}
|
||||
|
||||
var ta = document.createElement("textarea");
|
||||
ta.style.width = "100%";
|
||||
ta.style.height = "20em";
|
||||
ta.style.boxSizing = "border-box";
|
||||
ta.value = 'export var domprops = ' + JSON.stringify(Object.keys(props).sort(cmp), null, 4);
|
||||
document.body.appendChild(ta);
|
||||
|
||||
function cmp(a, b) {
|
||||
a = a.toLowerCase();
|
||||
b = b.toLowerCase();
|
||||
return a < b ? -1 : a > b ? 1 : 0;
|
||||
}
|
||||
})();</script>
|
||||
</body>
|
||||
</html>
|
215
my-app/node_modules/terser/tools/terser.d.ts
generated
vendored
Executable file
215
my-app/node_modules/terser/tools/terser.d.ts
generated
vendored
Executable file
|
@ -0,0 +1,215 @@
|
|||
/// <reference lib="es2015" />
|
||||
|
||||
import { SectionedSourceMapInput, EncodedSourceMap, DecodedSourceMap } from '@jridgewell/source-map';
|
||||
|
||||
export type ECMA = 5 | 2015 | 2016 | 2017 | 2018 | 2019 | 2020;
|
||||
|
||||
export type ConsoleProperty = keyof typeof console;
|
||||
type DropConsoleOption = boolean | ConsoleProperty[];
|
||||
|
||||
export interface ParseOptions {
|
||||
bare_returns?: boolean;
|
||||
/** @deprecated legacy option. Currently, all supported EcmaScript is valid to parse. */
|
||||
ecma?: ECMA;
|
||||
html5_comments?: boolean;
|
||||
shebang?: boolean;
|
||||
}
|
||||
|
||||
export interface CompressOptions {
|
||||
arguments?: boolean;
|
||||
arrows?: boolean;
|
||||
booleans_as_integers?: boolean;
|
||||
booleans?: boolean;
|
||||
collapse_vars?: boolean;
|
||||
comparisons?: boolean;
|
||||
computed_props?: boolean;
|
||||
conditionals?: boolean;
|
||||
dead_code?: boolean;
|
||||
defaults?: boolean;
|
||||
directives?: boolean;
|
||||
drop_console?: DropConsoleOption;
|
||||
drop_debugger?: boolean;
|
||||
ecma?: ECMA;
|
||||
evaluate?: boolean;
|
||||
expression?: boolean;
|
||||
global_defs?: object;
|
||||
hoist_funs?: boolean;
|
||||
hoist_props?: boolean;
|
||||
hoist_vars?: boolean;
|
||||
ie8?: boolean;
|
||||
if_return?: boolean;
|
||||
inline?: boolean | InlineFunctions;
|
||||
join_vars?: boolean;
|
||||
keep_classnames?: boolean | RegExp;
|
||||
keep_fargs?: boolean;
|
||||
keep_fnames?: boolean | RegExp;
|
||||
keep_infinity?: boolean;
|
||||
loops?: boolean;
|
||||
module?: boolean;
|
||||
negate_iife?: boolean;
|
||||
passes?: number;
|
||||
properties?: boolean;
|
||||
pure_funcs?: string[];
|
||||
pure_new?: boolean;
|
||||
pure_getters?: boolean | 'strict';
|
||||
reduce_funcs?: boolean;
|
||||
reduce_vars?: boolean;
|
||||
sequences?: boolean | number;
|
||||
side_effects?: boolean;
|
||||
switches?: boolean;
|
||||
toplevel?: boolean;
|
||||
top_retain?: null | string | string[] | RegExp;
|
||||
typeofs?: boolean;
|
||||
unsafe_arrows?: boolean;
|
||||
unsafe?: boolean;
|
||||
unsafe_comps?: boolean;
|
||||
unsafe_Function?: boolean;
|
||||
unsafe_math?: boolean;
|
||||
unsafe_symbols?: boolean;
|
||||
unsafe_methods?: boolean;
|
||||
unsafe_proto?: boolean;
|
||||
unsafe_regexp?: boolean;
|
||||
unsafe_undefined?: boolean;
|
||||
unused?: boolean;
|
||||
}
|
||||
|
||||
export enum InlineFunctions {
|
||||
Disabled = 0,
|
||||
SimpleFunctions = 1,
|
||||
WithArguments = 2,
|
||||
WithArgumentsAndVariables = 3
|
||||
}
|
||||
|
||||
export interface MangleOptions {
|
||||
eval?: boolean;
|
||||
keep_classnames?: boolean | RegExp;
|
||||
keep_fnames?: boolean | RegExp;
|
||||
module?: boolean;
|
||||
nth_identifier?: SimpleIdentifierMangler | WeightedIdentifierMangler;
|
||||
properties?: boolean | ManglePropertiesOptions;
|
||||
reserved?: string[];
|
||||
safari10?: boolean;
|
||||
toplevel?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* An identifier mangler for which the output is invariant with respect to the source code.
|
||||
*/
|
||||
export interface SimpleIdentifierMangler {
|
||||
/**
|
||||
* Obtains the nth most favored (usually shortest) identifier to rename a variable to.
|
||||
* The mangler will increment n and retry until the return value is not in use in scope, and is not a reserved word.
|
||||
* This function is expected to be stable; Evaluating get(n) === get(n) should always return true.
|
||||
* @param n The ordinal of the identifier.
|
||||
*/
|
||||
get(n: number): string;
|
||||
}
|
||||
|
||||
/**
|
||||
* An identifier mangler that leverages character frequency analysis to determine identifier precedence.
|
||||
*/
|
||||
export interface WeightedIdentifierMangler extends SimpleIdentifierMangler {
|
||||
/**
|
||||
* Modifies the internal weighting of the input characters by the specified delta.
|
||||
* Will be invoked on the entire printed AST, and then deduct mangleable identifiers.
|
||||
* @param chars The characters to modify the weighting of.
|
||||
* @param delta The numeric weight to add to the characters.
|
||||
*/
|
||||
consider(chars: string, delta: number): number;
|
||||
/**
|
||||
* Resets character weights.
|
||||
*/
|
||||
reset(): void;
|
||||
/**
|
||||
* Sorts identifiers by character frequency, in preparation for calls to get(n).
|
||||
*/
|
||||
sort(): void;
|
||||
}
|
||||
|
||||
export interface ManglePropertiesOptions {
|
||||
builtins?: boolean;
|
||||
debug?: boolean;
|
||||
keep_quoted?: boolean | 'strict';
|
||||
nth_identifier?: SimpleIdentifierMangler | WeightedIdentifierMangler;
|
||||
regex?: RegExp | string;
|
||||
reserved?: string[];
|
||||
}
|
||||
|
||||
export interface FormatOptions {
|
||||
ascii_only?: boolean;
|
||||
/** @deprecated Not implemented anymore */
|
||||
beautify?: boolean;
|
||||
braces?: boolean;
|
||||
comments?: boolean | 'all' | 'some' | RegExp | ( (node: any, comment: {
|
||||
value: string,
|
||||
type: 'comment1' | 'comment2' | 'comment3' | 'comment4',
|
||||
pos: number,
|
||||
line: number,
|
||||
col: number,
|
||||
}) => boolean );
|
||||
ecma?: ECMA;
|
||||
ie8?: boolean;
|
||||
keep_numbers?: boolean;
|
||||
indent_level?: number;
|
||||
indent_start?: number;
|
||||
inline_script?: boolean;
|
||||
keep_quoted_props?: boolean;
|
||||
max_line_len?: number | false;
|
||||
preamble?: string;
|
||||
preserve_annotations?: boolean;
|
||||
quote_keys?: boolean;
|
||||
quote_style?: OutputQuoteStyle;
|
||||
safari10?: boolean;
|
||||
semicolons?: boolean;
|
||||
shebang?: boolean;
|
||||
shorthand?: boolean;
|
||||
source_map?: SourceMapOptions;
|
||||
webkit?: boolean;
|
||||
width?: number;
|
||||
wrap_iife?: boolean;
|
||||
wrap_func_args?: boolean;
|
||||
}
|
||||
|
||||
export enum OutputQuoteStyle {
|
||||
PreferDouble = 0,
|
||||
AlwaysSingle = 1,
|
||||
AlwaysDouble = 2,
|
||||
AlwaysOriginal = 3
|
||||
}
|
||||
|
||||
export interface MinifyOptions {
|
||||
compress?: boolean | CompressOptions;
|
||||
ecma?: ECMA;
|
||||
enclose?: boolean | string;
|
||||
ie8?: boolean;
|
||||
keep_classnames?: boolean | RegExp;
|
||||
keep_fnames?: boolean | RegExp;
|
||||
mangle?: boolean | MangleOptions;
|
||||
module?: boolean;
|
||||
nameCache?: object;
|
||||
format?: FormatOptions;
|
||||
/** @deprecated */
|
||||
output?: FormatOptions;
|
||||
parse?: ParseOptions;
|
||||
safari10?: boolean;
|
||||
sourceMap?: boolean | SourceMapOptions;
|
||||
toplevel?: boolean;
|
||||
}
|
||||
|
||||
export interface MinifyOutput {
|
||||
code?: string;
|
||||
map?: EncodedSourceMap | string;
|
||||
decoded_map?: DecodedSourceMap | null;
|
||||
}
|
||||
|
||||
export interface SourceMapOptions {
|
||||
/** Source map object, 'inline' or source map file content */
|
||||
content?: SectionedSourceMapInput | string;
|
||||
includeSources?: boolean;
|
||||
filename?: string;
|
||||
root?: string;
|
||||
asObject?: boolean;
|
||||
url?: string | 'inline';
|
||||
}
|
||||
|
||||
export function minify(files: string | string[] | { [file: string]: string }, options?: MinifyOptions): Promise<MinifyOutput>;
|
Loading…
Add table
Add a link
Reference in a new issue