property.js 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Tobias Koppers @sokra
  4. */
  5. "use strict";
  6. const SAFE_IDENTIFIER = /^[_a-z$][_a-z$0-9]*$/i;
  7. const RESERVED_IDENTIFIER = new Set([
  8. "break",
  9. "case",
  10. "catch",
  11. "class",
  12. "const",
  13. "continue",
  14. "debugger",
  15. "default",
  16. "delete",
  17. "do",
  18. "else",
  19. "export",
  20. "extends",
  21. "finally",
  22. "for",
  23. "function",
  24. "if",
  25. "import",
  26. "in",
  27. "instanceof",
  28. "new",
  29. "return",
  30. "super",
  31. "switch",
  32. "this",
  33. "throw",
  34. "try",
  35. "typeof",
  36. "var",
  37. "void",
  38. "while",
  39. "with",
  40. "enum",
  41. // strict mode
  42. "implements",
  43. "interface",
  44. "let",
  45. "package",
  46. "private",
  47. "protected",
  48. "public",
  49. "static",
  50. "yield",
  51. // module code
  52. "await",
  53. // skip future reserved keywords defined under ES1 till ES3
  54. // additional
  55. "null",
  56. "true",
  57. "false"
  58. ]);
  59. /**
  60. * @summary Returns a valid JS property name for the given property.
  61. * Certain strings like "default", "null", and names with whitespace are not
  62. * valid JS property names, so they are returned as strings.
  63. * @param {string} prop property name to analyze
  64. * @returns {string} valid JS property name
  65. */
  66. const propertyName = (prop) => {
  67. if (SAFE_IDENTIFIER.test(prop) && !RESERVED_IDENTIFIER.has(prop)) {
  68. return prop;
  69. }
  70. return JSON.stringify(prop);
  71. };
  72. /**
  73. * Returns chain of property accesses.
  74. * @param {ArrayLike<string>} properties properties
  75. * @param {number} start start index
  76. * @returns {string} chain of property accesses
  77. */
  78. const propertyAccess = (properties, start = 0) => {
  79. let str = "";
  80. for (let i = start; i < properties.length; i++) {
  81. const p = properties[i];
  82. if (`${Number(p)}` === p) {
  83. str += `[${p}]`;
  84. } else if (SAFE_IDENTIFIER.test(p) && !RESERVED_IDENTIFIER.has(p)) {
  85. str += `.${p}`;
  86. } else {
  87. str += `[${JSON.stringify(p)}]`;
  88. }
  89. }
  90. return str;
  91. };
  92. module.exports = {
  93. RESERVED_IDENTIFIER,
  94. SAFE_IDENTIFIER,
  95. propertyAccess,
  96. propertyName
  97. };