no-regexp-unicode-property-escapes-2019.js 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. /**
  2. * @author Toru Nagashima <https://github.com/mysticatea>
  3. * See LICENSE file in root directory for full license.
  4. */
  5. "use strict"
  6. const { RegExpValidator } = require("regexpp")
  7. const { getRegExpCalls } = require("../utils")
  8. const scNamePattern = /^(?:Script(?:_Extensions)?|scx?)$/u
  9. const scValuePattern = /^(?:Dogr|Dogra|Gong|Gunjala_Gondi|Hanifi_Rohingya|Maka|Makasar|Medefaidrin|Medf|Old_Sogdian|Rohg|Sogd|Sogdian|Sogo)$/u
  10. function isNewUnicodePropertyKeyValuePair(key, value) {
  11. return scNamePattern.test(key) && scValuePattern.test(value)
  12. }
  13. function isNewBinaryUnicodeProperty(key) {
  14. return key === "Extended_Pictographic"
  15. }
  16. /**
  17. * Verify a given regular expression.
  18. * @param {RuleContext} context The rule context to report.
  19. * @param {Node} node The AST node to report.
  20. * @param {string} pattern The pattern part of a RegExp.
  21. * @param {string} flags The flags part of a RegExp.
  22. * @returns {void}
  23. */
  24. function verify(context, node, pattern, flags) {
  25. try {
  26. let foundValue = ""
  27. new RegExpValidator({
  28. onUnicodePropertyCharacterSet(start, end, _kind, key, value) {
  29. if (foundValue) {
  30. return
  31. }
  32. if (
  33. value
  34. ? isNewUnicodePropertyKeyValuePair(key, value)
  35. : isNewBinaryUnicodeProperty(key)
  36. ) {
  37. foundValue = pattern.slice(start, end)
  38. }
  39. },
  40. }).validatePattern(pattern, 0, pattern.length, flags.includes("u"))
  41. if (foundValue) {
  42. context.report({
  43. node,
  44. messageId: "forbidden",
  45. data: { value: foundValue },
  46. })
  47. }
  48. } catch (error) {
  49. //istanbul ignore else
  50. if (error.message.startsWith("Invalid regular expression:")) {
  51. return
  52. }
  53. //istanbul ignore next
  54. throw error
  55. }
  56. }
  57. module.exports = {
  58. meta: {
  59. docs: {
  60. description:
  61. "disallow the new values of RegExp Unicode property escape sequences in ES2019",
  62. category: "ES2019",
  63. recommended: false,
  64. url:
  65. "http://mysticatea.github.io/eslint-plugin-es/rules/no-regexp-unicode-property-escapes-2019.html",
  66. },
  67. fixable: null,
  68. messages: {
  69. forbidden: "ES2019 '{{value}}' is forbidden.",
  70. },
  71. schema: [],
  72. type: "problem",
  73. },
  74. create(context) {
  75. return {
  76. "Literal[regex]"(node) {
  77. const { pattern, flags } = node.regex
  78. verify(context, node, pattern || "", flags || "")
  79. },
  80. "Program:exit"() {
  81. const scope = context.getScope()
  82. for (const { node, pattern, flags } of getRegExpCalls(scope)) {
  83. verify(context, node, pattern || "", flags || "")
  84. }
  85. },
  86. }
  87. },
  88. }