global-defs.js 3.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. import {
  2. AST_Array,
  3. AST_Chain,
  4. AST_Constant,
  5. AST_Dot,
  6. AST_ImportMeta,
  7. AST_Node,
  8. AST_Object,
  9. AST_ObjectKeyVal,
  10. AST_PropAccess,
  11. AST_SymbolDeclaration,
  12. AST_SymbolRef,
  13. AST_Toplevel,
  14. TreeTransformer,
  15. } from "../ast.js";
  16. import { make_node, noop, HOP } from "../utils/index.js";
  17. import { make_node_from_constant } from "./common.js";
  18. import { is_lhs } from "./inference.js";
  19. (function(def_find_defs) {
  20. function to_node(value, orig) {
  21. if (value instanceof AST_Node) {
  22. if (!(value instanceof AST_Constant)) {
  23. // Value may be a function, an array including functions and even a complex assign / block expression,
  24. // so it should never be shared in different places.
  25. // Otherwise wrong information may be used in the compression phase
  26. value = value.clone(true);
  27. }
  28. return make_node(value.CTOR, orig, value);
  29. }
  30. if (Array.isArray(value)) return make_node(AST_Array, orig, {
  31. elements: value.map(function(value) {
  32. return to_node(value, orig);
  33. })
  34. });
  35. if (value && typeof value == "object") {
  36. var props = [];
  37. for (var key in value) if (HOP(value, key)) {
  38. props.push(make_node(AST_ObjectKeyVal, orig, {
  39. key: key,
  40. value: to_node(value[key], orig)
  41. }));
  42. }
  43. return make_node(AST_Object, orig, {
  44. properties: props
  45. });
  46. }
  47. return make_node_from_constant(value, orig);
  48. }
  49. AST_Toplevel.DEFMETHOD("resolve_defines", function(compressor) {
  50. if (!compressor.option("global_defs")) return this;
  51. this.figure_out_scope({ ie8: compressor.option("ie8") });
  52. return this.transform(new TreeTransformer(function(node) {
  53. var def = node._find_defs(compressor, "");
  54. if (!def) return;
  55. var level = 0, child = node, parent;
  56. while (parent = this.parent(level++)) {
  57. if (!(parent instanceof AST_PropAccess)) break;
  58. if (parent.expression !== child) break;
  59. child = parent;
  60. }
  61. if (is_lhs(child, parent)) {
  62. return;
  63. }
  64. return def;
  65. }));
  66. });
  67. def_find_defs(AST_Node, noop);
  68. def_find_defs(AST_Chain, function(compressor, suffix) {
  69. return this.expression._find_defs(compressor, suffix);
  70. });
  71. def_find_defs(AST_Dot, function(compressor, suffix) {
  72. return this.expression._find_defs(compressor, "." + this.property + suffix);
  73. });
  74. def_find_defs(AST_SymbolDeclaration, function() {
  75. if (!this.global()) return;
  76. });
  77. def_find_defs(AST_SymbolRef, function(compressor, suffix) {
  78. if (!this.global()) return;
  79. var defines = compressor.option("global_defs");
  80. var name = this.name + suffix;
  81. if (HOP(defines, name)) return to_node(defines[name], this);
  82. });
  83. def_find_defs(AST_ImportMeta, function(compressor, suffix) {
  84. var defines = compressor.option("global_defs");
  85. var name = "import.meta" + suffix;
  86. if (HOP(defines, name)) return to_node(defines[name], this);
  87. });
  88. })(function(node, func) {
  89. node.DEFMETHOD("_find_defs", func);
  90. });